# 二.数据输入(动态)
前言
动态组件,即组件可以作为一个变量传入到某个组件中根据一些条件,动态地切换某个组件,或动态地选择渲染某个组件
- 下拉菜单组件应该由两部分组成:
- 选中项的文本
- 待选菜单(默认隐藏)
- 它的主要功能包括:
- 鼠标经过下拉菜单组件,显示待选菜单
- 鼠标滑出下拉菜单组件,隐藏待选菜单
- 鼠标点击待选菜单中的条目,选中项文本更新,组件派发 change 事件
# 1. 动态组件
Vue.js 提供了另外一个内置组件<component>
和is
特性,可以实现动态组件
刷新
全屏/自适应
除了直接绑定一个 Object,还可以是一个 String,比如标签名,组件名。
# 2.组件封装
下面的这个组件,将原生按钮 button 进行了封装,如果传入了prop:to
,它会渲染为一个<a>
标签,用于打开这个链接地址,如果没有传入to
,就当做普通的 button 使用
- 源代码
<template>
<component :is="tagName" v-bind="tagProps">
<slot></slot>
</component>
</template>
<script>
export default {
name: "VueComponent",
props: {
to: {
type: String,
default: "",
},
target: {
type: String,
default: "_self",
},
},
computed: {
tagName() {
return this.to === "" ? "button" : "a"; // 动态渲染不同的标签
},
tagProps() {
// 如果是链接,把这些属性绑定到component上
let props = {};
if (this.to) {
props = {
target: this.target,
href: this.to,
};
}
return props;
},
},
};
</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
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
# 3.使用案例
刷新
全屏/自适应
最终会渲染出一个原生button
按钮和两个原生的链接a
,且第二个点击会在新窗口中打开链接。
my-button 组件中component
is
绑定的就是一个标签名称 button/a,并且通过v-bind
将一些额外的属性全部绑定到component
上,
再回到第一个 a/b/c 组件的切换狩猎,如果这类组件,频繁切换,实际上组件是会重新渲染的,比如我们在组件 A 里加两个生命周期。
- a.vue
<template>
<div>组件A</div>
</template>
<script>
export default {
mounted() {
console.log("组件创建了") // 只要切换到 A 组件,`mounted`就会触发一次,
},
beforeDestory() {
console.log("组件销毁了") // 切换到其他组件,`beforeDesotory`也会触发一次,说明组件在重新渲染,这样有可能导致性能问题。
},
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
使用
keep-alive
只有mounted
触发了,如果不离开当前页面,切换其他组件beforeDestory
不会触发
<template>
<keep-alive>
<component :is="component"></component>
<!-- 为了避免组件的重复渲染,使用`<keep-alive>`,这样组件就会被缓存起来 -->
</keep-alive>
</template>
1
2
3
4
5
6
2
3
4
5
6
keep-alive 还有一些额外的 props 可以配置
- include:字符串或正则表达式,只有名称匹配的组件会被缓存
- exclude:字符串或正则表达式,任何名称匹配的组件都不会被缓存
- max:数字,最多可以缓存多少组件实例
总结
合理使用动态组件可以让我们写出的代码更加简洁,减少冗余代码