首页 web前端 js教程 实例详解vue.js内置组件之keep-alive组件的使用

实例详解vue.js内置组件之keep-alive组件的使用

Jul 12, 2018 pm 02:02 PM
alive keep vue 组件

keep-alive是Vue.js的一个内置组件。这篇文章主要介绍了vue.js内置组件之keep-alive组件使用,需要的朋友可以参考下

keep-alive是Vue.js的一个内置组件。 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。 当组件在 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。 它提供了include与exclude两个属性,允许组件有条件地进行缓存。

举个栗子

<keep-alive>
  <router-view v-if="$route.meta.keepAlive"></router-view>
 </keep-alive>
 <router-view v-if="!$route.meta.keepAlive"></router-view>
登录后复制

在点击button时候,两个input会发生切换,但是这时候这两个输入框的状态会被缓存起来,input标签中的内容不会因为组件的切换而消失。

* include - 字符串或正则表达式。只有匹配的组件会被缓存。
* exclude - 字符串或正则表达式。任何匹配的组件都不会被缓存。

<keep-alive include="a">
 <component></component>
</keep-alive>
登录后复制

只缓存组件别民name为a的组件

<keep-alive exclude="a">
 <component></component>
</keep-alive>
登录后复制

除了name为a的组件,其他都缓存下来

生命周期钩子

生命钩子 keep-alive提供了两个生命钩子,分别是activated与deactivated。

因为keep-alive会将组件保存在内存中,并不会销毁以及重新创建,所以不会重新调用组件的created等方法,需要用activated与deactivated这两个生命钩子来得知当前组件是否处于活动状态。

深入keep-alive组件实现


查看vue--keep-alive组件源代码可以得到以下信息

created钩子会创建一个cache对象,用来作为缓存容器,保存vnode节点。

props: {
 include: patternTypes,
 exclude: patternTypes,
 max: [String, Number]
},
created () {
 // 创建缓存对象
 this.cache = Object.create(null)
 // 创建一个key别名数组(组件name)
 this.keys = []
},
登录后复制

destroyed钩子则在组件被销毁的时候清除cache缓存中的所有组件实例。

destroyed () {
 /* 遍历销毁所有缓存的组件实例*/
 for (const key in this.cache) {
  pruneCacheEntry(this.cache, key, this.keys)
 }
},
登录后复制

:::demo

render () {
 /* 获取插槽 */
 const slot = this.$slots.default
 /* 根据插槽获取第一个组件组件 */
 const vnode: VNode = getFirstComponentChild(slot)
 const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
 if (componentOptions) {
 // 获取组件的名称(是否设置了组件名称name,没有则返回组件标签名称)
 const name: ?string = getComponentName(componentOptions)
 // 解构对象赋值常量
 const { include, exclude } = this
 if ( /* name不在inlcude中或者在exlude中则直接返回vnode */
  // not included
  (include && (!name || !matches(include, name))) ||
  // excluded
  (exclude && name && matches(exclude, name))
 ) {
  return vnode
 }
 const { cache, keys } = this
 const key: ?string = vnode.key == null
  // same constructor may get registered as different local components
  // so cid alone is not enough (#3269)
  ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : &#39;&#39;)
  : vnode.key
 if (cache[key]) { // 判断当前是否有缓存,有则取缓存的实例,无则进行缓存
  vnode.componentInstance = cache[key].componentInstance
  // make current key freshest
  remove(keys, key)
  keys.push(key)
 } else {
  cache[key] = vnode
  keys.push(key)
  // 判断是否设置了最大缓存实例数量,超过则删除最老的数据,
  if (this.max && keys.length > parseInt(this.max)) {
  pruneCacheEntry(cache, keys[0], keys, this._vnode)
  }
 }
 // 给vnode打上缓存标记
 vnode.data.keepAlive = true
 }
 return vnode || (slot && slot[0])
}
// 销毁实例
function pruneCacheEntry (
 cache: VNodeCache,
 key: string,
 keys: Array<string>,
 current?: VNode
) {
 const cached = cache[key]
 if (cached && (!current || cached.tag !== current.tag)) {
 cached.componentInstance.$destroy()
 }
 cache[key] = null
 remove(keys, key)
}
// 缓存
function pruneCache (keepAliveInstance: any, filter: Function) {
 const { cache, keys, _vnode } = keepAliveInstance
 for (const key in cache) {
 const cachedNode: ?VNode = cache[key]
 if (cachedNode) {
  const name: ?string = getComponentName(cachedNode.componentOptions)
  // 组件name 不符合filler条件, 销毁实例,移除cahe
  if (name && !filter(name)) {
  pruneCacheEntry(cache, key, keys, _vnode)
  }
 }
 }
}
// 筛选过滤函数
function matches (pattern: string | RegExp | Array<string>, name: string): boolean {
 if (Array.isArray(pattern)) {
 return pattern.indexOf(name) > -1
 } else if (typeof pattern === &#39;string&#39;) {
 return pattern.split(&#39;,&#39;).indexOf(name) > -1
 } else if (isRegExp(pattern)) {
 return pattern.test(name)
 }
 /* istanbul ignore next */
 return false
}
// 检测 include 和 exclude 数据的变化,实时写入读取缓存或者删除
mounted () {
 this.$watch(&#39;include&#39;, val => {
 pruneCache(this, name => matches(val, name))
 })
 this.$watch(&#39;exclude&#39;, val => {
 pruneCache(this, name => !matches(val, name))
 })
},
登录后复制

