淮南网站开发wordpress wp大学
本节目标
- 单页应用程序
 - 路由概念
 - VueRouter基本使用
 - 组件分类存放
 - 路由模块封装
 - 声明式导航
 - 其他路由配置
 - 路由模式
 - 编程式导航
 - 案例-面经基础版
 
单页应用程序
单页应用程序(SPA): 所有的功能都在一个HTML页面上实现
网易云音乐: 网易云音乐
多页应用程序(MPA): 不同功能通过切换不同页面实现
京东商城: 京东(JD.COM)-正品低价、品质保障、配送及时、轻松购物!
对比

- 单页应用: 适合对效率和性能要求高的程序, 系统类网站/内部网站/文档类网站/移动端站点
 - 多页用用: 适合对首页和SEO要求高的程序, 公司官网/电商类网站
 
路由概念
vue路由: 记录 路径和组件的 映射关系, 根据路由, 就能知道不同路径, 应该渲染哪个组件
- 单页应用程序开发效能和性能高的原因在于页面按需更新,
 - 实现按需更新的前提是要明确 访问路径 和 组件 的对应关系
 

VueRouter基本使用
vue官方的一个路由插件
官网: Vue Router | Vue.js 的官方路由
版本
- Vue2 -> VueRouter3.x -> Vuex3.x
 - Vue3 -> VueRouter4.x -> Vuex4.x
 
使用 5+2
固定步骤
- 下载: 下载VueRouter模块到当前工程
 

- 引入VueRouer插件
 

- 安装注册: 所有的插件都可以使用Vue.use()注册到项目中
 

- 创建路由对象
 

- 注入: 将路由对象注入到new Vue实例中, 建立关联
 

核心步骤
- 配置路由规则
 

- 配置路由出口 (组件展示位置)
 

组件分类存放
根据组件的作用不同, 存放在不同的文件夹中, 便于查找和维护

- 页面组件: 展示页面, 配合路由使用, 放于view文件中
 - 复用组件: 展示数据, 提高代码复用, 放于component文件夹中
 - 本质都是.vue文件, 只是用途有区别
 
路由模块封装
项目中, 路由相关的配置应该抽离为单独模块, 便于查找和维护
- 新建src/router/index.j文件, 作为路由配置文件, 统一管理路由
 

- 在main.js中挂载路由对象
 

声明式导航
通过导航链接实现路由跳转的方式,称为声明式导航
说明
- vue-router提供了一个全局组件 router-link (取代a标签)
 


