vue中 做权限管理 使用router.addRoutes()动态添加路由以及解决刷新失效,跳转后刷新失效问题

最近在公司做知识储备,有个权限的问题干扰了我2天,今天终于把他理顺了!!!

一、需求明确

我想做的是后台管理系统的权限管理,(所有的数据都是使用mockJs模拟得来),登录的时候,发送表单验证,验证成功后,后台返回权限列表,权限不同,返回的列表不同,拿到权限列表后,把权限列表渲染出来在页面侧边栏上。

 

 

二、注意点

(1) 前端提前设置静态的权限列表,通常只包括页面公共的部分,比如 login。

(2)前端提前定义所有的权限列表,将其定义为一个数组,该数组中包含所有的权限。

(3)后台返回的数据是该用户拥有的所有权限列表,一般写成路由形式,但只包含name即可,如:

{
    "code": 0,
    "message": "获取权限成功",
    "data": [
        {
            "name": "订单管理",
            "children": [
                {
                    "name": "订单列表"
                },
                {
                    "name": "生产管理",
                    "children": [
                        {
                            "name": "生产列表"
                        }                     
                    ]
                },
                {
                    "name": "退货管理"
                }
            ]
        }
    ]
}


此代码块来自:https://www.cnblogs.com/zhengrunlin/p/8981017.html  侵删

三、思路与实现

(1)当用户点击登录的时候,验证成功后,可以获取当前用户的id(token)存储到sessionStorage中。

(2)根据 '后台返回的权限列表(getList)',去比对 '我们提前定义好的权限列表(powerList)',然后得出 '应该动态添加的权限列表(list)' ,并存放到vuex中,最后执行addRoutes把比对出来的权限路由列表动态添加到路由中即可。

(3)进入home页面,渲染侧边栏。

 

四、问题

(1)vuex中数据存储在内存中,刷新后失效需要重新获取。因此会出现动态页面失效问题。我们需要根据是否为刷新页面来重新加载即可。

(2)进入动态加载的页面,然后再刷新,也会出现上面的情况

五、解决方法

在router的全局导航守卫beforeEach中设置,根据vuex中是否有list 来判断是否为刷新页面,如果有那么是第一次登陆, 如果没有,那么就为刷新页面,需要重新执行即可。

getRoutes就是执行路由对比,然后执行addRoutes的函数,因为其中有获取后台的路由列表这一步,为异步操作,所以应该放在action中

