Vue keepAlive页面强制刷新方式
作者:milugloomy
keepAlive页面强制刷新
需求
现在有一个需求,要求不刷新浏览器,但要刷新路由中的组件
方案
将需要keepAlive的页面name加入到keep-live的include中。
Vue的transition组件,有一个after-enter钩子事件,待子组件插入完毕调用,正好适合这个场景,在这个钩子中,将当前组件添加到keep-live的include中。
在刷新时,从keepAliveArr中移除当前组件的name,然后利用v-if删除router-view组件,在nextTick事件后将router-view添加回来,实现组件的刷新
代码
template
<transition @after-enter="afterRouterChange"> <keep-alive :include="keepAliveArr"> <router-view v-if="refreshControl" ref="child"/> </keep-alive> </transition> <button @click="refreshChild"></button>
script
export default { name: 'index', data () { return { keepAliveArr: [], refreshControl: true } }, methods: { refreshChild () { // 先移除,再加载,强制刷新子页面 const name = this.$refs.child.$options.name this.keepAliveArr.splice(this.keepAliveArr.indexOf(name), 1) this.refreshControl = false this.$nextTick(() => this.refreshControl = true) }, afterRouterChange () { // 记录子组件name,用于keepalive const childName = this.$refs.child.$options.name this.pageTabList[this.pageTabIndex].name = childName if (!this.keepAliveArr.includes(childName)) { this.keepAliveArr.push(childName) } } } }
keep-alive缓存页面刷新
vue文件keep-alive缓存页面刷新
概述:
vue开发项目时,需要缓存多个页面的情况
使用场景:
例如:现有4个页面,页面1,页面2,页面3,页面4
要求:
- 1、从1-2-3-4依次跳转时,每次都刷新页面,不进行缓存;
- 2、从4-3-2-1依次返回时,页面不刷新,依次取缓存页面;
总结:外到内都需要刷新,内到外皆获取缓存页面;
实现方式:keep-alive、vuex、路由钩子函数beforeRouteEnter、beforeRouteLeave
1.vuex部分
import Vue from 'vue'; import Vuex from 'vuex'; let storeModules = {}; Vue.use(Vuex); export default new Vuex.Store({ state: { keepAlive: [] }, getters: {}, mutations: { change_keepalive: (state, keepAlive) => { state.keepAlive = keepAlive; } }, actions: {}, modules: storeModules });
2.app.vue部分
<template> <div> <keep-alive :include="$store.state.keepAlive"> <router-view></router-view> </keep-alive> </div> </template> <script> export default {}; </script>
使用<keep-alive>的include属性,来实现动态的组件缓存。
先说一下include属性,它的值可以是:字符串,正则表达式,数组
首先我们需要知道keep-alive可以根据include中的值来匹配当前路由对应组件的name属性,来判断这个路由中的组件是否需要缓存。
3.页面1内部写法
methods: { // 跳转 goLink(){ this.$store.commit('change_keepalive', ['页面1','页面2','页面3']) this.$router.push({ path:'/页面2', }) } }, beforeRouteEnter (to, from, next) { next(vm => { vm.$store.commit('change_keepalive', ['页面1']) }) }
4.页面2内部写法
beforeRouteEnter (to, from, next) { next(vm => { if (from.path.indexOf('页面3') > -1) { vm.$store.commit('change_keepalive', ['页面1','页面2']) } }) }, beforeRouteLeave (to, from, next) { if (to.path.indexOf('页面3') > -1) { this.$store.commit('change_keepalive', ['页面1','页面2', '页面3']) } else if (to.path.indexOf('页面1')>-1) { this.$store.commit('change_keepalive', ['页面1']) } next() }
5.页面3内部写法
beforeRouteEnter (to, from, next) { next(vm => { if (from.path.indexOf('页面4') > -1) { vm.$store.commit('change_keepalive', ['页面1','页面2', '页面3']) } }) }, beforeRouteLeave (to, from, next) { if (to.path.indexOf('页面4') > -1) { this.$store.commit('change_keepalive', ['页面1','页面2', '页面3']) } else if (to.path.indexOf('页面2') > -1) { this.$store.commit('change_keepalive', ['页面1','页面2']) } next() }
6.页面4
不需要缓存则无需添加任何东西,正常书写即可,如需添加设置缓存,则按照上方更改添加配置即可。
注:
其中from.path.indexOf('页面x')中页面x为router的path属性
this.$store.commit('change_keepalive', ['页面1','页面2'])中的页面x为组件的name属性(不是路由的name,是组件的name)
<script> export default { name:'index',//组件name components: {}, props: {}, data() { return {}; }, computed: {}, watch: {}, created() {}, mounted() {}, methods: {} } </script>```
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。