在項目做得差不多的時候,突然產品提了個這樣的需求,例如頁面導航目前在首頁,再點擊一次首頁頁面要刷新重新渲染,這個刷新不是F5的那種刷新
接到這個需求后我也在網上找了很多資料,例如:https://blog.csdn.net/qq_39009348/article/details/81700082
文章里說的方法也可以解決問題,但是在項目已經做得差不多的時候,這樣要在每個頁面都修改就很難受了,所以文章里的方法不適合我
1.我換了種方式,一開始App.vue用的是文章里提到的方法,這個是繞不開的,這里我用了Vuex全局狀態控制來代替原文章里reload方法的作用
1 <template> 2 <div id="app"> 3 <router-view v-if="isRouterAlive"/> 4 </div> 5 </template> 6 <script> 7 export default { 8 computed:{ 9 isRouterAlive(){ 10 return this.$store.state.isRouterAlive // 用來解決路由相同不刷新問題 11 } 12 } 13 } 14 </script>
2.在store.js文件里定義isRouterAlive屬性
1 import Vue from 'vue' 2 import Vuex from 'vuex' 3 4 Vue.use(Vuex) 5 6 export default new Vuex.Store({ 7 state: { 8 isRouterAlive: true 9 }, 10 mutations: { 11 setIsRouterAlive(state,data){ 12 state.isRouterAlive = data; 13 } 14 }, 15 actions: { 16 setIsRouterAlive(context,data){ 17 context.commit("setIsRouterAlive",data) 18 } 19 } 20 })
3.監聽store的屬性,避免異步問題
1 /** 2 * 監聽isRouterAlive, 3 * 當被設為false時, 4 * 將它設為true,避免異步問題 5 */ 6 store.watch( 7 // 當返回結果改變... 8 (state) => { 9 return state.isRouterAlive 10 }, 11 // 執行回調函數 12 (newVal,oldValue) => { 13 if(!newVal){ 14 store.dispatch('setIsRouterAlive', true) 15 } 16 } 17 )
4.修改路由router.js,前置路由守衛攔截
1 import Vue from 'vue' 2 import Router from 'vue-router' 3 import store from '@/store' 4 // 立個flag,標識是不是第一次路由(F5刷新后第一次路由) 5 let flag = true; 6 //路由攔截器 7 // to: Route: 即將要進入的目標 路由對象 8 //from: Route: 當前導航正要離開的路由 9 router.beforeEach((to, from, next) => { 10 to.query.timestamp = new Date().getTime(); // 每次路由都加上參數,確保每次路由都能被攔截 11 if (to.path === from.path && Object.keys(to.query).length === 1 && !flag) { // 路由地址一樣,參數個數等於1,也就是只有上面設置的默認參數,不是第一次路由 12 store.dispatch('setIsRouterAlive', false); // 設置isRouterAlive為false 13 14 } 15 next(); 16 flag = false; 17 18 }); 19 export default router;
這樣子就實現了我的需求,只用修改4個文件,代碼量不多,to.query.timestamp = new Date().getTime();這行代碼很關鍵,沒有這行代碼,路由相同的路由時是沒有任何一點反應的,不會進入守衛也不會被watch監聽到,
