属性透传与实传

实传:prop指定传递的属性; 透传:未指定prop传递的属性传递给子组件嵌套组件

透传实现:
二次封装ui组件场景为例

应用的api: $attrs, $listeners, inheritAttrs, 渲染函数

// 父组件<MyButton name="测试透传" type="error" :disabled="false" @click="clickBtn" />// 子组件const MyButton = {  // 将未被props指定的属性(不包含style,class)和不含 .native 修饰符的事件监听器绑定到子组件Button上  template: `<div class="box">    <Button v-bind:type="type" v-bind="$attrs" v-on="$listeners" />  </div>`,  components: {    Button,  },  inheritAttrs: false,  // 禁止未被props指定的属性利用到组件根元素上  props: {    type: {      type: String,      default: 'primary',    },  },  created() {    console.log(this.$attrs);  // {name: '测试透传', disabled: false}    console.log(this.$listeners);  // {click: f}  },};// ui组件Button, 间接应用如下<Button type="primary" name="测试文本" icon="xxx" disabled @click="xxx" />

.native绑定事件到子组件根元素
$listeners可用于将事件监听器指向到具体的某个子元素,应用更灵便
将原生事件绑定到组件

引申应用:动静组件透传实现
在下面案例的根底上实现动静生成表单内容

// template<div v-for="(config, index) in configArr" :key="config.type + index">  <!-- 动静组件,依据配置中的 Type 来决定渲染的是 Input 还是 Select -->  <component :is="config.type" :configProps="config.props"></component></div>// configArr[{  type: 'Input',  props: {    placeholder: '我是默认值',    clearable: true  }}, {  type: 'Button',  props: {    type: 'default'  }}]// 注册新的组件, 应用渲染函数以代替动静组件// 应用渲染函数解构props,获取attribute绑定const CompFormItem = {  components: {    Input, Select  },  name: 'FormItem',  props: {    config: {      required: true    }  },  render (h) {    // 第一个参数就是配置中的 type,也就是咱们的组件名称    return h(`${this.config.type}`, {      props: {        ...this.config.props || {}      },      attrs: {        ...this.config.props || {}      }    })  }}// 应用组件<FormItem :config="config"></FormItem>

-----对于vue3.x的变更-----

  1. $listeners被移除,事件监听器整合到$attrs中
  2. $attrs蕴含style、class属性
  3. .native修饰符移除,子组件未定义触发的事件,将被作为子组件的根元素的原生事件监听