隨着vue3.0的發布,vue-router發布了4.0版本,文檔 很明了,提供了vue2路由到vue3的變化和寫法指導。
vue2:
// transition <transition name="van-fade"> <router-view /> </transition> // keep-alive <keep-alive> <router-view v-if="this.$route.meat.keepAlive"></router-view> </keep-alive> <keep-alive v-if="!this.$router.meta.keepAlive"></keep-alive>
vue3:
<router-view v-slot="{ Component, route }"> <transition :name="route.meta.transitionName"> <keep-alive v-if="route.meta.keepAlive"> <component :is="Component" /> </keep-alive> <component :is="Component" v-else /> </transition> </router-view>
需要使用 v-slot API來傳入渲染的comp和route對象,而不再用this.$route
route.js寫法大體沒啥變化,寫在最后的未匹配上路由的rediect,需要用正則來匹配
{ // path: '/*', path: '/:pathMatch(.*)*', redirect: '/', },
監聽路由前進后退實現transtion的動畫效果,查了許多資料都有點不太完善,有用數組存住history 每次手動push和pop然后比對的,有用storage的,有用子路由‘/’來對比的...
我的方式:
// route router.beforeEach((to, from) => { const toDepth = to.path.split('/').length; const fromDepth = from.path.split('/').length; to.meta.transitionName = toDepth > fromDepth ? 'slide-left' : (to.path === store.state.pushPath ? 'slide-left' : 'slide-right'); }); // store state: { pushPath: '', }, mutations: { setPushPath(state, payload) { state.pushPath = payload; }, }, // util export const push = (path: string, params?: Record<string, string | number>): void => { store.commit('setPushPath', path); router.push({ path, params }); };
每次跳轉使用自己簡單封裝的路由api,記錄是前進還是后退。 可還行
更新一下,這種 v-if 的方式,其實是有問題的,太久沒登錄博客了,項目里面已經發現了問題改用 include 方式,沒有更新到文章。
原因是一旦有新打開的頁面 , 會重新加載keep-alive組件 , 丟失所有緩存,導致回退頁面的時候還是會走mounted,重新加載頁面。
那么,就用 include 吧!
執行 watch 路由的操作,可以在app.vue里面寫watch方式,也可以就在route里面的 beforeEach 方法里面去修改數組,通過store來綁定傳值。
// route router.beforeEach((to, from, next) => { const toDepth = to.path.split('/').length; const fromDepth = from.path.split('/').length; // to.meta.transitionName = // toDepth > fromDepth ? // 'van-slide-left' : // (to.path === store.state.pushPath ? // 'van-slide-left' : // 'van-slide-right'); const isPush = toDepth > fromDepth || to.path === store.state.pushPath; to.meta.transitionName = isPush ? 'van-slide-left' : 'van-slide-right'; if (to.meta.keepAlive) { store.commit('addIncludes', to.name); } if (from.meta.keepAlive && !isPush) { store.commit('minusIncludes', from.name); } next(); }); // store state: { pushPath: '', include: [] }, mutations: { setPushPath(state, payload) { state.pushPath = payload; }, addIncludes(state, payload) { if (!state.include.includes(payload)) { state.include.push(payload); } }, minusIncludes(state, payload) { const index = state.include.indexOf(payload); if (index !== -1) { state.include.splice(index, 1); } }, },