keep-alive page cache problem

One: Summary: Using Vue to develop a single-page application, how to solve the page caching problem (especially on the mobile phone side), how to get the latest data for the newly opened page, and return to the previous page to get the latest cached page data?

Two: Page opening and caching process:

insert image description here

Three: In order to solve the above caching process problem, the knowledge that needs to be understood:

1:keep-alive 组件; 说明: 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们;

   |- include 属性  说明: 只要include包含组件name则缓存下来;     官方解释:允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示
   |- exclude 属性  说明: 只要exclude包含组件name则不缓存下来;   官方解释:组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示

2: 路由配置参数中的 scrollBehavior 滚动行为,主要记录滚动位置的,我们不仅可以利用来记录缓存页面滚动的位置,还可以利用 savedPosition 知道页面到底是前进 还是 后退
	const RouterConfig = {
    
    
		mode: "hash", //hash history
		routes: Routers,
		scrollBehavior: function (to, from, savedPosition) {
    
    
			// console.log(to) // to:要进入的目标路由对象,到哪里去
			// console.log(from) // from:离开的路由对象,哪里来
			// console.log(savedPosition) // savePosition:会记录滚动条的坐标,点击前进/后退的时候记录值{x:?,y:?}
			// 从第二页返回首页时savedPosition为undefined
			if (savedPosition || typeof savedPosition === 'undefined') //后退
			{
    
    
			  //后退滚动到上一次位置
			  if (savedPosition) {
    
     return savedPosition }
			} else {
    
     //前进

			  //前进滚动到顶部
			  return {
    
    x:0,y:0}
			}
		}
	} 

3:vue 生命周期 中的 2个钩子  activated 和 deactivated

	activated      keep-alive 组件激活时调用  下面简单讲解下,建议看vue官方文档细致了解下
	deactivated    keep-alive 组件停用时调用  下面简单讲解下,建议看vue官方文档细致了解下

	啥意思呢?如果不使用 keep-alive,我们经常在 created 中执行页面打开前的动作,比如:ajax获取数据;

		不使用 keep-alive   打开页面 执行 created
		使用   keep-alive   打开页面 执行 created  之后又会执行 activated ,如果此时返回上一页(就是缓存的页面)那么只执行 activated

		再解释下: 就是使用了 keep-alive 打开新页面会执行 created+activated 2个钩子 ,如果返回到缓存的页面,此时缓存页面不执行 created了,如果此时你业务需要返回 alert(1),那么这个 alert(1),只能放在activated中,
		放在created中无效;

Four: I also read several solutions on the Internet, but they all have problems, and they are not the best solution. After studying the source code of Vue, I summed up the perfect solution and wrote it down, so that everyone can develop projects and learn from each other + complain;

Five: The following code is used to demonstrate the steps

The first step: router.js creates a new route

/*
* 
* keepAlive 是否缓存页面,true缓存 false 不缓存
* tabs 主要作用:解决tab之间路由跳转(一般值replace跳转),tab之间跳转应该不缓存页面,每次切换都是最新数据
	tabs 类型是数组,如下图 tab1 和 tab2 和 tab3 其实是3个tab页面不同组件,那么路由replace跳转不需要缓存数据
*
*/
const Routers =[
	{
    
    
	    path: "/index",
	    name: "index",
	    meta: {
    
    
	      title: "首页",
	      keepAlive:true
	    },
	    component: resolve => require(["@/views/test/index"], resolve)
	},
	{
    
    
	    path: "/tab1",
	    name: "tab1",
	    meta: {
    
    
	      title: "我是tab1列表",
	      keepAlive:true,
	      tabs:['tab1','tab2','tab3']
	    },
	    component: resolve => require(["@/views/test/tab1"], resolve)
	},
	{
    
    
	    path: "/tab2",
	    name: "tab2",
	    meta: {
    
    
	      title: "我是tab2列表",
	      keepAlive:true,
	      tabs:['tab1','tab2','tab3']
	    },
	    component: resolve => require(["@/views/test/tab2"], resolve)
	},
	{
    
    
	    path: "/tab3",
	    name: "tab3",
	    meta: {
    
    
	      title: "我是tab3列表",
	      keepAlive:true,
	      tabs:['tab1','tab2','tab3']
	    },
	    component: resolve => require(["@/views/test/tab3"], resolve)
	},
	{
    
    
	    path: "/content",
	    name: "content",
	    meta: {
    
    
	      title: "我是列表详情",
	      keepAlive:true
	    },
	    component: resolve => require(["@/views/test/content"], resolve)
	}
]

