重读 vue 文档 --- keep-alive
2020/3/23 11:02:05
本文主要是介绍重读 vue 文档 --- keep-alive,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
引言
keep-alive 是 vue 内置的
抽象组件
,可以用于包裹需要缓存的组件。保存组件状态,避免重新渲染,增强性能。
Props
keep-alive 组件接收三个参数,分别为 include
、exclude
、max
- include - 数组、字符串或正则表达式。只有名称匹配的组件会被缓存。
- exclude - 数组、字符串或正则表达式。任何名称匹配的组件都不会被缓存。
- max - 数字。最多可以缓存多少组件实例。
使用
结合动态组件使用
<keep-alive> <component v-bind:is="currentTabComponent"></component> </keep-alive> 复制代码
匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。
结合 vue-router 使用
<keep-alive> <router-view> <!-- 所有路径匹配到的视图组件都会被缓存! --> </router-view> </keep-alive> 复制代码
缓存指定路由对应组件
<keep-alive> <router-view v-if="$route.meta.keepAlive" /> </keep-alive> <router-view v-if="!$route.meta.keepAlive"></router-view> // vue-router routes 配置 export default [ { path: '/', name: 'componentsName', component: componentsName, meta: { keepAlive: true // 需要被缓存 } } ] 复制代码
<keep-alive` 是用在其一个直属的子组件被开关的情形。如果你在其中有 v-for 则不会工作。如果有上述的多个条件性的子元素,<keep-alive> 要求同时只有一个子元素被渲染。
深入源码
export default { name: 'keep-alive', abstract: true, // 抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。 // 具体关于抽象组件不会渲染出DOM,在 src/core/instance/lifecycle.js props: { include: patternTypes, // [String, RegExp, Array] exclude: patternTypes, max: [String, Number] }, created () { this.cache = Object.create(null) // 新建缓存对象 { key: vnode } this.keys = [] // 按序保存组件的 key }, destroyed () { for (const key in this.cache) { pruneCacheEntry(this.cache, key, this.keys) } }, /** * 监听 include、exclude 动态变化 */ mounted () { this.$watch('include', val => { pruneCache(this, name => matches(val, name)) // function filter (name) { return matches(val, name); } }) this.$watch('exclude', val => { pruneCache(this, name => !matches(val, name)) }) }, render () { const slot = this.$slots.default // 获取插槽默认内容 const vnode: VNode = getFirstComponentChild(slot) // 获取第一个子节点 // <keep-alive> 是用在其一个直属的子组件被开关的情形。如果你在其中有 v-for 则不会工作。如果有上述的多个条件性的子元素,<keep-alive> 要求同时只有一个子元素被渲染。 const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions if (componentOptions) { // check pattern const name: ?string = getComponentName(componentOptions) const { include, exclude } = this /** * 未匹配到相应组件,不缓存 */ if ( (include && (!name || !matches(include, name))) || (exclude && name && matches(exclude, name)) ) { return vnode } const { cache, keys } = this // 生成 key const key: ?string = vnode.key == null ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '') : vnode.key if (cache[key]) { // 命中缓存 vnode.componentInstance = cache[key].componentInstance // make current key freshest 刷新 keys 数组 remove(keys, key) keys.push(key) } else { // 未命中 cache[key] = vnode keys.push(key) // prune oldest entry if (this.max && keys.length > parseInt(this.max)) { pruneCacheEntry(cache, keys[0], keys, this._vnode) // 超出了最大缓存数量,则删除第一个节点(最长时间未使用的节点) } } vnode.data.keepAlive = true } return vnode || (slot && slot[0]) } } 复制代码
在 keep-alive 组件创建时,新建 catch 缓存节点,keys 按序
保存key。通过传入的 include、exclude判断是否命中缓存,命中,则从缓存中拿vnode组件实例,调整key的顺序。未命中,则添加缓存。判断是否超出最大缓存数量,超出,则删除最久未被使用的节点,即keys第一个 key 对应的 vnode
生命周期
组件一旦被 缓存,再次渲染就不会执行 created、mounted生命周期。因此 vue 提供了 activated和 deactivated 两个生命周期函数,在缓存组件再次渲染时执行一些操作。
总结
<keep-alive>
组件通过插槽,获取第一个子节点。根据 include、exclude判断是否需要缓存,通过组件的 key,判断是否命中缓存。利用LRU算法,更新缓存以及对应的 keys 数组。根据 max控制缓存的最大组件数量。
参考
这篇关于重读 vue 文档 --- keep-alive的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-04package.json 文件位置在哪?-icode9专业技术文章分享
- 2024-10-01Craco.js学习:从入门到实践指南
- 2024-10-01Create-React-App学习:入门与实践指南
- 2024-10-01CSS-in-JS学习:从入门到实践指南
- 2024-09-30JSX语法学习:从入门到初步掌握
- 2024-09-30Mock.js学习:入门教程与实战演练
- 2024-09-30React Hooks学习:从入门到实践
- 2024-09-30受控组件学习:React中的基础入门教程
- 2024-09-29JS定时器教程:初学者必看指南
- 2024-09-29JS对象教程:初学者的全面指南