:::

通过查看Vue源码可以看出,keep-alive默认传递3个属性,include 、exclude、max, max 最大可缓存的长度

结合源码我们可以实现一个可配置缓存的router-view

<!--exclude - 字符串或正则表达式。任何匹配的组件都不会被缓存。-->
<!--TODO 匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称-->
<keep-alive :exclude="keepAliveConf.value">
 <router-view class="child-view" :key="$route.fullPath"></router-view>
</keep-alive>
<!-- 或者 -->
<keep-alive :include="keepAliveConf.value">
 <router-view class="child-view" :key="$route.fullPath"></router-view>
</keep-alive>
<!-- 具体使用 include 还是exclude 根据项目是否需要缓存的页面数量多少来决定-->
登录后复制

创建一个keepAliveConf.js 放置需要匹配的组件名

// 路由组件命名集合
 var arr = [&#39;component1&#39;, &#39;component2&#39;];
 export default {value: routeList.join()};
登录后复制

配置重置缓存的全局方法

import keepAliveConf from &#39;keepAliveConf.js&#39;
Vue.mixin({
 methods: {
 // 传入需要重置的组件名字
 resetKeepAive(name) {
  const conf = keepAliveConf.value;
  let arr = keepAliveConf.value.split(&#39;,&#39;);
  if (name && typeof name === &#39;string&#39;) {
   let i = arr.indexOf(name);
   if (i > -1) {
    arr.splice(i, 1);
    keepAliveConf.value = arr.join();
    setTimeout(() => {
     keepAliveConf.value = conf
    }, 500);
   }
  }
 },
 }
})
登录后复制

在合适的时机调用调用this.resetKeepAive(name),触发keep-alive销毁组件实例;

Vue.js内部将DOM节点抽象成了一个个的VNode节点,keep-alive组件的缓存也是基于VNode节点的而不是直接存储DOM结构。它将满足条件的组件在cache对象中缓存起来,在需要重新渲染的时候再将vnode节点从cache对象中取出并渲染。

以上是实例详解vue.js内置组件之keep-alive组件的使用的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

vue.js怎么引用js文件 vue.js怎么引用js文件 Apr 07, 2025 pm 11:27 PM

在 Vue.js 中引用 JS 文件的方法有三种:直接使用 &lt;script&gt; 标签指定路径;利用 mounted() 生命周期钩子动态导入;通过 Vuex 状态管理库进行导入。

vue中的watch怎么用 vue中的watch怎么用 Apr 07, 2025 pm 11:36 PM

Vue.js 中的 watch 选项允许开发者监听特定数据的变化。当数据发生变化时,watch 会触发一个回调函数,用于执行更新视图或其他任务。其配置选项包括 immediate,用于指定是否立即执行回调,以及 deep,用于指定是否递归监听对象或数组的更改。

vue怎么给按钮添加函数 vue怎么给按钮添加函数 Apr 08, 2025 am 08:51 AM

可以通过以下步骤为 Vue 按钮添加函数:将 HTML 模板中的按钮绑定到一个方法。在 Vue 实例中定义该方法并编写函数逻辑。

vue中怎么用bootstrap vue中怎么用bootstrap Apr 07, 2025 pm 11:33 PM

在 Vue.js 中使用 Bootstrap 分为五个步骤:安装 Bootstrap。在 main.js 中导入 Bootstrap。直接在模板中使用 Bootstrap 组件。可选:自定义样式。可选:使用插件。

vue返回上一页的方法 vue返回上一页的方法 Apr 07, 2025 pm 11:30 PM

Vue.js 返回上一页有四种方法:$router.go(-1)$router.back()使用 &lt;router-link to=&quot;/&quot;&gt; 组件window.history.back(),方法选择取决于场景。

Vue 实现跑马灯/文字滚动效果 Vue 实现跑马灯/文字滚动效果 Apr 07, 2025 pm 10:51 PM

在 Vue 中实现跑马灯/文字滚动效果,可以使用 CSS 动画或第三方库。本文介绍了使用 CSS 动画的方法:创建滚动文本,用 &lt;div&gt; 包裹文本。定义 CSS 动画,设置 overflow: hidden、width 和 animation。定义关键帧,设置动画开始和结束时的 transform: translateX()。调整动画属性,如持续时间、滚动速度和方向。

vue懒加载什么意思 vue懒加载什么意思 Apr 07, 2025 pm 11:54 PM

在 Vue.js 中,懒加载允许根据需要动态加载组件或资源,从而减少初始页面加载时间并提高性能。具体实现方法包括使用 &lt;keep-alive&gt; 和 &lt;component is&gt; 组件。需要注意的是,懒加载可能会导致 FOUC(闪屏)问题,并且应该仅对需要懒加载的组件使用,以避免不必要的性能开销。

怎样查询vue的版本 怎样查询vue的版本 Apr 07, 2025 pm 11:24 PM

可以通过以下方法查询 Vue 版本:使用 Vue Devtools 在浏览器的控制台中查看“Vue”选项卡。使用 npm 运行“npm list -g vue”命令。在 package.json 文件的“dependencies”对象中查找 Vue 项。对于 Vue CLI 项目,运行“vue --version”命令。检查 HTML 文件中引用 Vue 文件的 &lt;script&gt; 标签中的版本信息。

See all articles