Vue中keep-alive失效的一种情况

7,389 阅读2分钟

用keep-alive标签包裹router-view失效的一种情况

问题:App.vue中用了router-view,在组件中又使用了router-view,嵌套的router-view使用keep-alive包裹会失效,App.vue亦无效。两个一起包都没用。

这里有提到我这种情况,但是我这边不行。www.lovean.com/view-10-337…

App.Vue

<template>
  <div id="app">
      <keep-alive> 
    <router-view />
      </keep-alive>
  </div>
</template>

Router

   {
        path: 'videoStorage',
        component: () => import('@/views/mediaResource/videoStorage'),
        meta: {
          title: '视频媒体库', type: 'NAVMENU'
        },
        children: [
          {
            path: '',
            name: 'VideoStorage',
            component: () => import('@/views/mediaResource/videoStorage/default')
          },
          {
            path: 'videoDetail',
            name: 'VideoDetail',
            component: () => import('@/views/mediaResource/videoDetail'),
            meta: {
              title: '资源详情', activeMenu: '/mediaResource/videoStorage'
            }
          },

videoStorage/index.vue

<template>
    <router-view/>
</template>
//就这么多

主要页面代码都在videoStorage/default/index.vue里,在router-view上加keep-alive时,会发现页面的mounted钩子依旧运行得很畅快,似乎在藐视keep-alive

解答:路由指向videoStorage/default/index.vue,跳过上面那个憨憨组件,这样就能去掉组件里的router-view,组件直接使用

组件要记得加name

改正后

App.vue

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

Router

 {
    path: '/mediaResource',
    component: Layout,
    meta: { title: '媒介管理', icon: 'iconxiangzi', group: 'BUSINESS', type: 'CATALOG' },
    children: [
      {
        path: 'resourceStorage',
        component: () => import('@/views/mediaResource/resourceStorage/default'),
        meta: {
          title: '图文媒体库', type: 'NAVMENU'
        },
  	 },
  	  {
        path: 'resourceStorage/mediaDetail',
        name: 'MediaDetail',
        component: () => import('@/views/mediaResource/mediaDetail'),
        meta: {
          title: '资源详情', activeMenu: '/mediaResource/resourceStorage'type: 'INNERMENU'
        }
      },

需要将children里的组件抽出来,继续放在里面的话在页面跳转的时候是跳转不过去的,而是类似再访问了一次原页面,虽然url和左上角的导航有改动~

还要加type,不然会识别成入口标签,这个是二级的嘛~

实现页面缓存

使用条件筛选后选中列表中的一条进入详情页面,返回时条件还在着,页面不刷新,其实不加应该也没事~

 beforeRouteEnter(to, from, next) {
    if (from && from.name === 'MediaDetail') {
      next(vm => {
        vm.load = false
      })
    } else {
      next(vm => {
        vm.load = true
      })
    }
  },
  activated() {
    if (this.load) {
      this.getChargeList()
      this.getFiledList()
      this.getFuncList()
      this.getResourceList()
      const userMessage = JSON.parse(sessionStorage.getItem('user_message'))
      this.adminId = userMessage.id
    }
    bus.$on('refresh', () => {
      this.getResourceList()
    })
  },

activated是配合keep-alive使用的,只有在keep-alive中他才会每次进入都触发,create、mounted啥的只触发一次,load检测他是否是从详情页面返回的,是的话不刷新~

更方便的方法

网上流传的meta标签中加keep-alive属性

    {
      path:'/commoditySort/list',
      name:'commoditySortList',
      meta:{
        isShowHeader:true,
        isShowLeftSider:true,
        keepAlive:true,
        breadcrumb: [
          {
            name:'message.index',
            path:'/index'
          },
          {
            name:'message.manager',
            path:'/manager/list'
          }
        ]
      },
      component: () => import('@/project/views/commoditySort/list')
    },

layout.vue

        <el-main :style="{marginLeft:layoutMarginLeft+'px',marginTop:LayoutHeaderHeight+'px',padding:0}">
          <keep-alive>
            <router-view
              v-if="route.meta.keepAlive"
              :style="{zIndex: 0,width: viewWidth + 'px', height: viewHeight + 'px', backgroundColor: 'rgba(255, 255, 255, 1)'}"
            ></router-view>
          </keep-alive>
          <router-view
            v-if="!route.meta.keepAlive"
            :style="{zIndex: 0,width: viewWidth + 'px', height: viewHeight + 'px', backgroundColor: 'rgba(255, 255, 255, 1)'}"
          ></router-view>
        </el-main>

App.vue

<template>
  <div id="app">
    <Layout></Layout>
  </div>
</template>