目录
前言
动态组件
扩展
关于is
1.动态组件
的用法
组件缓存
扩展
跟keep-alive有关的生命周期是哪些?
activated
deactivated
前言
在开发Vue项目的时候,大部分组件是没必要多次渲染的,所以Vue提供了一个
内置组件keep-alive来缓存组件内部状态,避免重新渲染。
keep-alive是一个抽象组件:它自身不会渲染一个DOM元素,也不会出现在父组件链中;
使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
动态组件
多个组件使用同一个挂载点,并动态切换,这就是动态组件
栗子:完成一个注册功能页面, 2个按钮切换, 一个填写注册信息, 一个填写用户简介信息
-
<template>
-
<div>
-
<button @click="comName = 'UserName'">账号密码填写</button>
-
<button @click="comName = 'UserInfo'">个人信息填写</button>
-
-
<p>下面显示注册组件-动态切换:</p>
-
<div style="border: 1px solid red;">
-
<component :is="comName"></component>
-
</div>
-
</div>
-
</template>
-
-
<script>
-
// 目标: 动态组件 - 切换组件显示
-
// 场景: 同一个挂载点要切换 不同组件 显示
-
// 1. 创建要被切换的组件 - 标签+样式
-
// 2. 引入到要展示的vue文件内, 注册
-
// 3. 变量-承载要显示的组件名
-
// 4. 设置挂载点<component :is="变量"></component>
-
// 5. 点击按钮-切换comName的值为要显示的组件名
-
-
import UserName from '../components/01/UserName'
-
import UserInfo from '../components/01/UserInfo'
-
export default {
-
data(){
-
return {
-
comName: "UserName"
-
}
-
},
-
components: {
-
UserName,
-
UserInfo
-
}
-
}
-
</script>
结论:vue内置component组件, 配合is属性, 设置要显示的组件名字
扩展
关于is
1.动态组件
componentName可以是在本页面已经注册的局部组件名和全局组件名,也可以是一个组件的选项对象。 当控制componentName改变时就可以动态切换选择组件。
2.is的用法
有些HTML元素,诸如 <ul>、<ol>、<table>和<select>,对于哪些元素可以出现在其内部是有严格限制的。 而有些HTML元素,诸如 <li>、<tr> 和 <option>,只能出现在其它某些特定的元素内部。
-
<ul>
-
-
<card-list></card-list>
-
-
</ul>
-
// 所以上面会被作为无效的内容提升到外部,并导致最终渲染结果出错。应该这么写:
-
<ul>
-
-
<li is="cardList"></li>
-
-
</ul>
-
组件缓存
组件切换会导致组件被频繁销毁和重新创建, 性能不高
使用Vue内置的keep-alive组件, 可以让包裹的组件保存在内存中不被销毁
演示1: 可以先给和 注册created和destroyed生命周期事件, 观察创建和销毁过程
演示2: 使用keep-alive内置的vue组件, 让动态组件缓存而不是销毁 语法: Vue内置的keep-alive组件 包起来要频繁切换的组件
-
<div style="border: 1px solid red;">
-
<!-- Vue内置keep-alive组件, 把包起来的组件缓存起来 -->
-
<keep-alive>
-
<component :is="comName"></component>
-
</keep-alive>
-
</div>
在vue-router中的应用
-
<keep-alive : include="whiteList" : exclude="blackList">
-
<router-view></router-view>
-
</keep-alive>
include定义缓存白名单,keep-alive会缓存命中的组件;
exclude定义缓存黑名单,被命中的组件将不会被缓存;
很多时候也可以配合路由的meta属性使用
-
export default[
-
{
-
path:'/',
-
name:'home',
-
components:Home,
-
meta:{
-
keepAlive:true //需要被缓存的组件
-
},
-
{
-
path:'/book',
-
name:'book',
-
components:Book,
-
meta:{
-
keepAlive:false //不需要被缓存的组件
-
}
-
]
-
<keep-alive>
-
<router-view v-if="this.$"></router-view>
-
<!--这里是会被缓存的组件-->
-
</keep-alive>
-
<keep-alive v-if="!this.$"></keep-alive>
-
<!--这里是不会被缓存的组件-->
补充生命周期: 被缓存的组件不再创建和销毁, 而是激活和非激活
- activated - 激活
- deactivated - 失去激活状态
结论: keep-alive可以提高组件的性能, 内部包裹的标签不会被销毁和重新创建, 触发激活和非激活的生命周期方法
扩展
跟keep-alive有关的生命周期是哪些?
生命周期函数:在被keep-alive包含的组件/路由中,会多出两个生命周期的钩子:activated 与 deactivated。
-
activated
activated钩子:**在在组件第一次渲染时会被调用,之后在每次缓存组件被激活时调用。
Activated钩子调用时机:** 第一次进入缓存路由/组件,在mounted后面,beforeRouteEnter守卫传给 next 的回调函数之前调用,并且给因为组件被缓存了,再次进入缓存路由、组件时,不会触发这些钩子函数,beforeCreate created beforeMount mounted 都不会触发
-
deactivated
deactivated钩子:**组件被停用(离开路由)时调用。
deactivated钩子调用时机:使用keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroyed(组件销毁),因为组件没被销毁,被缓存起来了,这个钩子可以看作beforeDestroy的替代,如果你缓存了组件,要在组件销毁的的时候做一些事情,可以放在这个钩子里,组件内的离开当前路由钩子beforeRouteLeave => 路由前置守卫 beforeEach =>全局后置钩子afterEach => deactivated 离开缓存组件 => activated 进入缓存组件(如果你进入的也是缓存路由)