vue动态组件

931 阅读2分钟

开发vue时,有时候需要根据应用场景生成的动态的vue组件,vue为我们提供比较常用的两种对接方式:

  1. 使用component标签元素
  2. 使用render渲染函数

使用component标签元素

直接配置组件名、属性、值和事件

<template>
  <component
    :is="config.name"
    v-bind="config.props"
    v-on="config.on"
    v-model="config.value"
    :class="config.class"
    :style="config.style"
  ></component>
</template>

<script>
export default {
  data() {
    return {
      config: {
        name: "el-input-number",
        props: {
          size: "small"
        },
        on: {
          input: function(data) {}
        },
        value: 10
      }
    };
  }
};
</script>

优点:编写简单、方便,容易上手;原生元素(如:input)也可使用
缺点:不支持原生事件

使用render渲染函数

需要定义一个中间组件,它起着桥梁的作用;它的作用就相当于上面的component,只不过component由系统实现了,这个中间组件由用户实现。
(具体的案例可见vue-easy-form,其动态组件的实现方式就是利用了render渲染函数

export default {
  render: function(createElement) {
    createElement(
        this.config.name, // tag name 标签名称 https://www.cnblogs.com/tugenhua0707/p/7528621.html
        {
          attrs: this.config.attrs, //attrs为原生属性
          // style: this.config.style,
          class: this.config.class,
          style: this.config.style,
          // DOM属性
          domProps: {
            // innerHTML: "baz"
            // value: this.config.value
          },
          // 组件props
          props: this.config.props,
          
          // 事件监听器在 `on` 属性内
          on: this.config.on,
          // 原生事件
          nativeOn: this.config.nativeOn,
          // 作用域插槽的格式为
          // { name: props => VNode | Array<VNode> }
          scopedSlots: {
            default: props => createElement('span', props.text)
          }
        }
      );
  },
  props: {
    config: {
      type: Object,
      required: true,
      default: () => {
        return {};
      }
    }
  },
  methods: {}
};

优点:编程式的写法,编写自由
缺点:由于编写自由,所有的功能都要重新实现。(比如原生元素的<input type="checkbox"/>的双向绑定)

项目选择

  1. 若项目是基于业务的,所有的开发代码都在项目中,使用component标签元素作为动态组件的桥梁一般都够用;
  2. 若项目是一个独立的类库,作为第三方组件提供给别人使用,最好使用render渲染函数实现动态组件,这样实现的功能比较齐全。