You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

VueJS新手求助:如何从自定义按钮组件触发两个不同自定义事件

嘿,很高兴你已经在摸索Vue组件的事件处理啦!你目前用.native修饰符能实现功能,但确实直接让自定义组件触发自定义事件是更符合Vue组件设计思想的做法,不仅更灵活,还能让组件的API更清晰。下面我一步步教你怎么改造现有代码:

第一步:让自定义Button组件主动触发事件

我们需要在Button.vue里监听内部元素的点击,然后主动向外触发自定义事件,这样父组件就不用依赖.native了。

修改Button.vue的代码:

<template>
  <nuxt-link v-if="to" :to="to" :class="[ buttonCheck, buttonWidth ? 'w-' + buttonWidth : 'w-48', buttonStyles.container ]" @click="handleClick">
    <div class="text">
      <p :class="buttonStyles.paragraph">
        <slot></slot>
      </p>
    </div>
  </nuxt-link>
  <component v-else :is="setButtonType" :class="[ buttonCheck, buttonWidth ? 'w-' + buttonWidth : 'w-48', buttonStyles.container ]" @click="handleClick">
    <div class="text">
      <p :class="buttonStyles.paragraph">
        <slot></slot>
      </p>
    </div>
  </component>
</template>

<script>
import { Fragment } from "vue-fragment";
export default {
  props: {
    buttonType: {
      type: String,
      default: "a"
    },
    to: {
      type: String,
      default: ""
    },
    buttonColor: {
      type: String
    },
    buttonWidth: {
      type: String
    }
  },
  data() {
    return {
      setButtonType: this.buttonType,
    };
  },
  // 新增handleClick方法,触发自定义事件
  methods: {
    handleClick(event) {
      // 向外触发名为`click`的自定义事件,同时传递原生事件对象(可选)
      this.$emit('click', event);
    }
  }
};
</script>

第二步:在父组件(Line.vue)中监听自定义事件

现在Button组件会主动触发click事件,我们可以直接用@click监听,去掉.native修饰符:

修改Line.vue里的Button调用部分:

<Button buttonType="button" @click="emitRemove" buttonWidth="32" :class="['ml-3', hover === input.value ? 'opacity-100' : 'opacity-0']">
  Delete
</Button>
<!-- 下方Add按钮同理 -->
<Button buttonType="button" @click="emitAdd" buttonWidth="32" class="mt-3">
  Add
</Button>

进阶:让Button组件支持自定义事件名(可选)

如果你想让不同的Button触发不同名称的自定义事件(比如直接让Delete按钮触发remove,Add按钮触发add),可以给Button.vue加一个自定义prop来控制事件名:

Button.vue的props里新增:

props: {
  // 其他props...
  emitEvent: {
    type: String,
    default: 'click' // 默认触发click事件
  }
}

然后修改handleClick方法:

handleClick(event) {
  this.$emit(this.emitEvent, event);
}

之后在Line.vue里就可以指定事件名:

<!-- Delete按钮触发remove事件 -->
<Button buttonType="button" emit-event="remove" @remove="emitRemove" ...>
  Delete
</Button>
<!-- Add按钮触发add事件 -->
<Button buttonType="button" emit-event="add" @add="emitAdd" ...>
  Add
</Button>

为什么推荐这种方式?

  • .native是监听原生DOM事件,依赖组件内部的DOM结构,如果后续你修改了Button组件的内部元素(比如把<button>换成<div>),.native可能会失效;
  • 自定义事件让组件的API更明确,其他开发者使用时能清楚知道组件支持哪些事件,可读性更强;
  • 自定义事件可以传递自定义参数,比原生DOM事件更灵活。

内容的提问来源于stack exchange,提问作者The_Thinker

火山引擎 最新活动