Vue.js(23)之 keepAlive和activated

阅读:

vue中前进刷新、后退缓存用户浏览数据和浏览位置的实践

keep-alive 组件级缓存

keep-alive

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

<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中,不会渲染到DOM树中

它的作用是在内存中缓存组件(不让组件销毁),等到下次渲染是,还会保留在原来的状态。

组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。

使用:

<keep-alive include="mainList">
    <router-view class="child-view"></router-view>
</keep-alive>

keep-alive的属性:

include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
include 和 exclude 属性允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示
max - 数字。最多可以缓存多少组件实例,一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。

组件匹配首先检查组件自身的 name 选项(不是route的name),如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。

keep-alive的钩子函数:

activated 和 deactivate 生命周期钩子:
设置了keepAlive缓存的组件:
activated deactivate 只要页面切换加载组件就会执行一次
第一次进入:beforeRouterEnter -> created -> … ->activated-> … ->deactivated
后续进入时:beforeRouterEnter -> activated -> deactivated

如果每次进入组件,需要更新某些数据,此时需要把这些方法写在 actived 中

当离开组件时,需要终止某些方法,需要在 deactivated 操作,比如:进入页面发起ajax,在ajax的加载没有完成时退出该页面,此时就需要将 loading(我的ajax 和 loading 是分别控制的) 置为 false

小场景

结合 router 缓存部分组件

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

route元信息:

routers: [{
  path: '/',
  name: 'Home',
  meta: {
    keepAlive: false // 不需要缓存
  }
},{
  path: '/page',
  name: 'Page',
  meta: {
    keepAlive: true  // 需要缓存
  }
},]

列表和详情页

需求:列表页面需要缓存,上拉加载更多,点击进入详情页;此时详情页回退到列表页,需要记录上次滚动的距离。

route:

routers = [
  {
    path: '/',
    name: 'home',
    component: Home,
    redirect: { path: '/' },
    children: [{
      path: '/',
      name: 'index',
      component: List, // 列表页
      meta: { 
          isUseCache: false,// 是否需要缓存
          keepAlive: true // 缓存
      } 
    }, {
      path: '/detail1',
      name: 'detail1',
      component: Detail1, // 详情页
      meta: { keepAlive: false } // 不缓存
    }]
  }
]

在列表页的 activated beforeRouteLeave 钩子中:

activated() {
    // isUseCache为false,重新刷新获取数据
    if(!this.$route.meta.isUseCache){            
        this.list = []; // 清空原有数据
        this.onLoad(); // 这是我们获取数据的函数
    }
},

beforeRouteLeave (to, from, next) {    
    // 如果去详情页,就缓存 列表页面数据
    if (to.name == 'Detail') {
        from.meta.isUseCache = true;    
    }        
    next();
},

现在,从详情页面返回列表页面就会存在缓存了。

那么如果在详情页面的订单状态发生改变,那么返回列表页面就需要刷新了。

那么详情页面的路由可以这样:

data() {    
    return {
        isDel: false  // 是否进行了删除订单的操作       
    }
},
beforeRouteLeave (to, from, next) {        
    if (to.name == 'List') {
        // 根据是否删除了订单的状态,进行判断list是否需要使用缓存数据
        to.meta.isUseCache = !this.isDel;               
    }        
    next()
},
methods: {        
    deleteOrder () {       
        // 删除订单的操作 code ...
        this.isDel = true;
        this.$router.go(-1)
    }
}
原文地址:https://www.cnblogs.com/houfee/p/11336777.html