vue中keep-alive组件失效,父子组件嵌套,子组件失效

需求是:后台管理系统各个子组件都要能缓存,tab切换不重新刷新,如下

首先路由配置:

import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from '../views/Index.vue'
import Login from '../views/Login.vue'

// 解决重复点击导航路由报错
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err);
}

Vue.use(VueRouter)

export const routes = [
  {
    path: '/',
    name: 'index',
    component: Index,
    redirect: '/home',
    children: [
      {
        path: '/home',
        name: 'home',
        meta:{title:"首页",permission: "home",icon:'el-icon-s-home',father:'home'},
        component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')
      },
    ]
  },
  {
    path: '/infoManage',
    name: 'infoManage',
    meta: {
      title:"信息管理",
      permission: "infoManage",
      icon:"glyphicon-th-list",
      isMenu:true
    },
    component: Index,
    redirect: '/infoManage/company',
    children: [{
      path: '/infoManage/company',
      name: 'company',
      meta: {
        title:"公司管理",
        permission: "company",
        father:'infoManage'
      },
      component: () => import( /* webpackChunkName: "infoManage" */ '../views/infoManage/company.vue')
    }, {
      path: '/infoManage/site',
      name: 'site',
      meta: {
        title:"直营网点",
        permission: "site",
        father:'infoManage'
      },
      component: () => import( /* webpackChunkName: "infoManage" */ '../views/infoManage/site.vue')
    } ]
  },
  {
    path: '/systemManage',
    name: 'systemManage',
    meta: {
      title:"系统管理",
      permission: "systemManage",
      icon:"glyphicon-cog",
      isMenu:true
    },
    component: Index,
    redirect: '/systemManage/user',
    children: [{
      path: '/systemManage/user',
      name: 'user',
      meta: {
        title:"用户管理",
        permission: "user",
        father:'systemManage'
      },
      component: () => import( /* webpackChunkName: "systemManage" */ '../views/systemManage/user.vue')
    }, {
      path: '/systemManage/role',
      name: 'role',
      meta: {
        title:"角色管理",
        permission: "role",
        father:'systemManage'
      },
      component: () => import( /* webpackChunkName: "systemManage" */ '../views/systemManage/role.vue')
    }, {
      path: '/systemManage/authorization',
      name: 'authorization',
      meta: {
        title:"权限管理",
        permission: "authorization",
        father:'systemManage'
      },
      component: () => import( /* webpackChunkName: "systemManage" */ '../views/systemManage/authorization.vue')
    },]
  },
  {
    path: '/login',
    name: 'login',
    meta:{title:"登录",permission: "login"},
    component: Login
  },
  {
    path: '*',
    redirect: '/'
  },
]

const router = new VueRouter({
  routes
})

export default router

注意每个组件的name选项要和路由配置中的name保持一致.同时"/"和其他路由"/infoManage"保持同级

其次是keep-alive:



store中的tabRoutes:

state:
    tabRoutes:[
      {name:"home",meta:{title:'首页',active:true,father:'home'},path:'/home'},
      // {name:"company",meta:{title:'公司管理'},path:'/infoManage/company'},
      // {name:"site",meta:{title:'直营网点'},path:'/infoManage/site'},
    ],//激活的keep-alive的tab组件


mutations:
    //增加/删除/激活keep-alive组件(data参数是this.$route对象)
    changeTabRoutes(state,data){
      if(data.type===1){
        // 增加或重定向
        const index=state.tabRoutes.findIndex(v=>{
          return v.path===data.path
        })
        // console.log(data,index)
        if(index===-1){//新增
          delete data.type
          state.tabRoutes.push(data);
        }
        state.tabRoutes.forEach(v=>{
          v.path===data.path?v.meta.active=true:v.meta.active=false
        })
        state.tabRoutes=Object.assign([],state.tabRoutes)
      }else if(data.type===2){
        // 删除
        const index=state.tabRoutes.findIndex((item)=>{
          return item.path===data.path
        })
        if(state.tabRoutes[index].meta.active){
          router.push(state.tabRoutes[index-1].path)
          state.tabRoutes[index-1].meta.active=true
        }
        state.tabRoutes.splice(index,1);
      }else if(data.type===3){
        // 直接点击tab切换激活的路由
        state.tabRoutes.forEach(v=>{
          v.path===data.path?v.meta.active=true:v.meta.active=false
        })
        state.tabRoutes=Object.assign([],state.tabRoutes)
        // console.log(state.tabRoutes)
      }else if(data.type===4){
        // 全部删除
        state.tabRoutes=[{name:"home",meta:{title:'首页',active:true,father:'home'},path:'/home'},]
      }else if(data.type===5){
        // 删除其他
        let index=null,items=null
        state.tabRoutes.forEach(v=>{
          if(v.path==='/home'&&v.meta.active){
            state.tabRoutes=[state.tabRoutes[0]]
          }else{
            index=state.tabRoutes.findIndex((item)=>{
              items=item
              return item.meta.active
            })
          }
        })
        // console.log(index)
        if(index){
          state.tabRoutes=[{name:"home",meta:{title:'首页',active:false,father:'home'},path:'/home'},]
          state.tabRoutes.push(items)
        }
        // index?state.tabRoutes=Object.assign([],[{name:'首页',path:'/home',active:false}],[state.tabRoutes[index]]):""
        // console.log(state.tabRoutes)
      }
    },

然后是组件:

vue中keep-alive组件失效,父子组件嵌套,子组件失效_第1张图片

结果:

vue中keep-alive组件失效,父子组件嵌套,子组件失效_第2张图片

注意 要求被切换到的组件都有自己的名字,不论是通过组件的 name 选项还是局部/全局注册。

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

参考源码:https://gitee.com/zengjianyang123/backTemplate.git

参考:https://cn.vuejs.org/v2/api/#keep-alive

你可能感兴趣的:(vue)