keep-alive缓存vue页面

1,151 阅读2分钟

需求

最近需求需要tab栏中的界面重新点击的时候不进行刷新,检索框内填写的内容和列表的数据不改变

image.png

think

这是要缓存啊,当时脑子里想了解决办法来实现这个功能
1.笨方法,切换其他页面的时候,将当前的检索数据进行保存,存到localStorage,或者调接口在库里存储一下,但是这还需要后端去处理,自己也需要将当前的路由和检索数据组合数据,些许麻烦,抛弃
2.就是keep-alive 定义和笼统的就不说了
两个属性

  • include: 只有匹配的组件会被缓存。
  • exclude: 匹配到的组件都不会被缓存。 独有的两个周期
    1.activated:页面第一次进入的时候,钩子触发的顺序是created->mounted->activated 当再次前进或者后退的时候只触发activated
    2.deactivated :页面退出的时候会触发deactivated.

开整

有include这个属性,直接把router-view放到keep-alive,cachedViews为所要缓存页面,

    <keep-alive :include="cachedViews">
        <router-view :key="key" />
      </keep-alive>

因为页面需要权限控制,所以数据的获取全部由后端进行返回,里面包含路由的一些参数

image.png

cachedViews既然是全局的缓存数据,肯定要放到vuex中进行存储了,在页面进行跳转的时候将当前的页面的name加入到cachedViews中,同时也需要建一个数组来保存当前this.$route对象,里面有跳转的路由

//在跳转路由的时候view就是当前的this.$route
  addVisited: (state, view) => {
  //如果当前数组里面有当前页面就直接return
    if (state.visiteList.some(v => v.path === view.path))
    return
    state.visiteList.push(
      Object.assign({}, view, {
        title: view.meta.title || 'no-name'
      })
    )
  },
  addCached: (state, view) => {
    console.log(view);
      //如果当前数组里面有当前页面就直接return
    if (state.cachedViews.includes(view.name)) 
    return
    if (!view.meta.noCache) {
      state.cachedViews.push(view.name)
    }
  },

image.png

需要注意的一点是 路由的name对应的是页面中的name,切不可写错,要不就无法匹配到了

image.png

验证

在被缓存的页面中加入activated方法,下次进入的时候就只会调用activated

image.png image.png

问题延伸

现在keep-alive只能缓存到二级菜单,不能更深缓存。

解决办法

有三级菜单的需要在创建一个空壳文件用来放router-view,由此就可以缓存三级的菜单了

<template>
 <router-view />
</template>
export default {
  name: "二级菜单名",
}

搞定

搞定需求了,加班餐上一下呗,老板!