第六章 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'})

2query传参

this.$router.push({name:'home',query: {id:'1'}}) this.$router.push({path:'/home',query: {id:'1'}})

url带的参数是可见的,刷新后参数不会消失

3params传参

this.$router.push({name:'home',params: {id:'1'}})

// 路由配置 path: "/home/:id" 或者 path: "/home:id" ,

// 不配置path ,,刷新页面参数会消失

// 配置path,刷新页面id会保留

4queryparams区别

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 的区别:

routerVueRouter的实例,相当于一个全局的路由器对象,里面含有很多属性和子对象.

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: truename: '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 })

五、动态路由

将路由分为constantRouterMapasyncRouterMap组,在路由守卫中,根据用户的权限,去匹配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, };

猜你喜欢

转载自www.cnblogs.com/wangchao1990/p/12756216.html