正如 Chris Fritz(Vue.js Core Team Emeriti)在VueCONF US 2019中提到的
如果我们让 Kia 进入.native,然后基本输入的根元素突然从输入变成了标签,这个组件就坏了,这并不明显,事实上,除非你有一个非常好的测试,否则你甚至可能不会马上发现它。相反,通过避免使用我目前认为将在 Vue 3 中删除的反模式.native修饰符,您将能够明确定义父级可能关心将哪些元素侦听器添加到...
使用 Vue 2
使用$listeners:
因此,如果您使用 Vue 2,解决此问题的更好选择是使用完全透明的包装器逻辑。为此,Vue 提供了一个$listeners属性,其中包含在组件上使用的侦听器对象。例如:
{
  focus: function (event) { /* ... */ }
  input: function (value) { /* ... */ },
}
然后我们只需要添加v-on="$listeners"到test组件中,例如:
Test.vue(子组件)
<template>
  <div v-on="$listeners">
    click here
  </div>
</template>
现在该<test>组件是一个完全透明的包装器,这意味着它可以像普通<div>元素一样使用:所有侦听器都可以工作,无需.native修饰符。
演示:
Vue.component('test', {
  template: `
    <div class="child" v-on="$listeners">
      Click here
    </div>`
})
new Vue({
  el: "#myApp",
  data: {},
  methods: {
    testFunction: function(event) {
      console.log('test clicked')
    }
  }
})
div.child{border:5px dotted orange; padding:20px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="myApp">
  <test @click="testFunction"></test>
</div>
 
 
我们也可以$emit为此使用方法,这有助于我们监听父组件中的子组件事件。为此,我们首先需要从子组件发出一个自定义事件,例如:
Test.vue(子组件)
<test @click="$emit('my-event')"></test>
重要提示:事件名称始终使用 kebab-case。有关这一点的更多信息和演示,请查看这个答案:VueJS将计算值从组件传递到父级。
现在,我们只需要在父组件中监听这个发出的自定义事件,例如:
应用程序
<test @my-event="testFunction"></test>
因此,基本上我们将简单地使用或代替v-on:click或 简写。@clickv-on:my-event@my-event
演示:
Vue.component('test', {
  template: `
    <div class="child" @click="$emit('my-event')">
      Click here
    </div>`
})
new Vue({
  el: "#myApp",
  data: {},
  methods: {
    testFunction: function(event) {
      console.log('test clicked')
    }
  }
})
div.child{border:5px dotted orange; padding:20px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="myApp">
  <test @my-event="testFunction"></test>
</div>
 
 
使用 Vue 3
使用v-bind="$attrs":
Vue 3 将在很多方面让我们的生活变得更轻松。它的一个例子是,它将帮助我们创建一个更简单的透明包装器,只需使用v-bind="$attrs". 通过在子组件上使用它,我们的侦听器不仅可以直接从父组件工作,而且任何其他属性也可以像正常一样工作<div>。
所以,关于这个问题,我们不需要在 Vue 3 中更新任何东西,你的代码仍然可以正常工作,就像<div>这里的根元素一样,它会自动监听所有子事件。
演示 #1:
const { createApp } = Vue;
const Test = {
  template: `
    <div class="child">
      Click here
    </div>`
};
const App = {
  components: { Test },
  setup() {
    const testFunction = event => {
      console.log("test clicked");
    };
    return { testFunction };
  }
};
createApp(App).mount("#myApp");
div.child{border:5px dotted orange; padding:20px;}
<script src="//unpkg.com/vue@next"></script>
<div id="myApp">
  <test v-on:click="testFunction"></test>
</div>
 
 
但是对于具有嵌套元素的复杂组件,我们需要将属性和事件应用于 main<input />而不是父标签,我们可以简单地使用v-bind="$attrs"
演示 #2:
const { createApp } = Vue;
const BaseInput = {
  props: ['label', 'value'],
  template: `
    <label>
      {{ label }}
      <input v-bind="$attrs">
    </label>`
};
const App = {
  components: { BaseInput },
  setup() {
    const search = event => {
      console.clear();
      console.log("Searching...", event.target.value);
    };
    return { search };
  }
};
createApp(App).mount("#myApp");
input{padding:8px;}
<script src="//unpkg.com/vue@next"></script>
<div id="myApp">
  <base-input 
    label="Search: "
    placeholder="Search"
    @keyup="search">
  </base-input><br/>
</div>