Skip to content

<keep-alive>组件缓存问题 #811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gongph opened this issue Oct 21, 2016 · 56 comments
Closed

<keep-alive>组件缓存问题 #811

gongph opened this issue Oct 21, 2016 · 56 comments

Comments

@gongph
Copy link

gongph commented Oct 21, 2016

如下代码:

<keep-alive>
    <router-view></router-view>
</keep-alive>

通过路由匹配到的组件都将被 cache 了, 如果其中的组件我不想缓存该怎么做呢?

@fnlctrl
Copy link
Member

fnlctrl commented Oct 21, 2016

暂时没有直接支持。不过现在你可以在meta里定义是否keepAlive来workaround。

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

未来会直接支持,https://github.com/vuejs/vue/projects/3#card-487045

@fnlctrl fnlctrl closed this as completed Oct 21, 2016
@gongph
Copy link
Author

gongph commented Oct 21, 2016

这样做的话,相当于说,要么组件都不缓存,要么都被缓存,是这样吗?

@fnlctrl
Copy link
Member

fnlctrl commented Oct 21, 2016

不是。这样做是只有你设置了meta: {keepAlive: true}的会被缓存,其他不会缓存。

@gongph
Copy link
Author

gongph commented Oct 21, 2016

多些指点。请收下我的膝盖!

@rousos87
Copy link

rousos87 commented Nov 1, 2016

@gongph

For example in your routes config

