vue 中 vue-router、transition、keep-alive 怎么结合使用?

我的路由切换有左滑右滑的效果,于是我是这么使用的。

 <transition :name="name">
     <router-view class="router-view"></router-view>
  </transition>

现在我想缓存组件,让列表页返回的时候能保存位置。网上查了下,一般是这么用的

  <keep-alive>
    <router-view v-if="$route.meta.keepAlive">
    </router-view>
  </keep-alive>
  <router-view v-if="!$route.meta.keepAlive"></router-view>

我于是把两者结合起来,这样用

    <transition :name="name">
      <keep-alive>
        <router-view  v-if="$route.meta.keepAlive"></router-view>
      </keep-alive>
      <router-view v-if="!$route.meta.keepAlive"></router-view>
    </transition>

这样后端构建没问题,但是前端就报错了:

<transition> can only be used on a single element.

报错信息让用transition-group,于是

    <transition-group :name="name">
      <keep-alive key="keep-alive">
        <router-view class="router-view" v-if="$route.meta.keepAlive"></router-view>
      </keep-alive>
      <router-view class="router-view" v-if="!$route.meta.keepAlive" key="not-keep-alive"></router-view>
    </transition-group>

结果又报错:

 <transition-group> children must be keyed: <keep-alive>

明明是加了key了的。

研究发现transition-group 其实就是一个div或者span等html元素。
于是我尝试自己加这层html。

---- 分割线---

我没有再尝试加这层 html!!!因为我用下面的方式搞定了!

    <transition :name="name">
      <keep-alive>
        <router-view class="router-view" v-if="$route.meta.alive"></router-view>
      </keep-alive>
    </transition>
    <transition :name="name">
      <router-view class="router-view" v-if="!$route.meta.alive"></router-view>
    </transition>

就是两个transition,一个负责keep-alive组件的动画,一个负责 not-keep-alive的动画。两边各管各的。

如果有隐患,后续我会更新。

最后,请教怎么把问题改成文章的形式。。不知道为什么,提问题的帖子就变成了回答问题的帖子了。。。

另外,请教下大家都是怎么处理这个问题的。、

阅读 21.2k
8 个回答
    <transition :name="name">
      <keep-alive>
        <router-view class="router-view" v-if="$route.meta.alive"></router-view>
      </keep-alive>
    </transition>
    <transition :name="name">
      <router-view class="router-view" v-if="!$route.meta.alive"></router-view>
    </transition>
使用 transition-group 可以解决这个问题
1. 你原来的写法
<transition-group :name="name">
      <keep-alive key="keep-alive">
        <router-view class="router-view" v-if="$route.meta.keepAlive"></router-view>
      </keep-alive>
      <router-view class="router-view" v-if="!$route.meta.keepAlive" key="not-keep-alive"></router-view>
    </transition-group>
2. 我修改之后的写法

就是多加了一层div,v-if挪到div上,切换路由的时候就有transition-group默认的过渡效果了

<transition-group :name="name">
    <div key="keep-alive"  v-if="$route.meta.keepAlive">
      <keep-alive key="keep-alive">
        <router-view class="router-view"></router-view>
      </keep-alive>
    </div>  
      <router-view class="router-view" v-if="!$route.meta.keepAlive" key="not-keep-alive"></router-view>
    </transition-group>

你好,我也遇到你这个问题,但是我用你最后一个方式,动画就没了

两个router-view都需要加key?你的key没有加冒号?

正好遇到了这个问题 试一下

遇到同样问题,折磨人啊,我想到的也是这种办法,但是不知道有什么隐患不?

新手上路,请多包涵
<template>
  <div id="app">
    <transition :name="transitionName">
      <keep-alive>
        <router-view v-if="$route.meta.keepAlive" :key="$route.meta.keepAlive"></router-view>
      </keep-alive>
    </transition>
    <transition :name="transitionName">
      <router-view v-if="!$route.meta.keepAlive" :key="!$route.meta.keepAlive"></router-view>
    </transition>
  </div>
</template>
watch: {
    // 使用watch 监听$router的变化
    $route(to, from) {
      // 如果to索引大于from索引,判断为前进状态,反之则为后退状态
      if (to.meta.keepAlive) {
        this.transitionName = "slide-left";
      } else {
        if (to.meta.index > from.meta.index) {
          // 设置动画名称
          this.transitionName = "slide-left";
        } else {
          this.transitionName = "slide-right";
        }
      }
    },
  },

.slide-right-enter-active,
.slide-right-leave-active,
.slide-left-enter-active,
.slide-left-leave-active {
width: 100vw;
will-change: transform;
transition: all 500ms;
position: absolute;
}
.slide-right-enter {
opacity: 0;
transform: translate3d(-100%, 0, 0);
}
.slide-right-leave-active {
opacity: 0;
transform: translate3d(100%, 0, 0);
}
.slide-left-enter {
opacity: 0;
transform: translate3d(100%, 0, 0);
}
.slide-left-leave-active {
opacity: 0;
transform: translate3d(-100%, 0, 0);
}

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题