<think>嗯,用户的问题是关于Vue3中使用useRouter的$router.push方法两次调用导致页面不刷新的情况。我需要先理解这个问题的原因,然后找到解决方案。 首先,用户提到的是Vue3,所以应该使用Composition API中的useRouter。而$router.push在Vue3中可能被用作router.push,因为useRouter返回的是router对象,所以通常会用router.push而不是$router.push,但可能用户习惯这样写了,或者代码中确实有这样的用法。 然后,两次调用$router.push导致页面不刷新。这可能是因为Vue Router的机制,当跳转到相同的路由但参数不同时,默认情况下组件不会重新渲染,因为Vue会复用相同的组件实例。这时候,生命周期钩子如onMounted不会再次触发,导致页面内容没有更新。 我记得Vue Router的文档中提到过这种情况,可以通过给router-view添加key属性,或者使用afterEach钩子来强制刷新。或者,在跳转使用replace方法而不是push,但用户的问题是需要两次push,所以replace可能不适用。 另外,用户提供的引用内容中提到,push使用的是history.pushState,不会刷新页面,只是添加历史记录。所以当两次push相同的路由但参数不同时,Vue可能不会重新加载组件,导致页面不更新。 解决方案方面,可以尝试以下几种方法: 1.路由跳转后,强制重新加载当前组件。可以通过在push之后重新加载当前页面,但这样可能会有闪烁,不是最佳方案。 2.router-view添加一个唯一的key,比如基于当前路由的完整路径,这样当路由变化时,Vue会重新创建组件实例,触发生命周期钩子。这个方法比较常见,也比较有效。 3. 使用beforeRouteUpdate导航守卫,在组件内监听路由参数的变化,然后手动更新数据。这需要用户在组件中实现这个守卫,并在回调中处理数据加载。 4.跳转使用...展开运算符传递参数,或者在push时传递name而不是path,确保参数正确传递,避免因为params和path一起使用导致的参数失效问题,如引用[2]提到的。 需要验证这些方法在Vue3中的适用性。例如,在Vue3的组合式API中,beforeRouteUpdate可能被替换为onBeforeRouteUpdate,或者需要另外导入。同时,router-view的key方法仍然有效,因为这是Vue的机制,不依赖版本。 另外,用户可能遇到的另一个问题是,两次push的路由路径相同但参数不同,但Vue Router没有检测到参数变化,所以没有重新渲染。这时候,添加key到router-view可以解决,因为当key变化时,组件会重新渲染。 总结可能的解决方案: - 为router-view添加key,值为$route.fullPath,这样每次路由变化都会重新渲染组件。 - 使用onBeforeRouteUpdate钩子来响应路由参数变化,并重新获取数据。 - 确保传递参数的方式正确,避免因为path和params混用导致参数未正确传递,从而路由没有变化。 此外,用户可能没有正确监听路由参数的变化,比如在setup中使用watch来监听route.params,并在变化时执行数据获取操作。这也是一个可行的解决方案。 需要检查用户是否在组件中正确处理了参数变化,比如在onMounted中获取数据,但如果没有监听参数变化,当路由参数改变时,组件不会重新挂载,导致数据不更新。 所以,可能的步骤是: 1. 确保路由配置正确,参数变化能被检测到。 2. 在组件中使用watch来监听路由参数,并在变化时重新加载数据。 3. 或者使用router-view的key强制重新渲染。 现在需要将这些整理成中文,结构清晰,分步骤说明,并引用提供的参考资料。</think>### 分步解决方案 在Vue3中,`useRouter().push()`两次调用导致页面不刷新问题通常由以下原因引起: 1. **Vue Router的组件复用机制**:当路由目标相同但参数变化时,Vue会复用组件实例而非重新创建,导致生命周期钩子(如`onMounted`)不会触发[^1]。 2. **参数传递方式错误**:若动态路由参数未正确传递,Vue Router可能无法检测到变化[^2]。 #### 解决方法 **方法1:为`<router-view>`添加唯一`key`** 在模板中强制组件重新渲染: ```vue <router-view :key="$route.fullPath"></router-view> ``` 原理:通过`$route.fullPath`生成唯一标识,路由变化时触发组件销毁和重建。 **方法2:监听路由参数变化** 在组件中使用`watch`或导航守卫响应参数变化: ```typescript import { watch } from "vue"; import { useRoute } from "vue-router"; const route = useRoute(); watch( () => route.params.id, // 监听具体参数 (newId) => { fetchData(newId); // 重新加载数据 } ); ``` **方法3:使用`onBeforeRouteUpdate`导航守卫** 在组件内响应路由更新: ```typescript import { onBeforeRouteUpdate } from "vue-router"; onBeforeRouteUpdate((to, from) => { if (to.params.id !== from.params.id) { fetchData(to.params.id); // 根据新参数加载数据 } }); ``` **方法4:确保参数传递规范** 避免`path`与`params`混用,优先使用`name`跳转: ```typescript // 正确方式(使用name+params) router.push({ name: "UserProfile", params: { id: 123 }, }); // 错误方式(path+params不生效) router.push({ path: "/user", params: { id: 123 }, // 此params会被忽略 }); ``` ### 总结 通过强制组件重新渲染、监听参数变化或规范参数传递,可解决路由跳转后页面不刷新问题。若需保留浏览器历史记录栈,优先选择**方法1**或**方法2**;若需精细化控制数据加载,选择**方法3**。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值