需求说明

1、部分路由需要做缓存
2、单页面中部分组件需要重新渲染,比如:对表格进行新增、删除、修改等之后需要刷新页面中的部分组件

keep-alive
<keep-alive>包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们

分析及解决

路由缓存

由于只缓存部分页面,

<template>
  <div id="app">
  <!--此处省略若干代码-->
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

这种将<router-view>全部缓存的方式不可行,需要加一些判断来实现。

<template>
  <div id="app">
    <!--此处省略若干代码-->
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</template>

再配合在路由定义中加入:

meta: {keepAlive: true}

这样就可以实现只缓存路由keepAlive设置为true的路由;
值得注意的是:

!!!建议在App.vue中就设置<keep-alive>,而且如果想要缓存的路由是某个父路由的子路由,这个父路由是不用使用<keep-alive>的,直接使用<router-view>就行了,否则会造成缓存的混乱。

页面组件刷新

通常手动刷新组件就是使用$nextTick()进行,如:

<template>
  <div>
    <div v-if="testComponentVisible"></div>
  </div>
</template>
data(){
    return {
       testComponentVisible: true,
    }
  },
  methods: {
    closeComponent() {
			this.testComponentVisible = false;
			this.$nextTick(()=> {
				this.testComponentVisible = true;
			})
		}
  },

但是如果组件刷新的情况变得很多之后就会重复多次定义上面的代码,如何一劳永逸呢?
具体做法是:
App.vue中定义一个全局使用,

<template>
  <div id="app">
    <!--此处省略若干代码-->
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive && isRouterAlive"></router-view>
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive && isRouterAlive"></router-view>
  </div>
</template>
provide() {
    return {
      reload: this.reload,
    };
  },
  data() {
    return {
      isRouterAlive: true
    };
  },
  methods: {
    reload() {
      console.log('启动');
      this.isRouterAlive = false;
      this.$nextTick(function () {
        this.isRouterAlive = true;
      });
    },
  },

provide由于是在App.vue中定义所以是可以给到所有的组件之间获取的。
在子组件中使用inject: ['reload'],就可以获取;
比如子组件<my-test-component>

<my-test-component @reload="reload"></my-test-component>

子组件里面只需要在完成对表格进行新增、删除、修改等之后

this.$emit("reload")

这样就可以刷新组件了。

Logo

前往低代码交流专区

更多推荐