vue 部分页面缓存情况下问题记录

283 阅读2分钟

最近在做后台项目中遇到一个需求是,pageA跳转pageA编辑页时保留pageA当前状态,pageA跳转pageB时不再保留状态,其实也就是缓存页面问题。于是就拿vue-admin-template为模版进行了测试。

以Tree页面为目标页面,实现在输入框输入后跳转Table页时保留输入内容,而跳转其他页面时不保留。

一、添加keepAlive配置

{
    path: 'tree',
    name: 'Tree',
    component: () => import('@/views/tree/index'),
    meta: { title: 'Tree', icon: 'tree', keepAlive: true }
}

在meta里添加keepAlive参数用于标示缓存目标页面。

二、router-view添加缓存设置

添加缓存就是把router-view放在标签里即可。

AppMain.vue

<template>
  <section class="app-main">
    <transition name="fade-transform" mode="out-in">
      <keep-alive>
        <router-view v-if="$route.meta.keepAlive" :key="key" />
      </keep-alive>
      <router-view v-if="!$route.meta.keepAlive" :key="key" />
    </transition>
  </section>
</template>

如上,添加keepAlive判断后就能实现目标页面添加缓存功能。

这时页面会报错,

transition标签只能用于单个元素/组件的过渡动效。改用transion-group标签。

<template>
  <section class="app-main">
    <transition-group name="fade-transform" mode="out-in">
      <keep-alive>
        <router-view v-if="$route.meta.keepAlive" :key="key" />
      </keep-alive>
      <router-view v-if="!$route.meta.keepAlive" :key="key" />
    </transition-group>
  </section>
</template>

添加key

<template>
  <section class="app-main">
    <transition-group name="fade-transform" mode="out-in">
      <keep-alive key="aliveItem">
        <router-view v-if="$route.meta.keepAlive" :key="key" />
      </keep-alive>
      <router-view v-if="!$route.meta.keepAlive" :key="key" />
    </transition-group>
  </section>
</template>

依旧会报错,keep-alive标签未添加key。查看keep-alive源码可以到,这是因为keep-alive是一个抽象组件,对于抽象组件来说,除了slot属性之外,其他属性在组件内部并没有意义,例如class样式,所以在Vnode层剔除掉多余的属性。

// 创建子组件Vnode过程
function createComponent(Ctordata,context,children,tag) {
    // abstract是内置组件(抽象组件)的标志
    if (isTrue(Ctor.options.abstract)) {
        // 只保留slot属性,其他标签属性都被移除,在vnode对象上不再存在
        var slot = data.slot;
        data = {};
        if (slot) {
            data.slot = slot;
        }
    }
}

······

为了保留动画效果,那就拆开,再改改代码。

<template>
  <section class="app-main">
    <transition name="fade-transform" mode="out-in">
      <keep-alive key="aliveItem">
        <router-view v-if="$route.meta.keepAlive" :key="key" />
      </keep-alive>
    </transition>
    <transition name="fade-transform" mode="out-in">
      <router-view v-if="!$route.meta.keepAlive" :key="key" />
    </transition>
  </section>
</template>

测试过后效果还行。这块搞定了,还差点意思,跳转非Table页面时不保存缓存。

views/tree/index.vue

beforeRouteEnter(to, from, next) {
    if (from.name !== 'Table') {
      to.meta.keepAlive = true
    } else {
      to.meta.keepAlive = false
    }
    next()
}

路由进入前做个判断控制就行了。