VueJS 之动态组件
参考
项目 | 描述 |
---|---|
搜索引擎 | Bing |
哔哩哔哩 | 黑马程序员 |
VueJS 官方文档 | 动态组件 & 异步组件 |
描述
项目 | 描述 |
---|---|
Edge | 109.0.1518.70 (正式版本) (64 位) |
操作系统 | Windows 10 专业版 |
@vue/cli | 5.0.8 |
npm | 8.19.3 |
VueJS | 2.6.14 |
动态组件
动态组件即动态切换组件,实现组件的动态切换可以使用 VueJS 提供的 component 元素,该元素拥有一个 is 属性。
你可以向 component 元素提供一个组件的名称来作为 is 属性的参数,接下来对应的组件将替代 components 元素。
子组件
在该部分内容中需要用到两个子组件,即 First.vue 及 Last.vue。接下来的内容中,如果没有特殊提示,First.vue 及 Last.vue 中的内容均如下所示。
First.vue
<template>
<div class="container"></div>
</template>
<script>
export default {
}
</script>
<style scoped>
.container{
width: 400px;
height: 180px;
background-color: dodgerblue;
}
</style>
Last.vue
<template>
<div class="container"></div>
</template>
<script>
export default {
}
</script>
<style scoped>
.container{
width: 400px;
height: 180px;
background-color: pink;
}
</style>
举个栗子
展示组件 First.vue
<template>
<div class="container">
<component is="First"></component>
</div>
</template>
<script>
// 导入组件
import First from '@/components/First.vue';
import Last from '@/components/Last.vue';
export default {
// 注册组件
components: {
First,
Last
}
}
</script>
<style>
</style>
执行结果:
展示组件 Last.vue
<template>
<div class="container">
<component is="Last"></component>
</div>
</template>
<script>
// 导入组件
import First from '@/components/First.vue';
import Last from '@/components/Last.vue';
export default {
// 注册组件
components: {
First,
Last
}
}
</script>
<style>
</style>
执行结果:
切换组件
我们可以定义一个数据并将该数据作为 component 元素的 is 属性值,这个数据保存了组件的名称,当我们需要切换组件时,只需要改变数据所保存的内容即可。
举个栗子
<template>
<div class="container">
<!-- 使用属性绑定指令将指定的数据绑定到属性中 -->
<component v-bind:is="show"></component>
<button @click="transfer()">Transfer</button>
</div>
</template>
<script>
// 导入组件
import First from '@/components/First.vue';
import Last from '@/components/Last.vue';
export default {
// 定义数据
data() {
return {
show: 'First'
}
},
// 注册组件
components: {
First,
Last
},
// 定义事件处理函数
methods: {
transfer() {
if(this.show === 'First'){
this.show = 'Last';
}else{
this.show = 'First';
}
}
}
}
</script>
<style>
</style>
执行效果:
keep-alive
子组件
在该部分内容中需要用到两个子组件,即 First.vue 及 Last.vue。接下来的内容中,如果没有特殊提示,First.vue 及 Last.vue 中的内容均如下所示。
子组件 First.vue
<template>
<div class="container">
<h3>Number: {{ num }}</h3>
<button @click="add()">Add</button>
</div>
</template>
<script>
export default {
// 定义数据
data() {
return {
num: 0
}
},
// 定义事件调用函数
methods: {
add() {
this.num += 1;
}
}
}
</script>
<style scoped>
.container{
width: 400px;
height: 180px;
background-color: dodgerblue;
}
h3{
color: #fff;
}
</style>
子组件 Last.vue
<template>
<div class="container"></div>
</template>
<script>
export default {
}
</script>
<style scoped>
.container{
width: 400px;
height: 180px;
background-color: pink;
}
</style>
组件的再生成
在组件的动态切换过程中,存在组件的生成与销毁过程。
<template>
<div class="container">
<!-- 使用属性绑定指令将指定的数据绑定到属性中 -->
<component v-bind:is="show"></component>
<button @click="transfer()">Transfer</button>
</div>
</template>
<script>
// 导入组件
import First from '@/components/First.vue';
import Last from '@/components/Last.vue';
export default {
// 定义数据
data() {
return {
show: 'First'
}
},
// 注册组件
components: {
First,
Last
},
// 定义事件处理函数
methods: {
transfer() {
if(this.show === 'First'){
this.show = 'Last';
}else{
this.show = 'First';
}
}
}
}
</script>
<style>
</style>
执行效果:
分析:
在切换组件后,原组件将被销毁。再次切换为原组件时,由于组件经历了再生成的过程,组件中的数据都将处于初始状态。
keep-alive
在实现组件的动态切换功能时,你可能会想保持这些组件的状态,以避免反复重新渲染导致的性能问题。我们可以使用 keep-alive 元素达成该目的。
keep-alive 能够使被替换的组件不用经历组件的再生成过程,被替换的组件将处于缓存状态,等待用户的再次使用。keep-alive 的使用方式很简单,你仅需要使用 keep-alive 元素将需要被缓存的动态组件包裹起来。
举个栗子
<template>
<div class="container">
<keep-alive>
<!-- 使用属性绑定指令将指定的数据绑定到属性中 -->
<component v-bind:is="show"></component>
</keep-alive>
<button @click="transfer()">Transfer</button>
</div>
</template>
<script>
// 导入组件
import First from '@/components/First.vue';
import Last from '@/components/Last.vue';
export default {
// 定义数据
data() {
return {
show: 'First'
}
},
// 注册组件
components: {
First,
Last
},
// 定义事件处理函数
methods: {
transfer() {
if(this.show === 'First'){
this.show = 'Last';
}else{
this.show = 'First';
}
}
}
}
</script>
<style>
</style>
执行效果:
include
keep-alive 元素拥有 include 属性,你可以通过向该属性提交组件名来指定需要被缓存的组件。如果有多个组件需要被缓存,请使用逗号分隔组件名。
举个栗子
<template>
<div class="container">
<!-- 指定 First 组件需要被缓存 -->
<keep-alive include="First">
<!-- 使用属性绑定指令将指定的数据绑定到属性中 -->
<component v-bind:is="show"></component>
</keep-alive>
<button @click="transfer()">Transfer</button>
</div>
</template>
<script>
// 导入组件
import First from '@/components/First.vue';
import Last from '@/components/Last.vue';
export default {
// 定义数据
data() {
return {
show: 'First'
}
},
// 注册组件
components: {
First,
Last
},
// 定义事件处理函数
methods: {
transfer() {
if(this.show === 'First'){
this.show = 'Last';
}else{
this.show = 'First';
}
}
}
}
</script>
<style>
</style>
执行效果
exclude
keep-alive 元素拥有 exclude 属性,你可以通过向该属性提交组件名来指定不需要被缓存的组件。如果有多个组件不需要被缓存,请使用逗号分隔组件名。
举个栗子
<template>
<div class="container">
<!-- 指定 First 组件不需要被缓存 -->
<keep-alive exclude="First">
<!-- 使用属性绑定指令将指定的数据绑定到属性中 -->
<component v-bind:is="show"></component>
</keep-alive>
<button @click="transfer()">Transfer</button>
</div>
</template>
<script>
// 导入组件
import First from '@/components/First.vue';
import Last from '@/components/Last.vue';
export default {
// 定义数据
data() {
return {
show: 'First'
}
},
// 注册组件
components: {
First,
Last
},
// 定义事件处理函数
methods: {
transfer() {
if(this.show === 'First'){
this.show = 'Last';
}else{
this.show = 'First';
}
}
}
}
</script>
<style>
</style>
执行效果
生命周期钩子
在组件被缓存或被激活的时候将触发相应的生命周期钩子(生命周期函数)。
- 当组件被激活时将触发 activated 生命周期钩子。
- 当组件被缓存时将触发 deactivated 生命周期钩子。
举个栗子
<template>
<div class="container">
<keep-alive>
<!-- 使用属性绑定指令将指定的数据绑定到属性中 -->
<component v-bind:is="show"></component>
</keep-alive>
<button @click="transfer()">Transfer</button>
</div>
</template>
<script>
// 导入组件
import First from '@/components/First.vue';
import Last from '@/components/Last.vue';
export default {
// 定义数据
data() {
return {
show: 'First'
}
},
// 注册组件
components: {
First,
Last
},
// 定义事件处理函数
methods: {
transfer() {
if(this.show === 'First'){
this.show = 'Last';
}else{
this.show = 'First';
}
}
}
}
</script>
<style>
</style>
请将子组件 First.vue 修改为:
<template>
<div class="container">
<h3>Number: {{ num }}</h3>
<button @click="add()">Add</button>
</div>
</template>
<script>
export default {
// 定义数据
data() {
return {
num: 0
}
},
// 定义事件调用函数
methods: {
add() {
this.num += 1;
}
},
// activated 生命周期对应的生命周期钩子
activated() {
console.log('【Activated】')
},
// deactivated 生命周期对应的生命周期钩子
deactivated() {
console.log('【Deactivated】')
}
}
</script>
<style scoped>
.container{
width: 400px;
height: 180px;
background-color: dodgerblue;
}
h3{
color: #fff;
}
</style>
执行效果: