属性透传与实传
实传: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的变更—–
- $listeners被移除,事件监听器整合到$attrs中
- $attrs蕴含style、class属性
- .native修饰符移除,子组件未定义触发的事件,将被作为子组件的根元素的原生事件监听
发表回复