乐趣区

关于vue.js:vue使用之属性透传

属性透传与实传

实传: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 修饰符移除,子组件未定义触发的事件,将被作为子组件的根元素的原生事件监听
退出移动版