关于Vue自定义组件封装的属性/事件/插槽的透传问题
// parent.vue
<Myinputv-model="keyWords"placeholder="请输入内容"size="small"@input="input"@change="change"width="320"
><template #prepend><el-select v-model="select" placeholder="请选择" style="width: 115px"><el-option label="Restaurant" value="1" /><el-option label="Order No." value="2" /><el-option label="Tel" value="3" /></el-select></template><template #append><el-button @click="handleQuery">查询</el-button></template>
</Myinput>// child.vue<el-inputv-bind="$attrs"class="e-input":style="inputStyle"v-on="$listeners"@input="$emit('input', $event)"@change="$emit('change', $event)"><template v-for="(_, slotName) in $slots" #[slotName]><slot :name="slotName"></slot></template></el-input>
内部属性: $attrs、$listeners、$slots
一、属性的透传
v-bind=“$attrs”: 只会读取子组件【props 选项】中没有申明过的属性
二、自定义事件的透传
方式一:
v-on=“$listeners”: 会将父组件所有事件监听器传递到子组件内部元素
<el-input v-bind="$attrs" class="e-input" :style="inputStyle" v-on="$listeners">
</el-input>
方式二: 直接在子组件上触发事件
<el-inputv-bind="$attrs"class="e-input":style="inputStyle"@input="$emit('input', $event)"@change="$emit('change', $event)"
>
</el-input>
方式三: 手动触发事件
export default {props: ["value"],computed: {inputValue: {get() {return this.value;},set(val) {this.$emit("input", val);},},},methods: {handleChange(e) {this.$emit("change", e.target.value);},},
};
三、插槽的透传
“$slots”: 获取所有父组件传递的插槽(默认、具名、作用域)
<template v-for="(_, slotName) in $slots" #[slotName]><slot :name="slotName"></slot>
</template>
四、获取子组件实例
// parent.vue
<Myinput ref="elInp" />mounted() {// 输入框聚焦this.$refs.elInp.setFocus();},
//child.vue<el-inputref="inputRef"v-bind="$attrs"class="e-input":style="inputStyle"v-on="$listeners"/>methods: {setFocus() {this.$refs.inputRef.focus();},
},
el-input 二次封装示例