- 使用router-link的好处有:
 - 能跳转: 配置to属性, 指定路径(必须), 即可实现路由跳转 (使用a标签还要添加#)
 - 能高亮: 默认就会提供激活类名, 可以直接通过css设置高亮效果 (使用a标签还要通过JS控制类名切换)
 

- router-link编译后还是以 a 标签的形式实现的路由跳转, 但是使用更方便
 
激活类名
router-link 自动给当前导航添加了两个高亮类名

- router-link-active (模糊匹配)(用的多)(路径包含就可以匹配高亮)
 - to="/my" 可以匹配 /my /my/a /my/b
 - router-link-exact-active (精确匹配)(路径相等才可以匹配高亮)
 - to="/my" 仅可以匹配 /my
 
自定义激活类名
如果觉得官方的高亮类名太长, 可以通过配置, 修改高亮类名


跳转传参
1> 查询参数传参
- 传值: to="/path?参数名=值&?参数名=值"
 - 取值: $route.query.参数名
 - 效果: 

 - 场景: 适合传递多个参数
 
2> 动态路由传参
- 配置: path: '/search/:参数名'
 - 传参: to="/path/参数值"
 - 取值: $route.params.参数名
 - 效果:  

 - 场景: 优雅简洁, 传递单个参数比较方便
 - 参数可选符: path: '/search/:参数名?'
 - 参数可选符表示该路由参数可传可不传
 
其他路由配置
路由重定向
网页打开, url默认路径是 /, 未匹配到组件时, 会出现空白
- 通过路由重定向, 强制跳转path路径
 - { path: '/', redirect: '/home' }
 - 路由重定向建议放到路由规则的首位
 
任意路由
当路径匹配不到页面时, 希望给用户友好的提示页面, 而不是空白
- 当所有路由规则都匹配失败, 就命中任意路由
 - { path: '*', component: '404组件' }
 - 路由重定向要放到路由规则的末尾
 
嵌套路由
通过childer配置项, 可以配置嵌套子路由
- 在childer配置项中, 配置路由规则
 
{path: '/',component: () => import('@/views/Layout.vue'),children: [{ path: '/article', component: () => import('@/views/Article.vue') },]
}, 
- 准备二级路由出口
 - 通过声明式或者编程式导航, 跳转二级页面
 
路由模式
实际的项目中, 很少使用带有 # 的路径, 此时,就需要切换路由模式
哈希模式
- 哈希模式路径中带有#, 使用该模式的项目较少
 - 哈希模式的底层实现是通过 a标签的锚链接 实现
 - 哈希模式是vue路由的默认模式
 - 使用URL的hash部分来模拟一个完整的URL, hash永远不会被包含在HTPP请求中
 - 浏览器兼容性好, 即使在非HTML5模式下也可以正常工作
 

历史模式
- 历史模式路径中不带#, 使用该模式的项目较多
 - 历史模式的底层实现是通过 H5 history API 实现
 - 使用历史模式的路由, 上线后需要服务器进行配置, 否则访问深层链接时会遇到404
 - 这两种模式对于前端来说, 切换成本极低, 改下配置就行
 - URL更加简洁, 对用户和搜索引擎友好
 

编程式导航
编程式导航就是通过JS代码实现路由切换
为保持简洁, 取值的方法不再赘述, 与 声明式导航 一致
1>路径跳转
简单方便
1.1>跳转的方法

1.2>传参的方法
1.2.1>query传参

1.2.2>动态路由传参

2>命名路由跳转
适合路径名字长的情况
2.1>跳转的方法


2.2>传参的方法
2.2.1>query传参

2.2.2>动态路由传参

3>其他跳转方法
- this.$router.push('hash地址') //跳转到指定地址,并增加一条历史记录
 - this.$router.replace('hash地址') //跳转到指定地址,并替换当前历史记录
 - this.$router.go(数值n) //在浏览历史中前进和后退
 - this.$router.back() //在历史记录中,后退到上一个页面
 - this.$router.forward() //在历史记录中,前进下一个页面
 
案例-面经基础版
需求分析
- 主要功能: 点击底部导航, 切换页面, 点击列表,跳转详情页
 

- 拆分路由: 首页和详情页是一级路由, 首页内嵌四个二级路由
 

- 其他需求: 使用组件缓存, 优化性能
 
搭建路由
1>搭建一级路由
// 配置路由规则
import Vue from 'vue'
import VueRouter from "vue-router";
Vue.use(VueRouter)const router = new VueRouter({routes: [{path: '/',component: () => import('@/views/Layout.vue'),},{path: '/detail',component: () => import('@/views/ArticleDetail.vue')},]
})export default router 
<template><!-- 准备路由出口 --><div class="h5-wrapper"><router-view></router-view></div>
</template> 
 
2>搭建二级路由
// 配置路由规则
... ...
const router = new VueRouter({routes: [{path: '/',component: () => import('@/views/Layout.vue'),redirect: '/article',children: [{ path: '/article', component: () => import('@/views/Article.vue') },{ path: '/collect', component: () => import('@/views/Collect.vue') },{ path: '/like', component: () => import('@/views/Like.vue') },{ path: '/user', component: () => import('@/views/User.vue') },]},]
})
... ... 
<template><div class="h5-wrapper"><!-- 1,准备二级路由出口 --><div class="content"><router-view></router-view></div><!-- 2,路由切换标签 --><!--  --><nav class="tabbar"><router-link to="/article">面经</router-link><router-link to="/collect">收藏</router-link><router-link to="/like">喜欢</router-link><router-link to="/user">我的</router-link></nav></div>
</template><style lang="less" scoped>
.h5-wrapper {... ....tabbar {... .../* 3,通过高亮类型实现激活高亮 */.router-link-active {color: #ff7300;}}
}
</style> 
 
渲染首页
<template><div class="article-page"><!-- 3,动态渲染数据  --><div v-for="item in list" :key="item.id" class="article-item" @click="$router.push(`/detail/${item.id}`)">... ...</div></div>
</template><script>
// 1,安装axios
import axios from "axios";
export default {name: "ArticlePage",data() {return {list: [],};},async created() {// 2,请求数据const res = await axios({url: "https://mock.boxuegu.com/mock/3083/articles",method: "get",});this.list = res.data.result.rows;},
};
</script> 
跳转详情页
.. ...
const router = new VueRouter({routes: [... ...{// 添加动态参数占位符path: '/detail/:id',component: () => import('@/views/ArticleDetail.vue')},]
})
.. ... 
<template><!-- 传递单个参数, 使用动态参数更加优雅 --><div class="article-page"><div v-for="item in list" :key="item.id" @click="$router.push(`/detail/${item.id}`)">... ...</div></div>
</template> 
 
渲染详情页
<template><!-- 2,渲染数据 --><div class="article-detail-page" v-if="info.id"><nav class="nav"><span @click="$router.back()" class="back"><</span> 面经详情</nav>... ...<main class="body">{{ info.content }}</main></div>
</template><script>
import axios from 'axios'
export default {name: "ArticleDetailPage",data() {return {info: {}}},async created() {// 1,请求数据 (拿到路由参数)const res = await axios({url: ` https://mock.boxuegu.com/mock/3083/articles/${this.$route.params.id}`,method: 'get'})this.info = res.data.result}
}
</script> 
 
缓存组件
<template><div class="h5-wrapper"><!-- 组件缓存 keep-alive默认生效范围: 使用该路由出口的组件都会被缓存(Layout组件, Detail组件)include属性: 组件名数组, 只有匹配的组件才会被缓存--><keep-alive :include="['LayoutPage']"><router-view></router-view></keep-alive></div>
</template> 
- 问题: 从列表页去往详情页, 再返回列表页, 列表页数据会重新加载, 如果希望停留在原位置, 可以缓存列表组件
 - keep-alive 是Vue的内置组件, 当它包裹动态组件时, 会缓存不活动的组件实例, 而不是销毁他们
 - keep-alive 是一个抽象组件, 它自身不会渲染成DOM元素, 也不会出现在父组件链中
 - keep-alive 在组件切换过程中, 把切出去的组件保留在内存中, 防止重复渲染DOM, 减少加载时间和性能损耗
 - keep-alive的三个配置属性:
 - :include=['组件名'], 数组中匹配的组件都会被缓存 (推荐)
 - 注意: 组件名是通过name属性指定的名字, 不指定name属性时, 文件名会作为组件名
 - :exclude=['数组名'], 数组中匹配的组件不会被缓存
 - max='数字', 最多可以缓存多少组件实例,一般匹配 exclude 属性使用, 避免缓存组件太多引发性能问题
 - 如果不指定规则, 缓存所有相关组件 (不推荐)
 - 一旦组件被缓存, 组件会新增两个生命周期函数, 组件的创建/挂载/销毁等生命周期函数也会受到影响
 - activated 生命周期函数: 当组件被激活(使用)的时候触发 (进入页面触发)
 - deactivated 生命周期函数: 当组件失活(缓存)的时候触发 (离开页面触发)
 
