VueJs:在自定义组件上绑定“v-on”以替换现有组件

VueJs: bind `v-on` on a custom component to replace an existing one

为了简化我的页面样式,我想创建一堆迷你组件,并利用 VueJs 中属性的合并方式。例如,这里有一个最小的 js 文件也托管在这个 JSFiddle:

Vue.component('my-button', {
    template: '<button style="font-size:20pt;"><slot></slot></button>'
})

var app = new Vue({
    el: "#app",
  data: {
    message: "world",
  },
  methods: {
    sayHello: function () {
        alert("Hello");
    }
  }
})

然后在我的 html 中我只想使用 <my-button> 而不是 button:

<div id="app">
Hello {{message}} <my-button @click="sayHello" style="color:red;">Style works, but not click</my-button> <button v-on:click="sayHello" style="color:red;">Both works</button>
</div>

不幸的是,似乎合并了属性,但没有合并侦听器,所以这意味着我无法在我的新按钮上执行 v-on:click...有什么方法可以实现吗?

谢谢!

-- 编辑 -- 我看到了 Boussadjra Brahim 使用 .native 的提议,它起作用了,但后来我发现 this link 解释了为什么这不是一个很好的做法以及如何使用 v-on="$listeners" 将所有听众映射到一个特定的子按钮。但是,我尝试将模板更改为:

    template: `<button style="font-size:20pt;" v-on="$listeners"><slot></slot></button>`,

但我得到一个错误:

Vue warn: Property or method "$listeners" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option."

这里是 JSFiddle.

您的 fiddle 没有工作,因为您使用的是旧版本的 Vue,$listeners 是在 Vue 2.4.0 中添加的。

这是一个演示:

Vue.component('my-button', {
  template: '<button style="color: red" v-on="$listeners"><slot/></button>'
})

new Vue({
  el: '#app',
  methods: {
    sayHello() {
      alert('Hello')
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <my-button @click="sayHello">Custom Button</my-button>
  <button @click="sayHello">Ordinary Button</button>
</div>