vue-router使用keep-alive

对于list页面到详情页面,需要保持缓存
1.逻辑:
1.进入list页面
1)如果是从detail页面返回的,无处理(list->detail (保持缓存)-->list(保持缓存))
2)如果是从其他页面返回的,需要清除缓存
存在情况,list->detail->otherPage->list 因为先跳转到了detail有了缓存,这种需要清空

2.在list页面,操作,然后跳转其他页面
1)如果是跳转到detail页面。无处理
2)如果是跳转到其他页面,清空缓存.

[
    {
      path:'/list',
      meta:{keepAlive:true​​​​​​​}
    },
    {
      path:'/detail',
      meta:{depend:'/list'​​​​​​​}
    }
]

meta.keepAlive的值,标识是否需要缓存
depend后面跟的list的全路径,作为和list关联的一种设置。

2.使用router-view的地方



export default {
  computed: {
    key(){
       let {fullPath,meta={}} = this.$route ;
       let {keepAliveKey=fullPath} = meta ;
       return keepAliveKey ;
    }
  }
}

计算属性key为了进入list页面清空缓存使用

3.路由钩子
 

import Vue from 'vue' ;
import {getUuid} from "@/utils/data";
//toList和toDetail就是判断是否是详情到明细或明细到详情
const isToList = (to,from)=>{
  let {meta:toMeta={}} = to ;
  let {meta:fromMeta={}} = from ;
  return toMeta.keepAlive && fromMeta.depend === to.fullPath ;
}

const isToDetail = (to,from)=>{
  let {meta:toMeta={}} = to ;
  let {meta:fromMeta={}} = from ;
  return fromMeta.keepAlive && toMeta.depend === from.fullPath ;
}

Vue.mixin({
  beforeRouteEnter(to, from, next) {
    //进入一个路由组件时,判断
    //如果目标是keep-alive,判断跳转到目标页是否需要keepAlive(from是明细,to是list),不需要的话重新渲染
    let isNotToList = !isToList(to,from) ;
    //如果不是明细返回list
    if(isNotToList){
      let {fullPath} = to ;
      let {keepAliveKey} = to.meta ;
      //重置key,这个就是router-view上面的key,进入组件时重置缓存
      if(fullPath === keepAliveKey){
        //重置key
        keepAliveKey = keepAliveKey + getUuid() ;
      }else{
        keepAliveKey = fullPath ;
      }
      to.meta.keepAliveKey = keepAliveKey ;
    }
    next() ;
  },
  beforeRouteLeave(to, from, next) {
    //离开一个组件时
    //如果是明细到list
    if(isToList(to,from)){
      //list页面作为重新查询数据标识用
      to.meta.loadPage = true ;
    }

    const removeKeepAlive = ($vnode)=>{
      if ($vnode) {
        if($vnode?.parent?.componentInstance?.$options?.name === 'keep-alive'){
          if ($vnode.parent && $vnode.parent.componentInstance && $vnode.parent.componentInstance.cache) {
            if ($vnode.componentOptions) {
              let key = $vnode.key == null
                ? $vnode.componentOptions.Ctor.cid + ($vnode.componentOptions.tag ? `::${$vnode.componentOptions.tag}` : '')
                : $vnode.key;
              let cache = $vnode.parent.componentInstance.cache;
              let keys = $vnode.parent.componentInstance.keys;
              if (cache[key]) {
                if (keys.length) {
                  let index = keys.indexOf(key);
                  if (index > -1) {
                    keys.splice(index, 1);
                  }
                }
                delete cache[key];
              }
            }
          }
        }
        removeKeepAlive($vnode.parent) ;
      }
    }
    //如果自己是keep-alive,判断跳转到的页面是否需要keepAlive(from是list,to是明细),如果不需要,destory
    let isNotToDetail = !isToDetail(to,from) ;
    //如果不是list到detail,remove掉 keep-alive
    if (isNotToDetail) {
      removeKeepAlive(this.$vnode) ;
    }
    next();
  },
});


 

你可能感兴趣的:(vue,vue.js,前端,javascript)