概括:
多个路由,需要经过路由器的管理。为了完成单页面应用SPA(single page web application)的导航区和展示区来来回回的切换展示。
4.1、路由的理解:
(1)路由就是一组key-value的对应关系。
(2)key为路径,value可能是function或component
4.2、路由分类
4.2.1 后端路由
(1)理解:value是function,用于处理客户端提交的请求。
(2)工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据。
4.2.2 前端路由
(1)理解:value是component,用于展示页面内容。
(2)工作过程:当浏览器路径发生改变时,对应的组件就会展示。
4.3、对SPA单页应用的理解:
(1)单页web应用(single page web application)。
(2)整个应用只有一个完整的页面index.html。
(3)点击页面中的导航链接不会重新刷新页面,只会做页面的局部更新。
(4)数据需要通过Ajax请求获取。
4.4、路由的基本使用
(1)安装vue-router(vue的一个插件库,专门用来实现SPA应用),命令:npm i vue-router
(2)应用插件:在配置router的文件引入vue-router插件并应用Vue use(router)。
(3)编写router配置项
import Vue from 'vue'
//引入路由
import Router from 'vue-router'
//引入组件
import admin from '../components/admin'
import main from '../pages/admin/table'
import login from '../pages/login'
//应用插件
Vue.use(Router)
//解决路由导航冗余报错(路由重复)
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
//创建并暴露一个路由器
export default new Router({
routes: [
{path: '/', redirect: '/login'}, //重定向 前端启动后,访问直接进入login页面
{
path: '/login',
name: 'login',
component: login,
},
{
path: '/admin',
name: 'admin',
component: admin,
children: [
{
path: '/admin/main',
name: 'main',
component: main,
children: [
// {path: '/index', name: 'index', component: main}
]
}
]
},
]
})
4.5、实现切换(active-class="active"可配置选种高亮)
<router-link active-class="active" to="/url"></router-link>
或 编程式路由
this.$router.push({path: index});//index为要具有的组件路径
4.6、指定路由组件展示位置
点击路由时,设置pageshow为true,重新渲染界面,routeKey初始化为0
<router-view v-if="pageshow" :key="'router' + routeKey"></router-view>
4.7、几个注意点
(1)路由组件通常被放在pages文件夹,一般组件放在component文件夹。
(2)通过切换,隐藏了上个路由组件,默认是销毁了,需要的时候再去挂载。
(3)每个组件都有自己的$route属性,里面存储着自己的路由信息。
(4)整个应用只有一个router,可以通过组件的$router属性去获取。
4.8、嵌套路由
import Vue from 'vue'
//引入路由
import Router from 'vue-router'
//引入组件
import admin from '../components/admin'
import main from '../pages/admin/table'
import login from '../pages/login'
//应用插件
Vue.use(Router)
//解决路由导航冗余报错(路由重复)
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
//创建并暴露一个路由器
export default new Router({
routes: [
{path: '/', redirect: '/login'}, //重定向 前端启动后,访问直接进入login页面
{
path: '/login',
name: 'login',
component: login,
},
{
//一级路由
path: '/admin',
name: 'admin',
component: admin,
//二级路由 通过children配置/admin子集路由
children: [
{
path: '/admin/main',
name: 'main',
component: main,
children: [
// {path: '/index', name: 'index', component: main}
]
}
]
},
]
})
4.9、路由的query参数
(1)传递参数
1、传了两个参数,id和name,但是参数传的是死参数
<router-link active-class="active" :to="/url?id=a&name=lunlun">跳转</router-link>
2、写成to对象形式,id和name,参数是可灵活变动的
<router-link active-class="active" :to="{
path:'/url',
query:{id=a,name='lunlun'}
}">跳转</router-link>
(2)在组件里接收参数 每个组件都有自己的$route属性
$route.query.id
$route.query.name
4.10、命名路由
(1)作用:可以简化路由
(2)如何使用
1、给路由命名
{
//一级路由
path: '/admin',
name: 'admin',//给路由命名
component: admin,
//二级路由 通过children配置/admin子集路由
children: [
{
path: '/admin/main',
name: 'main',
component: main,
children: [
// {path: '/index', name: 'index', component: main}
]
}
]
},
2、简化跳转
//简化前 需要写完整路径 to的字符串写法
<router-link active-class="active" to="/admin/main">跳转</router-link>
//简化后 直接通过名字跳转 to的对象写法
<router-link active-class="active" :to="{name:'main'}">跳转</router-link>
4.11、路由的params参数
(1)配置路由,声明接收params参数
{
//一级路由
path: '/admin',
name: 'admin',//给路由命名
component: admin,
//二级路由 通过children配置/admin子集路由
children: [
{
path: '/admin/main:id/:title',//使用占用符声明接收params参数
name: 'main',
component: main,
children: [
// {path: '/index', name: 'index', component: main}
]
}
]
},
(2)传递参数
特别注意:路由携带params参数时,不能使用path配置,必须使用name配置
//跳转并携带params参数 to的字符串写法 66 lunlun 为参数
<router-link active-class="active" :to="/admin/main/66/lunlun">跳转</router-link>
//跳转并携带params参数 to的对象写法
<router-link active-class="active" :to="{
name:'main',
params:{id:66,name:'lunlun'}
}">跳转</router-link>
(3)接收参数
$route.params.id
$route.params.name
4.12、路由的props配置(在router配置将文件配置props,在组件里面也要配置props接收参数)
作用:让路由组件更加的方便接收参数
(1) router配置文件配置
{
//一级路由
path: '/admin',
name: 'admin',//给路由命名
component: admin,
//二级路由 通过children配置/admin子集路由
children: [
{
path: '/admin/main:id/:title',//使用占用符声明接收params参数
name: 'main',
component: main,
// 第一种写法 props值为对象,该对象中所有的key-value的组合最终都会通过props传给main组件
//props:{id:66,name'lunlun'}
//第二种写法 props值为布尔值,布尔值为true时,则把路由收到的params(仅指的是params参数)参数通过props传给main
//props:true
//第三种写法 props值为函数,该函数返回的对象中每一组key-value都会props传给main组件
props:function(router){
return{
id:router.query.id,
name:router.query.name
}
}
children: [
// {path: '/index', name: 'index', component: main}
]
}
]
},
(2)组件文件接收配置
4.13、router-link和replace属性
(1)作用:控制路由跳转时操作浏览器历史记录的模式
(2)浏览器的历史记录有两种写入方式:分别为push和replace,push是追加历史记录,replace是替换当前记录,路由跳转的时候默认为push
(3)如何开启replace模式,直接添加replace
<router-link replace active-class="active" :to="/admin/main/66/lunlun">跳转</router-link>
4.14、编程式路由导航
方便点击事件路由导航
1、追加浏览器记录
this.$router.push({path: index,query:{id:66,name:'lunlun'}});
2、替换当前浏览器记录
this.$router.replace({path: index,query:{id:66,name:'lunlun'}});
3、回退上一条路由
this.$router.back()
4、前进下一条路由
this.$router.forward()
5、go()路由指定位置
this.$router.go(-3)//后退3步
this.$router.go(+2)//前进2步
4.15、缓存路由组件
(1)作用:让不展示的路由组件保持挂载,不被销毁
(2)具体编码
// 组件路由缓存 componentname被缓存的组件名
//单个组件被激活
<keep-alive include="clothing">
<!-- 指定组件的呈现位置-->
<router-view/>
</keep-alive>
//多个组件被激活
<keep-alive :include="['clothing','pay']">
<!-- 指定组件的呈现位置-->
<router-view/>
</keep-alive>
4.16、两个新的生命钩子(路由组件所独有)
(1)作用:路由组件所独有的两个生命钩子,用于捕获路由组件的激活状态
(2)具体名字:
1、activated路由组件被激活时触发
//调用被激活的组件
activated () {
this.tiems = setInterval(()=>{
console.log("clotiong组件被激活了")
this.opacitys -= 0.1;
if (this.opacitys <=0 ){
this.opacitys = 1
}
},1000)},
2、deactivated路由组件失活时触发
//调用失活的组件
deactivated () {
console.log("组件失活了")
clearInterval(this.tiems)
},
4.17、路由守卫
(1)作用:对路由进行权限的控制
(2)分类:全局路由、独享路由、组件内路由
(3)全局守卫
//全局前置路由守卫---路由组件初始化之前调用,每次路由切换之前调用
//参数to:路由去哪里,form:路由来自那里,next:路由跳转到页面
router.beforeEach((to,form,next)=>{
console.log(form,to)
// 符合条件才能进行路由跳转展示页面---如果路由来自名称name为pay是执行路由跳转
if (to.meta.isTrue){//判断当前路由是否需要进行权限配置
if (sessionStorage.getItem("user") == "lunlun88"){//权限控制的具体规则
next();//放行
}else {
alert("只给用户lunlun88查看,暂无权限查看!")
}
}else {
next();//放行
}
});
//全局后置路由守卫---路由初始化时调用,每次路由切换后调用
//参数to:路由去哪里,form:路由来自那里
router.afterEach((to,form)=>{
// 符合条件才能进行路由跳转展示页面---如果路由来自名称name为pay是执行路由跳转
if (to.meta.title){
document.title = to.meta.title//修改网页的title
}else {
document.title = "消费查询系统"
}
});
(4)独享路由守卫
独享路由守卫只有前置路由守卫,没有独享后置路由守卫
//仅限路由名为clothing使用
{
path: '/admin/clothing',
name: 'clothing',
component: clothing,
//props配置
props:function (router){
return{
id:router.query.id,
name:router.query.name
}
},
meta:{isTrue:true,title:"服饰装扮"},
beforeEnter:(to,form,next)=>{
if (to.meta.isTrue){//判断当前路由是否需要进行权限配置
if (sessionStorage.getItem("user") == "lunlun88"){//权限控制的具体规则
next();//放行
}else {
alert("只给用户lunlun88查看,暂无权限查看!")
}
}else {
next();//放行
}
},
children: []
}
(5)组件内路由守卫
//通过路由规则---通过路由切换,进入该组件时调用
beforeRouteEnter(to,form,next){
if (to.meta.isTrue){//判断当前路由是否需要进行权限配置
if (sessionStorage.getItem("user") == "lunlun88"){//权限控制的具体规则
next();//放行
}else {
alert("只给用户lunlun88查看,暂无权限查看!")
}
}else {
next();//放行
}
},
//通过路由规则---通过路由切换,离开该组件时调用
beforeRouteLeave(to,form,next){
next();
},