const router = new VueRouter({
      routes: [{
              path: '/',
              component: Home,
              meta: {
                  keepAlive: true
              },
              children: [{
                  path: '/Profile',
                  component: Profile,
                  meta: {
                      keepAlive: false
                  }
              }
]
})

and then in your file that exists

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

The first component will be cached but the second not.

Hope it helps.

@gongph
Copy link
Author

gongph commented Nov 2, 2016

thank you very much @rousos87

@JounQin
Copy link
Contributor

JounQin commented Nov 7, 2016

@fnlctrl 实测在进入 keepAlive: false 的组件后再重新进入 keepAlive: true 的组件时原来的状态丢失了,如果切换路由一直是 keepAlive: true 则没问题。

@fnlctrl
Copy link
Member

fnlctrl commented Nov 7, 2016

@JounQin 请给重现

@JounQin
Copy link
Contributor

JounQin commented Nov 7, 2016

@JounQin
Copy link
Contributor

JounQin commented Nov 7, 2016

@fnlctrl 抱歉,判断条件加错地方了,都是 <router-view/> 组件上判断确实是可以了,但是像这样使用为什么会出问题呢?

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

https://jsfiddle.net/JounQin/gL8z5zq1/2/

@fnlctrl
Copy link
Member

fnlctrl commented Nov 7, 2016

@JounQin
这个方法的原理是,<keep-alive>的子节点在被销毁之前会被缓存下来,所以要给它的子节点加v-if。<keep-alive>本身不能被销毁,否则就没作用了,所以不能给它加v-if。

@ibeizhu
Copy link

ibeizhu commented Nov 30, 2016

请问在vue router 1.X能否支持如上keep alive的功能? @fnlctrl

@fnlctrl
Copy link
Member

fnlctrl commented Nov 30, 2016 via email

@KangdaOOLin
Copy link

@fnlctrl 我有一个问题

<transition name="fade" mode="out-in">
  <keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
  </keep-alive>
  <router-view v-if="!$route.meta.keepAlive"></router-view>
</transition>

上面的代码会报错: <transition> can only be used on a single element. Use for lists。

虽然我知道是什么原因报错,但我想问的是,怎么去动态使用keep-alive,并结合transitionrouter-view

我尝试了不同的组合:

<transition name="fade" mode="out-in">
  <keep-alive v-if="$route.meta.keepAlive">
    <router-view v-if="$route.meta.keepAlive"></router-view>
  </keep-alive>
  <router-view v-if="!$route.meta.keepAlive"></router-view>
</transition>

上面的代码会导致keep-alive无法起作用,上面也讲到了。

<transition name="fade" mode="out-in">
  <template v-if="$route.meta.keepAlive">
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
  </template>
  <router-view v-if="!$route.meta.keepAlive"></router-view>
</transition>

上面的代码同样会导致keep-alive无法起作用~~

<transition name="fade" mode="out-in">
  <div>
    <keep-alive v-if="$route.meta.keepAlive">
      <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
    <router-view v-if="!$route.meta.keepAlive"></router-view>
  </div>
</transition>

上面的代码,keep-alive能起作用,但无法实现过渡的效果,因为不满足过渡动画的条件~~

@JounQin
Copy link
Contributor

JounQin commented Dec 18, 2016

@wenkanglin

<div id="app">
  <transition :name="transition">
    <keep-alive>
      <router-view v-if="keepAlive"></router-view>
    </keep-alive>
  </transition>
  <transition :name="transition">
    <router-view v-if="!keepAlive"></router-view>
  </transition>
</div>

@KangdaOOLin
Copy link

@JounQin 我试了一下,其他的没问题,但transition mode="out-in"过渡模式的功能无法实现

@huangyingwen
Copy link

@fnlctrl 实测在进入 keepAlive: true 的组件后再进入 keepAlive: false 的组件时, keepAlive: true 的组件会重新渲染,组件生命周期会再执行一遍
https://jsfiddle.net/n6Lxutz4/1/
看控制台

@Hanruis
Copy link

Hanruis commented Jun 20, 2017

在用 router 的时候,建议 keep-alive 的 include 属性来实现组件的缓存。

@tian-tian
Copy link

对于这种写法,如果有多层路由嵌套,会有些问题吧,

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

可以用keep-aliveinclude或者exclude属性来实现

<keep-alive :include="/Keep$/">
    <router-view></router-view>
</keep-alive>

@doublemin
Copy link

你好,确实发现多层路由嵌套会有问题,设置keep-alive为true的组件有的能缓存成功有的不能,但是使用include却一个也没缓存成功,include的使用有什么注意事项没有,在什么情况下才能正常使用? @tian-tian

@tian-tian
Copy link

参考vue的文档,里面说的很清楚。 @doublemin

@yoomin1106
Copy link

@wenkanglin 请问keey-alive和out-in的问题解决了吗?

@zhouweihua
Copy link

mark
transition keep-alive router-view 混用确实有问题
目前就全部先缓存了 在actived中更新数据

@realfly08
Copy link

最近在用vue+vue-router做一个app, 某一模块我用keep-alive实现全部缓存,页面返回的时候再将当前页面销毁,主要代码如下:

然后在man.js中注册了全局方法

Vue.mixin({
beforeRouteLeave(to,from,next){
//注册全局混合方法,由于所有页面都进行了缓存,页面返回时将当前页面销毁
const toRoute = to.path
const fromRoute = from.path
const h = sess.get(toRoute); //sessionStorage 里面会将所有打开过的页面保存下来,histroy表示未关闭
if(h&&h.history){
this.$destroy()
}
next();
}
})

这样功能可以实现正向打开页面全部被缓存,当前页面在返回的时候被销毁

但我发现,这个操作只有第一次有效,每二次从头进去的时候发现,页面根本不会缓存

wx20171026-214156 2x

第一次,打开四个页面,全部缓存

wx20171026-214224 2x

然后回到第一个页面

wx20171026-214300 2x

再打开刚才的四个页面,缓存出了问题

@yuxianwen
Copy link

yuxianwen commented Nov 18, 2017

@JounQin 针对上面的 虽然 是可以的 ,但是只要进入一个页面 控制塔就会有一个错误报警信息

改良下 就完美了

`

  <transition
    :enter-active-class="enterActiveClass"
    :leave-active-class="leaveActiveClass"
    v-if="$route.meta.keepAlive"
  >
    <keep-alive>
      <router-view class="view"></router-view>
    </keep-alive>
  </transition>
  <transition
    :enter-active-class="enterActiveClass"
    :leave-active-class="leaveActiveClass"
    v-if="!$route.meta.keepAlive"
  >
    <router-view class="view"></router-view>
  </transition>
</div>`

@JoxC
Copy link

JoxC commented Nov 26, 2017

应该尽可能使用include/exclude
下面这种写法在二级以上路由中可能造成在路由切换路由时生成不必要的子组件

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

@nokelong
Copy link

@realfly08 你的问题解决了吗,出现同样的多级路由缓存问题

@nokelong
Copy link

发现这个怪异的问题,通过注册beforeEach强制刷新页面暂时解决

@realfly08
Copy link

@carzy-lin
Copy link

对于这种写法,如果有多层路由嵌套,会有些问题吧,

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

可以用keep-aliveinclude或者exclude属性来实现

<keep-alive :include="/Keep$/">
    <router-view></router-view>
</keep-alive>
```  多层嵌套路由使用过渡时候,使key绑在router-view上,这样会作用到每个进入的路由,有什么可以解决的吗

@BoLin6
Copy link

BoLin6 commented May 15, 2019

<keep-alive>
    <router-view :key="$route.path"></router-view>
</keep-alive>

我以这种方式根据不同的path,去刷新页面, 但是出现一个问题, 就是当我更改缓存页面中的dom结构时, 这个时候页面进行vue热更新, 导致整体页面丢失了, 将 :key="$route.path"去掉就没事了, 为什么会出现这种情况呢

@qtttttttttting
Copy link

请问现在可以支持动态移除缓存吗?

@ileadall42
Copy link

这个真的是容易犯的错误。

@liaoxuewei
Copy link

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

采用这种做法,但是有时可以,有时不行,请问哪里可能导致这个问题?检查N次都找不到原因。

其他地方提问:
https://www.jianshu.com/p/0b0222954483
我利用router.meta的属性控制每个功能页面是否刷新,但是碰到这样的情况:
A/B/C,其中C刷新,其他两个不刷新。
首次进入A/B/C,肯定需要刷新,这个没有问题,问题是:

  1. A和B之间切换,每次都刷新,但是我的需求是不想刷新(第二次进入时)
  2. A和C之间切换,每次进入C都刷新,第二次进入A不刷新,情况正常。
    问题来了,这个1就不是我希望的结果,这样希望第二次不刷新的需求相当于没有任何的意义了。

@liaoxuewei
Copy link

liaoxuewei commented Jul 22, 2019

经过多次测试,发现居然是Route的层级问题,我的路由定义是:

{
  id: 1,
  ...
  path: "xxx",
  children:
  [
    {
      id: 2,
      ...
      path: "xxx",
      children:
      [
        {
          id: 3,
          ...
          path: "xxx",
          meta: {
            keepAlive: true // 需要被缓存
          },
          children:
          [
          ]
        }
      ]
    }
  ]
}

id=3的这个无法缓存,id=2可以缓存(即树的第二级可以缓存,第三级及以后不能缓存)。
这个是不是BUG啊?按理不应该局限这个吧?

@haohailong1990
Copy link

使用 keep-alive :include匹配name,列表页(比如之前浏览了3页数据),返回没有被缓存3页

@gongph
Copy link
Author

gongph commented Aug 22, 2019

使用 keep-alive :include匹配name,列表页(比如之前浏览了3页数据),返回没有被缓存3页

keeep-alive 缓存的是路由组件,不是功能型(table)组件。这个你需要单独处理的

@haohailong1990
Copy link

使用 keep-alive :include匹配name,列表页(比如之前浏览了3页数据),返回没有被缓存3页

keeep-alive 缓存的是路由组件,不是功能型(table)组件。这个你需要单独处理的

<transition name="router-fade" mode="out-in">
    <keep-alive>
        <router-view v-if="$route.meta.keepAlive"></router-view>
    </keep-alive>
</transition>
<transition name="router-fade" mode="out-in">
    <router-view v-if="!$route.meta.keepAlive"></router-view>
</transition> 这样是可以的,没有用include,但是这样的话,从keepAlive为true的组件切到keepAlive为false,会莫名执行切换前的 created 和 mounted方法

@wakaka378
Copy link

我现在有这样一个需求:
假设我现在在index页面,从index页面进入到一个填写信息的页面information,当我填写完信息后提交后,有一个confirm确认页面。这时候我发现我信息有一个填错了,返回修改information数据,此时information数据应该都还在。keep-alive可以很好的解决这个问题,那填写完毕后也提交了,再从index进入到information页面,此时information页面的数据都还在,怎么解决这个问题?

简单的来说:
A到B B组件不缓存
C到B B组件要缓存

@gongph
Copy link
Author

gongph commented Aug 30, 2019

我现在有这样一个需求:
假设我现在在index页面,从index页面进入到一个填写信息的页面information,当我填写完信息后提交后,有一个confirm确认页面。这时候我发现我信息有一个填错了,返回修改information数据,此时information数据应该都还在。keep-alive可以很好的解决这个问题,那填写完毕后也提交了,再从index进入到information页面,此时information页面的数据都还在,怎么解决这个问题?

简单的来说:
A到B B组件不缓存
C到B B组件要缓存

info -> confirm 之前可以暂存表单数据。提交成功后再 resetForm 。这个跟 keep-alive 没关系吧?

@wakaka378
Copy link

我现在有这样一个需求:
。假设我现在在索引页面,从索引页面进入到一个填写信息的页面信息,当我填写完信息后提交后,有一个确认确认页面这时候我发现我信息有一个填错了,返回修改信息数据,此时信息数据应该都还在.keep活可以很好的解决这个问题,那填写完毕后也提交了,再从索引进入到信息页面,此时信息页面的数据都还在,怎么解决这个问题?
简单的来说:
A到BB组件不缓存
C到BB组件要缓存

info - >确认之前可以暂存表单数据。提交成功后再resetForm。这个跟keep-alive没关系吧?

只是假设有这个需求 要用到keep-alive
我实际项目中也会用keep-alive 因为有些页面请求太多 吧组件缓存起来比较好

目前找到的解决方案就是通过添加路由元信息 通过路由元信息判断组件是否缓存 再搭配beforeRouteLeave

@pipione
Copy link

pipione commented Oct 15, 2019

https://cn.vuejs.org/v2/api/#keep-alive ,
image

我目前使用的是keep-alive 自带的属性来判断是否给某些页面缓存,比如组件名称包含list的就给与缓存
image

@GarenMx
Copy link

GarenMx commented Dec 27, 2019

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

列表页 路由钩子

beforeRouteLeave(to, from, next){
     if(to.path.indexOf('/detail') != -1){
            if(!from.meta.keepAlive){
                from.meta.keepAlive = true
            }
            next()
        }else{
            from.meta.keepAlive = false;
            next();
        }
    },

路由

  {
     path: "/list",
     name: "List",
     component: List,
     meta: {
        keepAlive: true
     },
   },
   {
     path: "/detail",
     name: "Detail",
     component: Detail
   },
预期:列表页进行过滤分页等操作后,点击某个产品进入详情页, 后退时,列表页保留上次操作状 
           态,从其它页面进入到列表页,列表页需要刷新请求拿到最新数据。
实际:列表页->详情页->列表页  第一次操作能实现预期  (列表页状态能保留)
           这个时候我进行下一步操作 从列表页->其他任意页面(非详情页)->列表页  进行分页或者过 
           滤项操作后点击某个产品进入详情页 后退时 列表页保存的状态是第一次操作的状态,而不是第 
           二次操作的状态。
我想了解一下这种现象的原因和解决办法!

@way-zw
Copy link

way-zw commented Dec 30, 2019

https://www.jianshu.com/p/cd1baf5b03b0
@nokelong 试试这个

最近在用vue + vue-router做一个应用,某些模块我用keep-alive实现全部缓存,页面返回的时候再将当前页面销毁,主要代码如下:

然后在man.js中注册了一系列方法

Vue.mixin({
beforeRouteLeave(到,从下一个){
//注册全局混合方法,由于所有页面都进行了缓存,页面返回时将当前页面销毁
常量toRoute = to.path
常量fromRoute = from.path
常量ħ = sess.get(toRoute); // sessionStorage里面可以打开所有打开过的页面保存下来,histroy表示未关闭
if(h && h.history){
this。$ destroy()
}
next();
}
})

这样功能可以实现正向打开页面全部被缓存,当前页面在返回的时候被销毁

但我发现,这个操作只有第一次有效,每二次从头进去的时候发现,页面根本不会缓存

wx20171026-214156 2x

第一次,打开四个页面,全部缓存
wx20171026-214224 2x

然后回到第一个页面

wx20171026-214300 2x

再打开刚才的四个页面,缓存出了问题

我做的时候也是,不知道为啥只缓存第一次,第二次就不缓存了,请问你是怎么解决的

@Maconzhang
Copy link

https://www.jianshu.com/p/cd1baf5b03b0
@nokelong 试试这个

最近在用vue + vue-router做一个应用,某些模块我用keep-alive实现全部缓存,页面返回的时候再将当前页面销毁,主要代码如下:
然后在man.js中注册了一系列方法
Vue.mixin({
beforeRouteLeave(到,从下一个){
//注册全局混合方法,由于所有页面都进行了缓存,页面返回时将当前页面销毁
常量toRoute = to.path
常量fromRoute = from.path
常量ħ = sess.get(toRoute); // sessionStorage里面可以打开所有打开过的页面保存下来,histroy表示未关闭
if(h && h.history){
this。$ destroy()
}
next();
}
})
这样功能可以实现正向打开页面全部被缓存,当前页面在返回的时候被销毁
但我发现,这个操作只有第一次有效,每二次从头进去的时候发现,页面根本不会缓存
wx20171026-214156 2x
第一次,打开四个页面,全部缓存
wx20171026-214224 2x
然后回到第一个页面
wx20171026-214300 2x
再打开刚才的四个页面,缓存出了问题

我做的时候也是,不知道为啥只缓存第一次,第二次就不缓存了,请问你是怎么解决的

兄弟解决了吗? 我也是这样 第一次从列表页A到详情页,再返回列表是缓存了。从其他列表页面进入列表页A 再进详情页 再返回,列表页A的组件就无法缓存了?

@xiaozeng1212
Copy link

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

列表页 路由钩子

beforeRouteLeave(to, from, next){
     if(to.path.indexOf('/detail') != -1){
            if(!from.meta.keepAlive){
                from.meta.keepAlive = true
            }
            next()
        }else{
            from.meta.keepAlive = false;
            next();
        }
    },

路由

  {
     path: "/list",
     name: "List",
     component: List,
     meta: {
        keepAlive: true
     },
   },
   {
     path: "/detail",
     name: "Detail",
     component: Detail
   },
预期:列表页进行过滤分页等操作后,点击某个产品进入详情页, 后退时,列表页保留上次操作状 
           态,从其它页面进入到列表页,列表页需要刷新请求拿到最新数据。
实际:列表页->详情页->列表页  第一次操作能实现预期  (列表页状态能保留)
           这个时候我进行下一步操作 从列表页->其他任意页面(非详情页)->列表页  进行分页或者过 
           滤项操作后点击某个产品进入详情页 后退时 列表页保存的状态是第一次操作的状态,而不是第 
           二次操作的状态。
我想了解一下这种现象的原因和解决办法!
<keep-alive>
   <router-view v-if="$route.meta.KeepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.KeepAlive"></router-view>

列表页路由钩子

beforeRouteLeave(to, from, next){
     if(to.path.indexOf('/detail') != -1){
            if(!from.meta.keepAlive){
                from.meta.keepAlive = true
            }
            next()
        }else{
            from.meta.keepAlive = false;
            next();
        }
    },

路由

  {
     path: "/list",
     name: "List",
     component: List,
     meta: {
        keepAlive: true
     },
   },
   {
     path: "/detail",
     name: "Detail",
     component: Detail
   },
预期:列表页进行过滤分页等操作后,点击某个产品进入详情页, 后退时,列表页保留上次操作状 
           态,从其它页面进入到列表页,列表页需要刷新请求拿到最新数据。
实际:列表页->详情页->列表页  第一次操作能实现预期  (列表页状态能保留)
           这个时候我进行下一步操作 从列表页->其他任意页面(非详情页)->列表页  进行分页或者过 
           滤项操作后点击某个产品进入详情页 后退时 列表页保存的状态是第一次操作的状态,而不是第 
           二次操作的状态。
我想了解一下这种现象的原因和解决办法!
<keep-alive>
   <router-view v-if="$route.meta.KeepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.KeepAlive"></router-view>

列表页 路由钩子

beforeRouteLeave(to, from, next){
     if(to.path.indexOf('/detail') != -1){
            if(!from.meta.keepAlive){
                from.meta.keepAlive = true
            }
            next()
        }else{
            from.meta.keepAlive = false;
            next();
        }
    },

路由

  {
     path: "/list",
     name: "List",
     component: List,
     meta: {
        keepAlive: true
     },
   },
   {
     path: "/detail",
     name: "Detail",
     component: Detail
   },
预期:列表页进行过滤分页等操作后,点击某个产品进入详情页, 后退时,列表页保留上次操作状 
           态,从其它页面进入到列表页,列表页需要刷新请求拿到最新数据。
实际:列表页->详情页->列表页  第一次操作能实现预期  (列表页状态能保留)
           这个时候我进行下一步操作 从列表页->其他任意页面(非详情页)->列表页  进行分页或者过 
           滤项操作后点击某个产品进入详情页 后退时 列表页保存的状态是第一次操作的状态,而不是第 
           二次操作的状态。
我想了解一下这种现象的原因和解决办法!

请问你解决了吗,我也是这个问题

@fangcongcong
Copy link

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

列表页 路由钩子

beforeRouteLeave(to, from, next){
     if(to.path.indexOf('/detail') != -1){
            if(!from.meta.keepAlive){
                from.meta.keepAlive = true
            }
            next()
        }else{
            from.meta.keepAlive = false;
            next();
        }
    },

路由

  {
     path: "/list",
     name: "List",
     component: List,
     meta: {
        keepAlive: true
     },
   },
   {
     path: "/detail",
     name: "Detail",
     component: Detail
   },
预期:列表页进行过滤分页等操作后,点击某个产品进入详情页, 后退时,列表页保留上次操作状 
           态,从其它页面进入到列表页,列表页需要刷新请求拿到最新数据。
实际:列表页->详情页->列表页  第一次操作能实现预期  (列表页状态能保留)
           这个时候我进行下一步操作 从列表页->其他任意页面(非详情页)->列表页  进行分页或者过 
           滤项操作后点击某个产品进入详情页 后退时 列表页保存的状态是第一次操作的状态,而不是第 
           二次操作的状态。
我想了解一下这种现象的原因和解决办法!

解决了吗?

@angentle
Copy link

angentle commented Sep 3, 2020

<keep-alive>
    <router-view :key="$route.path"></router-view>
</keep-alive>

我以这种方式根据不同的path,去刷新页面, 但是出现一个问题, 就是当我更改缓存页面中的dom结构时, 这个时候页面进行vue热更新, 导致整体页面丢失了, 将 :key="$route.path"去掉就没事了, 为什么会出现这种情况呢

我也遇到同样的问题 请问这个解决了么

@BoLin6
Copy link

BoLin6 commented Sep 3, 2020 via email

@hooray
Copy link

hooray commented Nov 18, 2020

用transition标签包裹起来, 就可以了

------------------ 原始邮件 ------------------ 发件人: "vuejs/vue-router" <notifications@github.com>; 发送时间: 2020年9月3日(星期四) 下午2:43 收件人: "vuejs/vue-router"<vue-router@noreply.github.com>; 抄送: "사랑해요"<494013115@qq.com>;"Comment"<comment@noreply.github.com>; 主题: Re: [vuejs/vue-router] <keep-alive>组件缓存问题 (#811) <keep-alive> <router-view :key="$route.path"></router-view> </keep-alive> 我以这种方式根据不同的path,去刷新页面, 但是出现一个问题, 就是当我更改缓存页面中的dom结构时, 这个时候页面进行vue热更新, 导致整体页面丢失了, 将 :key="$route.path"去掉就没事了, 为什么会出现这种情况呢 我也遇到同样的问题 请问这个解决了么 — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

也还是不行

@hooray
Copy link

hooray commented Nov 18, 2020

<keep-alive>
    <router-view :key="$route.path"></router-view>
</keep-alive>

我以这种方式根据不同的path,去刷新页面, 但是出现一个问题, 就是当我更改缓存页面中的dom结构时, 这个时候页面进行vue热更新, 导致整体页面丢失了, 将 :key="$route.path"去掉就没事了, 为什么会出现这种情况呢

我也遇到同样的问题 请问这个解决了么

同样遇到+1
有解决方案么

@zhanglong1009
Copy link

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

列表页 路由钩子

beforeRouteLeave(to, from, next){
     if(to.path.indexOf('/detail') != -1){
            if(!from.meta.keepAlive){
                from.meta.keepAlive = true
            }
            next()
        }else{
            from.meta.keepAlive = false;
            next();
        }
    },

路由

  {
     path: "/list",
     name: "List",
     component: List,
     meta: {
        keepAlive: true
     },
   },
   {
     path: "/detail",
     name: "Detail",
     component: Detail
   },
预期:列表页进行过滤分页等操作后,点击某个产品进入详情页, 后退时,列表页保留上次操作状 
           态,从其它页面进入到列表页,列表页需要刷新请求拿到最新数据。
实际:列表页->详情页->列表页  第一次操作能实现预期  (列表页状态能保留)
           这个时候我进行下一步操作 从列表页->其他任意页面(非详情页)->列表页  进行分页或者过 
           滤项操作后点击某个产品进入详情页 后退时 列表页保存的状态是第一次操作的状态,而不是第 
           二次操作的状态。
我想了解一下这种现象的原因和解决办法!

我也是遇到了这个问题,一直没法解决,导致到现在都没用keepAlive....

@giserman001
Copy link

大家解决了吗?

@zoechen94
Copy link

https://www.jianshu.com/p/cd1baf5b03b0
@nokelong 试试这个

最近在用vue + vue-router做一个应用,某些模块我用keep-alive实现全部缓存,页面返回的时候再将当前页面销毁,主要代码如下:
然后在man.js中注册了一系列方法
Vue.mixin({
beforeRouteLeave(到,从下一个){
//注册全局混合方法,由于所有页面都进行了缓存,页面返回时将当前页面销毁
常量toRoute = to.path
常量fromRoute = from.path
常量ħ = sess.get(toRoute); // sessionStorage里面可以打开所有打开过的页面保存下来,histroy表示未关闭
if(h && h.history){
this。$ destroy()
}
next();
}
})
这样功能可以实现正向打开页面全部被缓存,当前页面在返回的时候被销毁
但我发现,这个操作只有第一次有效,每二次从头进去的时候发现,页面根本不会缓存
wx20171026-214156 2x
第一次,打开四个页面,全部缓存
wx20171026-214224 2x
然后回到第一个页面
wx20171026-214300 2x
再打开刚才的四个页面,缓存出了问题

我做的时候也是,不知道为啥只缓存第一次,第二次就不缓存了,请问你是怎么解决的

兄弟解决了吗? 我也是这样 第一次从列表页A到详情页,再返回列表是缓存了。从其他列表页面进入列表页A 再进详情页 再返回,列表页A的组件就无法缓存了?

老哥解决了吗,我也是,从其他列表页回来列表页A-详情B-列表A,第一次不缓存,第二次开始就缓存了

@gongph
Copy link
Author

gongph commented Aug 23, 2023 via email

1 similar comment
@gongph
Copy link
Author

gongph commented Oct 29, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests