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