一、Vue Router的使用
1. 前端路由
路由是一组映射关系(key - value),key为路径,value 为function或component
后端路由:value为function,用于处理客户端提交的请求。服务器接收一个请求时,根据请求 路径找到匹配的函数来处理请求,返回响应数据。
前端路由:value为component,用于展示页面的内容。当浏览器的路径改变时,对应的组件 就会展示
2. vue-router基本使用和特点
A. 基本使用步骤:
(1)定义路由组件,随页面路径变换,切换展示的组件称之为路由组件。
(2)创建路由实例:
// 定义路由的映射规则
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 创建路由实例
export default new VueRouter({
routes
})
(3)挂载到Vue根实例
const app = new Vue({
router
}).$mount('#app')
(4)指定路由组件的展示位置:
<router-view></router-view>会根据路由规则和浏览器路径来展示不同的路由组件。
(5)路由跳转(导航),详情使用请参见Vue Router的基本使用
1. 可以使用vue内置组件<router-link></router-link to="路径">跳转到不同的路由组件
2. 编程式路由导航API:this.$router.push(),this.router.replace(),this.router.go(n), this.$router.back(),this.$router.forward()
(6)嵌套路由:注意定义时的children不用写完整路径,跳转时要写完整路径。详情参见 Vue Router-嵌套路由
(7)重定向及别名:参见Vue Router-重定向和别名
B. 特点
(1). 通过切换隐藏的路由组件默认是被销毁的,等要展示的时候会重新创建。
(2). 每个组件都要自己的$route属性,里面存储的该组件的路由信息。
(3). 整个应用只有一个router,可以通过组件的$router属性获取。
3.路由传参
(1)params传参
1.在配置路由时,声明接收params参数
{
path: 'details/:id/:title', // 使用占位符声明接收params参数
component: Detail,
name: 'xiangqing'
}
2.传递参数:
// 字符串写法
<router-link :to="/details/123/macbook2019">跳转到details</router-link>
// 对象写法
<router-link :to="{
name: 'xiangqing',
paramas: {
id: 123,
title: 'macbook2019'
}
}">跳转到details</router-link>
3. 接收参数:
在跳转之后的组件中可以通过$route.params中得到
(2)query传参
1.传递参数
/ 字符串写法
<router-link :to="/details?id=123&title=macbook2019">跳转到details</router-link>
// 对象写法
<router-link :to="{
name: 'xiangqing',
query: {
id: 123,
title: 'macbook2019'
}
}">跳转到details</router-link>
2.接收参数
在跳转之后的组件中可以通过$route.query中得到
(3)props传参
在路由中:
{
name: 'xiangqing',
path: 'details',
component: Detail,
// 布尔模式:props值为true,则把路由收到的所有params参数通过props传给Detail组件,缺点:query参数不行
props: true
// 对象模式:props值为对象,该对象中所有的key-value的组合最终会通过props传给Detail组件,缺点:只能写固定值
props: {id: 123, title: 'MacBook2019'},
// 函数模式:props值为函数,该回调函数基于一个route参数(即每一个组件的$route对象),自由传递参数给Detail组件
props: route => ({ id: route.query.id })
}
4. 缓存路由组件
作用:路由组件在路由切换时会默认被销毁,如果不希望被销毁,可以用缓存方式保持路由组件挂载。
实现:用keep-alive标签将放置路由组件的地方包裹起来
< !-- include里面写要缓存的组件的name -->
<keep-alive include="News">
<router-view></router-view>
</keep-alive>
5. 和路由组件相关的生命周期钩子函数
1. activated 路由组件被激活时触发
2. deactivated 路由组件失活时触发
注意:激活和失活的含义就是路由组件展示和不展示,不等于挂载和销毁(考虑到缓存路由组件的情况),使用的时候直接像生命周期的八个钩子函数一样在对应组件里使用。
二、路由守卫
1. 全局守卫
全局定义,对于每次切换路由时都触发,代码示例:
// 全局前置守卫,初始化时执行,每次路由切换前执行
router.beforeEach((to, from, next) => {
if(to.meta.isAuth) { // 判断当前路由是否需要进行权限控制
if(localStorage.getItem('xxx' == '****')) { // 权限控制的具体规则
next() // 放行,执行跳转
}else {
alert('暂无权限查看')
}
}else {
next() // 放行执行跳转
}
})
// 全局后置路由守卫,初始化执行,每次路由切换后执行
router.afterEach((to, from) => {
if(to.meta.title) {
document.title = to.meta.title // 修改网页title
}else {
document.title = 'vue_test'
}
})
2. 路由独享守卫
单独定义在某个路由规则里的守卫:beforeEnter
const routes = [
{
path: "/user/:id",
component: UserDetails,
beforeEnter: (to, from ,next) => {
if (to.meta.isAuth) {
// 判断当前路由是否需要进行权限控制
if (localStorage.getItem("xxx" === "****")) {
// 权限控制的具体规则
next(); // 放行,执行跳转
} else {
alert("暂无权限查看");
}
} else {
next(); // 放行执行跳转
}
},
},
];
3. 组件内路由守卫
在组件中使用:
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被验证前调用
// 不能获取组件实例 `this` !
// 因为当守卫执行时,组件实例还没被创建!
next()
},
beforeRouteUpdate(to, from) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
// 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
},
beforeRouteLeave(to, from) {
// 在导航离开渲染该组件的对应路由时调用
// 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
},
三、路由器的hash和histroy模式
1. 基本概念:
a.Vue Router的工作模式分为hash模式和history模式,如不做设置,默认为hash模式。
b. hash模式下,浏览器地址会携带“#”,“#”后的值称之为hash值,hash值不会包含在http请求中,即hash值不会传给服务器。
2. 两种模式区别:
a. hash模式:
1.地址中永远带着“#”号,如果将地址通过第三方手机app分享,若app校验严格,则地址会标记为不合法。
2.对于浏览器的兼容性较好
b. history模式:
1. 地址干净,不带“#”号
2. 兼容性和hash模式相比略差
3. history模式下,形如:http://xxxx:8083/detail/user/title的地址,刷新浏览器时会将/detail/user/title也传给服务器,后端服务器会找不到对应的资源报404,所以应用部署上线时需要后端支持,解决刷新页面404的问题。