乐趣区

vue之vue router

走在前端的大道上
本篇将自己读过的相关 vue router 文章中,对自己有启发的章节片段总结在这(会对原文进行删改), 会不断丰富提炼总结更新。
文章内容 基于 vue 2.0
1.vue router 如何传参?
1.1 params、query 是什么?
params:/router1/:id,/router1/123,/router1/789 // 这里的 id 叫做 params
query:/router1?id=123 ,/router1?id=456 // 这里的 id 叫做 query。
比如:跳转 /router1/:id
<router-link :to=”{name:’router1′,params: { id: status}}” > 正确 </router-link>
<router-link :to=”{name:’router1′,params: { id2: status}}”> 错误 </router-link>
1.2 html 标签传参
params、query 不设置也可以传参,params 不设置的时候,刷新页面或者返回参数会丢失
路由界面:
当你使用 params 方法传参的时候,要在 url 后面加参数名,并在传参的时候,参数名要跟 url 后面设置的参数名对应。params 是路由的一部分, 必须要有,否则会导致跳转失败或者页面会没有内容如图片 :id,

// 上面的 router-link 传参, 也可以使用编程式导航跳转
this.$router.push({name:’router1′,params: { id: status ,id2: status3},query: {queryId: status2}});
// 编程跳转写在一个函数里面,通过 click 等方法来触发
query,是拼接在 url 后面的参数,就没有这种限制,直接在跳转里面用就可以,没有也没关系。
使用路由上面的参数
<template>
<div class=”router1″>
<h1> 接收参数的路由 </h1>
<h1> params.id:{{$route.params}}</h1>
<h1>query.status:{{$route.query.queryId}}</h1>
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
</template>
注意:获取路由上面的参数,用的是 $route,后面没有 r
本节参考文章:vue router 使用 params query 传参,以及有什么区别
1.3 vue this.$router.push() 传参
params 传参注意⚠️:patams 传参,路径不能使用 path 只能使用 name, 不然获取不到传的数据
this.$router.push({name: ‘dispatch’, params: {paicheNo: obj.paicheNo}})
取数据:
this.$route.params.paicheNo
query 传参
this.$router.push({path: ‘/transport/dispatch’, query: {paicheNo: obj.paicheNo}})
取数据:
this.$route.query.paicheNo
2.this.$router 与 this.$route 
在登录页完成登录请求后进行下面的操作 获取路径中存放前一个路径的参数 , 然后跳转到该页面
loginSuccess() {
const {params: { back} } = this.$route;
const route = back || {name: ‘home’};
const {name, params, query} = route;
this.$router.replace({name, params, query});
},
在上面这段代码中出现了两个我们经常混淆的概念: 我们知道 this.$router 是 router 实例,可以用来直接访问路由。我们称 router 配置中每一个对象为一个路由记录,this.$route 是暴露出来用来访问每个路由记录的。因此我们获取参数时使用的是 this.$route 跳转路由时使用的是道 this.$router。
this.$router.push 与 this.$router.replace
上端代码中我们使用了 replace 而不是 push 来跳转路由,这两者的区别是会不会在 history 中产生记录。replace 不会新增记录,而是直接替换掉了这条路由记录。
本节参考文章:vue router+ vuex+ 首页登录判断逻辑
3. 路由懒加载
路由懒加载应该是写大一点的项目都会用的一个功能,只有在使用这个 component 的时候才会加载这个相应的组件,这样写大大减少了初始页面 js 的大小并且能更好的利用游览器的缓存。
首先,可以将异步组件定义为返回一个 Promise 的工厂函数 (该函数返回的 Promise 应该 resolve 组件本身):
const Foo = () => Promise.resolve({ /* 组件定义对象 */})
const Foo = resolve => require([‘./Foo.vue’], resolve)
// 或者
const Foo = () => import(‘./Foo’);
官网:详细
4. 单页及多页应用全局配置 404 页面
4.1 SPA 的 404 路由配置
单页应用配置 404 页面,也区分两种情况:
4.1.1 路由表固定的情况
如果 SPA 的路由表是固定的,那么配置 404 页面就变得非常的简单。只需要在路由表中添加一个路径为 404 的路由,同时在路由表的最底部配置一个路径为 * 的路由,重定向至 404 路由即可。(由于路由表是由上至下匹配的,一定要将任意匹配规则至于最底部,否则至于此路由规则下的路由将全部跳转至 404,无法正确匹配。)
// router.js
export default new Router({
mode: ‘history’,
routes: [
// …
{
name: ‘404’,
path: ‘/404’,
component: () => import(‘@/views/notFound.vue’)
},
{
path: ‘*’, // 此处需特别注意至于最底部
redirect: ‘/404’
}
],
})
4.1.2 路由表动态生成的情况
路由表是动态生成的情况下,也就是说路由表分为两部分,一部分为基础路由表,另一部分是需要根据用户的权限信息动态生成的路由表。
本项目中动态生成路由采用 vue-router 自带的 addRoutes 方法,该方法是会将新的路由规则在原路由表数组的尾部注入的。由于任意匹配重定向至 404 页面的规则必须至于路由表的最底部,所以此处我将重定向至 404 页面的规则抽出,在动态路由注入后,再注入重定向规则,以确保该规则至于路由表最底部。
// router.js
export default new Router({
mode: ‘history’,
routes: [
// …
{
name: ‘404’,
path: ‘/404’,
component: () => import(‘@/views/notFound.vue’)
},
// …other codes
],
})
// notFoundRouterMap.js

export default [
{
name: ‘404’,
path: ‘/404’,
component: () => import(‘@/views/notFound.vue’)
},
},
{
path: ‘*’,
redirect: ‘/404’
}
]
// main.js

//…other codes
router.beforeEach((to, from, next) => {
new Promise((resolve, reject) => {
if (getCookie(tokenName)) {
if (!getInfo()) {
Promise.all([store.dispatch(‘getBasicInfo’), store.dispatch(‘getUserDetail’)]).then(res => {
store.dispatch(‘GenerateRoutes’, { roles}).then(() => {
// 根据用户权限生成可访问的路由表
router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
router.addRoutes(NotFoundRouterMap) // 添加 404 及重定向路由规则
resolve({…to, replace: true}) // 重新加载一次路由,让路由表更新成功后走下面 else 的判断
})

})
} else {
// …other codes
}
} else {
window.location.href = ‘/login.html’
}
}).then(res => {
if (res) {
next(res)
} else {
next()
}
}).catch(err => {
new Error(err)
next(false)
})
4.2 多页应用的 404 路由配置
多页应用区别于 SPA 的不同点是每个页面有自己的一套路由,并且每个页面可能有自己的一套 404 页面风格,当然也可能没有。这时候,就不能再采用动态添加路由规则的方法了。
我采用的方案是在全局导航守卫 beforeEach 中对路由匹配的情况进行判断,这时候就需要用到 vue 导航守卫中的 matched 数组了。如果没有一个匹配上的,那么就重定向至 404 页面。当然,这个 404 页面也单独设置为一个页面。
// permission.js

//…other codes
router.beforeEach((to, from, next) => {
new Promise((resolve, reject) => {
// …other codes
}).then(res => {
if (!to.matched.length) {
window.location = ‘/error.html#/404’
return
}
if (res) {
next(res)
} else {
next()
}
}).catch(err => {
new Error(err)
next(false)
})
本节参考文章:Vue 单页及多页应用全局配置 404 页面实践
5. 后台系统权限控制
具体实现思路

创建 vue 实例的时候将 vue-router 挂载,但这个时候 vue-router 挂载一些登录或者不用权限的公用的页面。
当用户登录后,获取用 role,将 role 和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。
调用 router.addRoutes(store.getters.addRouters) 添加用户可访问的路由。
使用 vuex 管理路由表,根据 vuex 中可访问的路由渲染侧边栏组件。

6. 基于路由的动态过渡
<!– 使用动态的 transition name –>
<transition :name=”transitionName”>
<router-view></router-view>
</transition>
// 接着在父组件内
// watch $route 决定使用哪种过渡
watch: {
‘$route’ (to, from) {
const toDepth = to.path.split(‘/’).length
const fromDepth = from.path.split(‘/’).length
this.transitionName = toDepth < fromDepth ? ‘slide-right’ : ‘slide-left’
}
}
动手理解导航守卫(Vue)
Vue 动态路由的实现 (后台传递路由,前端拿到并生成侧边栏)
手摸手,带你用 vue 撸后台 系列二 (登录权限篇)
vue router 原理
前端的路由模式包括了 Hash 模式和 History 模式。vue-router 在初始化的时候,会根据 mode 来判断使用不同的路由模式,从而 new 出了不同的对象实例。例如 history 模式就用 HTML5History,hash 模式就用 HashHistory。
vue-router 源码:前端路由 vue-router 源码:路由模式

退出移动版