# 二.数据输入(动态)

前言

动态组件,即组件可以作为一个变量传入到某个组件中根据一些条件,动态地切换某个组件,或动态地选择渲染某个组件

  • 下拉菜单组件应该由两部分组成:
    • 选中项的文本
    • 待选菜单(默认隐藏)
  • 它的主要功能包括:
    • 鼠标经过下拉菜单组件,显示待选菜单
    • 鼠标滑出下拉菜单组件,隐藏待选菜单
    • 鼠标点击待选菜单中的条目,选中项文本更新,组件派发 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

# 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

使用keep-alive只有mounted触发了,如果不离开当前页面,切换其他组件beforeDestory不会触发



 




<template>
  <keep-alive>
    <component :is="component"></component>
    <!-- 为了避免组件的重复渲染,使用`<keep-alive>`,这样组件就会被缓存起来 -->
  </keep-alive>
</template>
1
2
3
4
5
6

keep-alive 还有一些额外的 props 可以配置

  • include:字符串或正则表达式,只有名称匹配的组件会被缓存
  • exclude:字符串或正则表达式,任何名称匹配的组件都不会被缓存
  • max:数字,最多可以缓存多少组件实例

总结

合理使用动态组件可以让我们写出的代码更加简洁,减少冗余代码