Step 2: Open the APP.vue page Note: The cachePageName here must be the component name, not the routing name (name must be added to each component, and the component name must be written the same as the routing name)

html代码:

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

js代码:

	export default {
    
    
		name: "App",
		data() {
    
    
		    return {
    
    

		    }
		},
		computed:{
    
    
		    cachePageName(){
    
    
		        return this.$store.state.cachePageName;
		    }
		},
		created(){
    
    
			//监听页面刷新
            window.addEventListener('beforeunload',function(){
    
    
            	//监听刷新默认缓存当前组件
                that.$store.commit('resetcachePageName',that.$route.name);
            })
		}
	} 

Step 3: You need to use vuex here, if you have not installed it, please install vuex yourself, no explanation here;

const store = new Vuex.Store({
    
    
	state: {
    
    
		cachePageName:'', //缓存组件名称
	},
	mutations: {
    
    
		//重置缓存组件名称
	    resetcachePageName(state, res){
    
    
	        state.cachePageName = res;
	    },
		//添加缓存组件名称
		addcachePageName(state, res){
    
    
		    if(state.cachePageName == ''){
    
    
		        state.cachePageName = res;
		    }else{
    
    
		        let arr = state.cachePageName.split(',');
		        if (res && typeof res === 'string') {
    
    
		            let i = arr.indexOf(res);
		            if (i <= -1) {
    
    
		                state.cachePageName = state.cachePageName+','+res;
		            }
		        }
		    }
		},
		//删除缓存组件名称
		delcachePageName(state, res){
    
    
		    let arr = state.cachePageName.split(',');
		    if (res && typeof res === 'string') {
    
    
		      let i = arr.indexOf(res);
		      if (i > -1) {
    
    
		          arr.splice(i, 1);
		          state.cachePageName = arr.join();
		      }
		    }
		}
	}
})

Step 4: Modify the scrollBehavior scrolling behavior in the route, and dynamically delete and add components that need to be cached during forward and backward

// 路由配置
const RouterConfig = {
    
    
	mode: "hash", //hash history
	routes: Routers,
	scrollBehavior: function (to, from, savedPosition) {
    
    
		// console.log(to) // to:要进入的目标路由对象,到哪里去
		// console.log(from) // from:离开的路由对象,哪里来
		// console.log(savedPosition) // savePosition:会记录滚动条的坐标,点击前进/后退的时候记录值{x:?,y:?}
		// 从第二页返回首页时savedPosition为undefined
		if (savedPosition || typeof savedPosition === 'undefined') //后退
		{
    
    

		  //判断是否是相邻得tab(tab跳转一定要replace跳转),如果是,那么每次打开都是获取最新页面
		  if(typeof from.meta.tabs !== 'undefined' && from.meta.tabs.length > 0)
		  {
    
     //是tabs

		    //清空tabs之间切换缓存,tabs直接跳转是不需要缓存的,因为大家都是同级页面
		    from.meta.tabs.map(function(vo,index){
    
    
		      store.commit('delcachePageName',vo);
		    })

		  }else{
    
     
		  	//不是tabs

		    //后退到缓存页面,那么这里需要删除上一个页面的缓存,因为你要是再次打开,肯定要获取最新的页面数据 A-B-C 如果从C返回B肯定要把C的缓存删除,不然你从B-C,那就显示C的缓存了
		    store.commit('delcachePageName',from.name);
		  }

		  //后退滚动到上一次位置
		  if (savedPosition) {
    
     return savedPosition }

		} else {
    
     //前进

		  //前进把前进的页面加入到要缓存的组件中
		  store.commit('addcachePageName',to.name);

		  //前进滚动到顶部
		  return {
    
    x:0,y:0}

		}
	}
}

Guess you like

Origin blog.csdn.net/weixin_49295874/article/details/121166546