关于Vue自定义组件封装的属性/事件/插槽的透传问题

html 复制代码
// parent.vue
<Myinput
  v-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-input
    v-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": 会将父组件所有事件监听器传递到子组件内部元素

html 复制代码
<el-input 
    v-bind="$attrs" 
    class="e-input" 
    :style="inputStyle" 
    v-on="$listeners">
</el-input>

方式二: 直接在子组件上触发事件

html 复制代码
<el-input
  v-bind="$attrs"
  class="e-input"
  :style="inputStyle"
  @input="$emit('input', $event)"
  @change="$emit('change', $event)"
>
</el-input>

方式三: 手动触发事件

js 复制代码
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": 获取所有父组件传递的插槽(默认、具名、作用域)

html 复制代码
<template v-for="(_, slotName) in $slots" #[slotName]>
  <slot :name="slotName"></slot>
</template>

四、获取子组件实例

js 复制代码
// parent.vue
<Myinput ref="elInp" />
  mounted() {
    // 输入框聚焦
    this.$refs.elInp.setFocus();
  },
html 复制代码
//child.vue
    <el-input
      ref="inputRef"
      v-bind="$attrs"
      class="e-input"
      :style="inputStyle"
      v-on="$listeners"
    />
    
methods: {
    setFocus() {
      this.$refs.inputRef.focus();
    },
},

el-input 二次封装示例

相关推荐
雪芽蓝域zzs9 分钟前
第25章:地图下钻交互(点击省份,切换到对应省份城市地图)
vue.js·echars
daols8838 分钟前
vue 甘特图组件 vxe-gantt 自动计算工期显示关键路径
vue.js·vxe-gantt
—Qeyser1 小时前
Element Plus 安装与配置指南 (Vue 3 + Vite + TS)
vue.js
雪芽蓝域zzs1 小时前
第19章:ECharts 组合图(折线 + 柱状混合图,双 Y 轴)
vue.js·echars
雪芽蓝域zzs2 小时前
第17章:ECharts 饼图自定义样式(扇区颜色、轮廓、标签配置 + 空状态兼容)
vue.js·echars
雪芽蓝域zzs2 小时前
第15章:ECharts 图表事件交互(若依 Vue3)
vue.js·echars
honkun62 小时前
vue甘特图组件 vxe-gantt 实现拖拽任务自动更新紧前紧后依赖线关联任务的日期
vue.js·vxe-gantt
雪芽蓝域zzs2 小时前
第20章:ECharts 图表主题切换 + 自定义颜色渐变
vue.js·echars
mldong3 小时前
给流程设计器加国际化,我没引 vue-i18n
前端·javascript·vue.js
边境悍匪3 小时前
蜗牛学苑 Java 智能体学习 Day46|贯穿项目 2 思维导图复盘
java·开发语言·vue.js·学习·spring