千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:长沙千锋IT培训  >  技术要点  >  千锋长沙前端培训分享之vue组件缓存之keep-alive

千锋长沙前端培训分享之vue组件缓存之keep-alive

来源:千锋教育
发布人:千锋长沙
时间: 2021-12-23 17:24:44

       千锋长沙前端培训分享之vue组件缓存之keep-alive,先来看一个项目中的需求,作为苦逼的前端开发者,我们无时无刻都要面对产品经理提的各种需求, 比如下图这个场景:

v2-490aa6e876aa22ccdad4eb333c269df3_720w


场景:

从首页的点击导航进入列表页,

列表页点击列表进入 该 数据详情页

从详情页返回,希望列表页缓存,不重新渲染数据,这样会提高用户体验。

分析一下

这样需求,如果是小程序的话,默认列表页就会缓存,因为小程序的运行环境是微信客户端,当我们打开一个页面会新建一个webview,

所有列表页和详情页是两个webview,当我们进入详情页,列表页webview,只是会在详情页webview下面,不会销毁。

以下是小程序运行环境:我们可以看到每个页面都有一个webview

但是但是,我们的项目是用vue开发的webapp,多个组件共用一个窗口,当我们切换路由时,切出路由组件会销毁,所有列表页进入详情页列表页会销毁,重新回到列表页,列表页组件会重新加载。

解决方案

睡服提需求的人,改个简单的需求

emm... ,看了看镜子中的自己,估计这辈子没办法从脸上得到任何的便利了,老老实实换个方案吧。

keep-alive

keep-alive是Vue提供的一个抽象组件,主要用于保留组件状态或避免重新渲染。

<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁他们。

和<transition> 相似, <keep-alive> 是一个抽象组件,它自身不会渲染一个DOM元素,也不会出现在父组件链中。

但是 keep-alive 会把其包裹的所有组件都缓存起来。

em...怎么办呢,我们只是需要让列表页缓存啊.

分析一下

我们可以把需求拆分为2步

(1) 把需要缓存和不需要缓存的组件区分开,在组件的路由配置的元信息,meta中定义哪些需要缓存哪些不需要缓存

具体代码如下

1,定义两个出口 router-view

<keep-alive>

<!-- 需要缓存的视图组件 -->

<router-view v-if="$route.meta.keepAlive">

</router-view>

</keep-alive>

<!-- 不需要缓存的视图组件 -->

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

</router-view>

2,在router配置中定义哪些需要缓存哪些不需要缓存

new Router({

routes: [

{

path: '/',

name: 'index',

component: () => import('./views/keep-alive/index.vue')

},

{

path: '/list',

name: 'list',

component: () => import('./views/keep-alive/list.vue'),

meta: {

keepAlive: true //需要被缓存

}

},

{

path: '/detail',

name: 'detail',

component: () => import('./views/keep-alive/detail.vue')

}

]

})

(2),开始按需缓存组件

我们从官方文档提供的 api 入手,

keep-alive组件如果设置了 include ,就只有和 include 匹配的组件会被缓存,

所以思路就是,动态修改 include 数组来实现按需缓存。

<template>

<keep-alive :include="include">

<!-- 需要缓存的视图组件 -->

<router-view v-if="$route.meta.keepAlive">

</router-view>

</keep-alive>

<!-- 不需要缓存的视图组件 -->

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

</router-view>

</template>

<script>

export default {

name: "app",

data: () => ({

include: []

}),

watch: {

$route(to, from) {

//如果 要 to(进入) 的页面是需要 keepAlive 缓存的,把 name push 进 include数组

if (to.meta.keepAlive) {

!this.include.includes(to.name) && this.include.push(to.name);

}

}

}

};

</script>

此时我们发现,从详情页返回列表页,列表页真的不再刷新了

em...新的问题又出现了,由于 列表页被缓存了,这个时候我从首页,再点击进入某个列表,也不刷新了,完了,点击首页导航应该进入不同的列表页的. 也就是说,从首页进入列表组件不应该被缓存的。

解决一下,我们在定义路由是,在元信息中再加一个字段,这里是deepth字段,代表进入路由的层级,比如首页路由deepth是0.5,列表页是1,详情页是2

new Router({

routes: [

{

path: '/',

name: 'index',

component: () => import('./views/keep-alive/index.vue'),

meta: {

deepth: 0.5 // 定义路由的层级

}

},

{

path: '/list',

name: 'list',

component: () => import('./views/keep-alive/list.vue'),

meta: {

deepth: 1

keepAlive: true //需要被缓存

}

},

{

path: '/detail',

name: 'detail',

component: () => import('./views/keep-alive/detail.vue'),

meta: {

deepth: 2

}

}

]

})

然后在 app.vue中增加监听器,监听 我们进入路由的 方向

具体代码如下

<template>

<keep-alive :include="include">

<!-- 需要缓存的视图组件 -->

<router-view v-if="$route.meta.keepAlive">

</router-view>

</keep-alive>

<!-- 不需要缓存的视图组件 -->

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

</router-view>

</template>

<script>

export default {

name: "app",

data: () => ({

include: []

}),

watch: {

$route(to, from) {

//如果 要 to(进入) 的页面是需要 keepAlive 缓存的,把 name push 进 include数组

if (to.meta.keepAlive) {

!this.include.includes(to.name) && this.include.push(to.name);

}

//如果 要 form(离开) 的页面是 keepAlive缓存的,

//再根据 deepth 来判断是前进还是后退

//如果是后退

if (from.meta.keepAlive && to.meta.deepth < from.meta.deepth) {

var index = this.include.indexOf(from.name);

index !== -1 && this.include.splice(index, 1);

}

}

}

};

</script>

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

最新文章NEW

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>