第六章 router专题
一、router-link
1、不带参数
<router-link :to="{name:'home'}">
<router-link :to="{path:'/home'}">
2、带参数
<router-link :to="{name:'home', params: {id:1}}">
// 路由配置 path: "/home/:id" 或者 path: "/home:id"
url的参数不可见,刷新后参数会消失
<router-link :to="{name:'home', query: {id:1}}">
// 路由可不配置
url带的参数是可见的,刷新后参数不会消失
二、root.$router.push() (函数里面调用)
1、不带参数
this.$router.push('/home')
this.$router.push({name:'home'}) this.$router.push({path:'/home'})
2、query传参
this.$router.push({name:'home',query: {id:'1'}}) this.$router.push({path:'/home',query: {id:'1'}})
url带的参数是可见的,刷新后参数不会消失
3、params传参
this.$router.push({name:'home',params: {id:'1'}})
// 路由配置 path: "/home/:id" 或者 path: "/home:id" ,
// 不配置path ,,刷新页面参数会消失
// 配置path,刷新页面id会保留
4、query和params区别
query跳转配合路由 path 属性,传参为明文,url上参数可见,刷新后参数不会消失
Params路转配合路由 name 属性,传参为密文,url上参数不可能,刷新后参数会消失
三、Router跳转、接收参数
query参数路转
root.$router.push({ path:'/select', //跳转的路径 query:{ id:this.id , } })
参数接收:root.$route.query.xxxxxxx
Params参数路转
root.$router.push({ name:‘Select', //跳转的路径 params:{ id:this.id , } })
参数接收:root.$route.params.xxxxxxx
$router 和$route 的区别:
router为VueRouter的实例,相当于一个全局的路由器对象,里面含有很多属性和子对象.
route相当于当前正在跳转的路由对象,可以从里面获取name,path,params,query等.
四、路由守卫
1.router.beforeEach((to,from,next))路由跳前:
ext: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next() 执行了to里面的路由对象
进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false):
中断当前的导航。
如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next('/') 或者 next({ path: '/' }):
跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 toprop 或 router.push 中的选项。
next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
确保要调用 next 方法,否则钩子就不会被 resolved。
2.作用(权限验证,动态路由)
router.beforeEach((to, from, next) => { NProgress.start() // 开始 progress bar if (getToken()) { // 判断token /* has token*/ if (to.path === '/login') { next({ path: '/' }) NProgress.done(); } else { if (store.getters['user/roles'].length === 0) { // 判断当前用户是否已拉取完user_info信息 store.dispatch('user/GetUserInfo').then(res => { // 拉取user_info const roles = res.data.roles // note: roles must be a array! such as: ['editor','develop'] store.dispatch('permission/GenerateRoutes', { roles }).then(() => { // 根据roles权限生成可访问的路由表 router.addRoutes(store.getters["permission/addRouters"]) // 动态添加可访问路由表 next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record }) }).catch((err) => { store.dispatch('FedLogOut').then(() => { Message.error(err) next({ path: '/' }) }) }) } else { next(); }
} } else { /* 无 token */ if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入 next() } else { next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页 NProgress.done() // 如果是登入页面,要手动处理 } } }) router.afterEach(() => { NProgress.done() // finish progress bar })
五、动态路由
将路由分为constantRouterMap和asyncRouterMap组,在路由守卫中,根据用户的权限,去匹配asyncRouterMap组中的路由加载到router中去:
if (store.getters['user/roles'].length === 0) { // 判断当前用户是否已拉取完user_info信息 store.dispatch('user/GetUserInfo').then(res => { // 拉取user_info const roles = res.data.roles // note: roles must be a array! such as: ['editor','develop'] store.dispatch('permission/GenerateRoutes', { roles }).then(() => { // 根据roles权限生成可访问的路由表 router.addRoutes(store.getters["permission/addRouters"]) // 动态添加可访问路由表 next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record }) }).catch((err) => { store.dispatch('FedLogOut').then(() => { Message.error(err) next({ path: '/' }) }) })
permission/GenerateRoutes方法:
import { asyncRouterMap, constantRouterMap } from "@/router";
/**
* 通过meta.role判断是否与当前用户权限匹配
* @param roles
* @param route
*/
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
return roles.some((role) => route.meta.roles.includes(role));
} else {
return true;
}
}
/**
* 递归过滤异步路由表,返回符合用户角色权限的路由表
* @param routes asyncRouterMap
* @param roles
*/
function filterAsyncRouter(routes, roles) {
const res = [];
routes.forEach((route) => {
const tmp = { ...route };
if (hasPermission(roles, tmp)) {
if (tmp.children) {
tmp.children = filterAsyncRouter(tmp.children, roles);
}
res.push(tmp);
}
});
return res;
}
const state = {
routers: constantRouterMap,
addRouters: [],
};
const getters = {
permission_routers: (state) => state.routers,
addRouters: (state) => state.addRouters,
};
const mutations = {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers;
state.routers = constantRouterMap.concat(routers);
console.log(state.routers);
},
};
const actions = {
GenerateRoutes({ commit }, data) {
return new Promise((resolve) => {
const { roles } = data;
let accessedRouters;
if (roles.includes("admin")) {
accessedRouters = asyncRouterMap;
} else {
accessedRouters = filterAsyncRouter(asyncRouterMap, roles);
}
commit("SET_ROUTERS", accessedRouters);
resolve();
});
},
};
export default {
namespaced: true,//vuex 命名空间
state,
getters,
mutations,
actions,
};

浙公网安备 33010602011771号