component内置组件
比如我们现在想要实现了一个功能:
-
点击一个tab-bar,切换不同的组件显示;
-
这个案例我们可以通过两种不同的实现思路来实现:
-
方式一:通过v-if来判断,显示不同的组件;
方式二:动态组件的方式;
1.v-if显示不同的组件
<template>
<div>
<button v-for="item in list" :key="item"
:class="{active: curItem === item}"
@click="btnClick(item)">{{item}}</button>
<!-- v-if实现 -->
<template v-if="curItem === 'home'">
<home/>
</template>
<template v-else-if="curItem === 'about'">
<about/>
</template>
<template v-else>
<category/>
</template>
</div>
</template>
<script>
import About from './pages/About.vue'
import Home from './pages/Home.vue'
import Category from './pages/Category.vue'
export default {
components: {
About,
Home,
Category
},
data() {
return {
list: ['home', 'about', 'category'],
curItem: 'home'
}
},
methods: {
btnClick(item) {
this.curItem = item
},
}
}
</script>
<style scoped>
.active {
color: red
}
</style>
2.使用vue内置组件component动态显示组件
通过给内置组件component的属性is
动态绑定不同的值,值为全局或局部注册的组件名称
,来渲染
不同的组件
<template>
<div>
<button v-for="item in list" :key="item"
:class="{active: curItem === item}"
@click="btnClick(item)">{{item}}</button>
<!-- 使用动态组件:
is的值为组件名称,组件可以是全局的也可以是局部的 -->
<component :is="curItem"></component>
</div>
</template>
<script>
import About from './pages/About.vue'
import Home from './pages/Home.vue'
import Category from './pages/Category.vue'
export default {
components: {
About,
Home,
Category
},
data() {
return {
list: ['home', 'about', 'category'],
curItem: 'home'
}
},
methods: {
btnClick(item) {
this.curItem = item
},
}
}
</script>
<style scoped>
.active {
color: red
}
</style>
这个curItem的值需要是什么内容呢?
- 可以是通过
component函数
注册的全局组件的名称; - 在一个组件对象的
components
对象中注册的局部组件的名称;
2.1动态组件的传值和监听事件
如果需要给动态渲染的动态组件传递属性,和监听组件内部发射的事件,可以直接在component组件上传递属性和监听事件
home.vue
例如,home.vue在被渲染的时候,需要给其传递name,age属性,并且监听其内部发出的pageClick事件
<template>
<div @click="divClick">
Home组件:{{name}} - {{age}}
</div>
</template>
<script>
export default {
props: ['name', 'age'],
emits: ['pageClick'],
methods: {
divClick() {
this.$emit('pageClick')
}
}
}
</script>
<style scoped>
</style>
App.vue
<template>
<div>
<button v-for="item in list" :key="item"
:class="{active: curItem === item}"
@click="btnClick(item)">{{item}}</button>
<!-- 使用动态组件:
is的值为组件名称,组件可以是全局的也可以是局部的
如果需要给动态渲染的动态组件传递属性,和监听组件内部发射的事件,可以直接在component组件上传递属性和监听事件 -->
<component :is="curItem" name="小明" :age="18" @pageClick="pageClick"></component>
</div>
</template>
<script>
import About from './pages/About.vue'
import Home from './pages/Home.vue'
import Category from './pages/Category.vue'
export default {
components: {
About,
Home,
Category
},
data() {
return {
list: ['home', 'about', 'category'],
curItem: 'home'
}
},
methods: {
btnClick(item) {
this.curItem = item
},
pageClick() {
console.log("页面内部发生了点击")
}
}
}
</script>
<style scoped>
.active {
color: red
}
</style>
keep-alive内置组件
我们先对之前的案例中About组件进行改造:
About.vue
<template>
<div>
About组件
<button @click="count++">{{count}}</button>
</div>
</template>
<script>
export default {
name: 'about',
data() {
return {
count: 0
}
}
}
</script>
<style scoped>
</style>
在其中增加了一个按钮,点击可以递增的功能;
- 比如我们将counter点到10,那么在切换到home再切换回来about时,状态是否可以保持呢?
- 答案是否定的;
- 这是因为默认情况下,我们在切换组件后,about组件会被销毁掉,再次回来时会重新创建组件;
- 但是,在开发中某些情况我们希望在
切换组件
时,继续保持
组件的状态,而不是销毁掉
, - 这个时候我们就可以使用一个内置组件:
keep-alive
- 但是,在开发中某些情况我们希望在
keep-alive组件用来缓存组件,使在切换组件时,组件不被销毁
keep-alive属性
keep-alive有一些属性:
-
include
- string | RegExp | Array。只有名称匹配的组件会被缓
存;名称指的是组件内部name属性的值 -
exclude
- string | RegExp | Array。任何名称匹配的组件都不
会被缓存;名称指的是组件内部name属性的值 -
max
- number | string。最多可以缓存多少组件实例,一旦达
到这个数字,那么缓存组件中最近没有被访问的实例会被销毁;
include 和 exclude prop 允许组件有条件地缓存:
- 二者都可以用逗号分隔字符串、正则表达式或一个数组来表示;
- 匹配首先检查组件自身的 name 选项;
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<keep-alive :include="[a,b]">
<component :is="view"></component>
</keep-alive>
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
App.vue
<template>
<div>
<button v-for="item in list" :key="item"
:class="{active: curItem === item}"
@click="btnClick(item)">{{item}}</button>
<!--缓存about组件-->
<keep-alive include="about">
<component :is="curItem" name="小明" :age="18" @pageClick="pageClick" ></component>
</keep-alive>
</div>
</template>
<script>
import About from './pages/About.vue'
import Home from './pages/Home.vue'
import Category from './pages/Category.vue'
export default {
components: {
About,
Home,
Category
},
data() {
return {
list: ['home', 'about', 'category'],
curItem: 'home'
}
},
methods: {
btnClick(item) {
this.curItem = item
},
pageClick() {
console.log("页面内部发生了点击")
}
}
}
</script>
<style scoped>
.active {
color: red
}
</style>
缓存组件的生命周期
对于缓存的组件来说,离开和再次进入组件时,组件是不会被销毁的,
- 离开组件时,不会执行
unmounted
等生命周期 - 再次进入组件时,也不会执行created或者mounted等生命周期函数的:
但是有时候我们确实希望监听到何时重新进入到了组件,何时离开了组件;
- 这个时候我们可以使用
activated
和deactivated
这两个生命周期钩子函数来监听;
<template>
<div>
About组件
<button @click="count++">{{count}}</button>
</div>
</template>
<script>
export default {
name: 'about',
data() {
return {
count: 0
}
},
activated() {
console.log("再次进入了当前组件")
},
deactivated() {
console.log("再次离开了当前组件")
},
}
</script>
<style scoped>
</style>
此文档主要内容来源于王红元老师的vue3+ts视频教程