动态组件
# 动态组件
# tabs 示例
- v-on 监听的事件也可能不一样!!
- v-bind 绑定的数据也可能不一样
<template>
<tabs v-for="pane of panes" :key="pane.key">
<component :is="pane.component" v-on="pane.event" v-bind="propData" />
</tabs>
</template>
<script>
import Main from './Main.vue'
import Add from './Add.vue'
export default {
components: {
Main,
Add,
},
data() {
return {
propData: {
id: '1',
name: 'conanan',
},
panes: [
{
key: '1',
tab: 'main页面',
component: Main,
event: { mainEvent1, mainEvent2 },
},
{
key: '2',
tab: 'add页面',
component: Add,
event: { addEvent },
},
],
}
},
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# keep-alive
和上面tabs的实现方式不一样!!这里component只有一个!!!
在开发中某些情况我们希望继续保持组件的状态,而不是销毁掉,这个时候我们就可以使用一个内置组件: keep-alive
keep-alive有一些属性:
- include - string | RegExp | Array。只有名称匹配的组件会被缓存;
- exclude - string | RegExp | Array。任何名称匹配的组件都会被缓存;
- max - number | string。最多可以缓存多少组件实例,一旦达到这个数字,那么缓存组件中最近没有被访问的实例会被销毁
include 和 exclude prop 允许组件有条件地缓存:
- 二者都可以用逗号分隔字符串、正则表达式或一个数组来表示;
- 匹配首先检查组件自身的 name 选项
# 缓存组件的生命周期
对于缓存的组件来说,再次进入时,我们是不会执行created或者mounted等生命周期函数的
但是有时候我们确实希望监听到何时重新进入到了组件,何时离开了组件
这个时候我们可以使用 activated 和 deactivated 这两个生命周期钩子函数来监听
# 示例
App.vue
<template>
<div>
<button v-for="item in tabs" :key="item"
@click="itemClick(item)"
:class="{active: currentTab === item}">
{{item}}
</button>
<!-- 2.动态组件 -->
<keep-alive include="home,about">
<component :is="currentTab"
name="coderwhy"
:age="18"
@pageClick="pageClick">
</component>
</keep-alive>
<!-- 1.v-if的判断实现 -->
<!-- <template v-if="currentTab === 'home'">
<home></home>
</template>
<template v-else-if="currentTab === 'about'">
<about></about>
</template>
<template v-else>
<category></category>
</template> -->
</div>
</template>
<script>
import Home from './pages/Home.vue';
import About from './pages/About.vue';
import Category from './pages/Category.vue';
export default {
components: {
Home,
About,
Category
},
data() {
return {
tabs: ["home", "about", "category"],
currentTab: "home"
}
},
methods: {
itemClick(item) {
this.currentTab = item;
},
pageClick() {
console.log("page内部发生了点击");
}
}
}
</script>
<style scoped>
.active {
color: red;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
About.vue
<template>
<div>
About组件
<button @click="counter++">{{counter}}</button>
</div>
</template>
<script>
export default {
name: "about",
data() {
return {
counter: 0
}
},
created() {
console.log("about created");
},
unmounted() {
console.log("about unmounted");
},
activated() {
console.log("about activated");
},
deactivated() {
console.log("about deactivated");
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Category.vue
<template>
<div>
Category组件
<button @click="counter++">{{counter}}</button>
</div>
</template>
<script>
export default {
name: "category",
data() {
return {
counter: 0
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Home.vue
<template>
<div @click="divClick">
Home组件: {{name}} - {{age}}
</div>
</template>
<script>
export default {
name: "home",
props: {
name: {
type: String,
default: ""
},
age: {
type: Number,
default: 0
}
},
emits: ["pageClick"],
methods: {
divClick() {
this.$emit("pageClick");
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
编辑 (opens new window)
上次更新: 2022/03/23, 17:55:39