vue3使用路由keep-alive和监听路由实现transition

  随着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);
      }
    },
  },

 

 

 

 

posted @ 2020-12-19 12:07  大禹不治水  阅读(8023)  评论(5编辑  收藏  举报