我的业务需求是有订单列表A订单详情页B以及其他页面C

简单来说就是从订单详情页B进入订单列表页A需要将订单列表页缓存下来(因为有筛选条件) 其他页面进入的话不缓存
简单,vue不是有keep-alive吗 判断一下

最开始是这样的

在App.vue中

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

然后在路由页面的order_list设置

meta:{
    keepAlive:false
}

最后呢在orderDetail中写一个路由守卫

beforeRouteLeave(to,from,next){
    if(to.name == 'order_list'){
        to.meta.keepAlive = true
    }
}

SoEazy!!!
但是事情远远没有这么简单

测试发现 第一次进去组件不缓存 第二次才行 什么鬼哦

百度一下吧
https://segmentfault.com/a/1190000020217946
看到了这篇帖子 老哥说的好像很有道理
开整

我的项目是3.0的 并且我创建项目的时候已经选择了vuex
如果没有的话在views同级建一个文件夹store在下面新建一个index.js写vuex的存储
我的vuex是这样的

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    catchList:[]
  },
  mutations: {
    keepAlive(state, component) {
      !state.catchList.includes(component) && state.catchList.push(component)
    },
    noKeepAlive(state) {
      state.catchList = []
    } 
  },
  actions: {
  },
  modules: {
  }
})

如果你是建项目选择了vuex的话无须在main.js引入了
如果没有的话
在main.js中

import store from './store'
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

ok
接下来就来实现我的逻辑了
其实我的逻辑是完全按照那个老哥的方法来的 但是有改变
为了更清晰 我就将完整过程记录下来

在App.vue页面需要这样

<template>
  <div id="app">
  <keep-alive :include="this.state_catchList">
    <router-view></router-view>
</keep-alive>

  </div>
</template>
<script>
import { mapState } from 'vuex';
export default {

  name: 'app',
  mounted(){
    console.log(this.state_catchList)
  },
  computed:{
    ...mapState({
      state_catchList: state => state.catchList
    })
  }
}
</script>

include的含义是包含此name的组件会被缓存(这里注意组件要写name,不是路由的name,是export default下面的那个name)
对应的是exclude
我这里绑定的就是vuex中的catchList了

首先在你的全局路由守卫中加入,记住是全局的,我是写在main.js中

  if(to.name === "order_list"){
    store.commit('keepAlive','order_list')
    next()
  }

这段代码应该不难理解 如果我进入了order_list页面
就将keepAlive跟名称提交到vuex的数组相当于将组件添加到了缓存
但是业务需求是我只有在从订单详情页进入订单列表才缓存 其他页面进入不缓存

因为router本身就带有路由守卫 我就写在这里就行了

import store from '../store/index.js'//引入vuex
  {
    path: '/order_list',
    name: 'order_list',
    component: orderList,
    meta:{
      keepAlive: false
    },
    beforeEnter:(to,from,next)=>{
      if(from.name != 'orderDetail'){
        console.log(from.name)
        store.commit("noKeepAlive")
        next()
      }else{
        next()
      }
    }
  },

这里的逻辑是在离开orderList前判断如果不是来自订单详情页
就将catchList清空了相当于不缓存

ok到这里基本上就ok了
测试一下
好的第一次进入缓存了
但是出现了新的问题
我的这几个页面底下有一个tabbar 就是相当于footer
在我从其他页面进入订单列表页再进入订单详情页中然后再退回到订单详情页时,发现tabbar选中的选项是我从上个页面的选项 比如我是从首页进入的订单列表 从订单详细页面退回的话 tabbar显示的就是首页

这让我很难受
最开始想的是一个笨办法
我给每一个进入order_list 添加一个路由守卫并提交'noKeepAlive'

但是试过了 不生效

试过了销毁重载组件等方法

最后想到了被缓存的组件也是有钩子的
这里注意被缓存的是不走正常的created这一套钩子的
但是他有activated和deactivated这两个钩子
那就在activated中操作一哈

  activated(){
    console.log('我被缓存了 但是我还是想干点啥')
    this.active = 1
  }

这里需要注意的是这个是写在单独的tabbar组件中的
active是tabbar绑定的一个下标 我直接让他写死为订单列表的下标了


Resssssss
28 声望2 粉丝