vue.js - 为什么 v-on 在外部模板中使用 Vue 组件时不起作用?

标签 vue.js vue-component

情况

假设我有一个组件 BaseButton这只是一个围绕 <button> 的简单包装器元素:

Vue.component('base-button', {
  template: `
    <button>
      <slot />
    </button>
  `
});

使用按钮时,我想将处理程序绑定(bind)到此按钮上的单击事件:

<base-button @click="handler">
  Click me
</base-button>

Pen with above code

问题

上述解决方案不起作用。处理程序根本不会被触发。

谁能解释一下为什么?我猜处理程序在被组件模板替换之前绑定(bind)到元素,但这只是一个猜测——我在 vue.js 文档中找不到任何关于它的信息。除此之外 docs 状态:

A non-prop attribute is an attribute that is passed to a component, but does not have a corresponding prop defined.

While explicitly defined props are preferred for passing information to a child component, authors of component libraries can’t always foresee the contexts in which their components might be used. That’s why components can accept arbitrary attributes, which are added to the component’s root element.

@click ( v-on:click ) 在我看来是一个非 Prop 属性,根据上面的文字应该得到继承。但事实并非如此。

Prop 解决方案

我知道我可以声明一个 prop 并在组件内部传递处理程序(下面的代码)。然后它按预期工作。

对我来说,此解决方案的问题是我无法精细控制处理程序的声明方式。如果一次使用 BaseButton 会怎样?我想在 @click 上使用 Vue.js 公开的一些事件修饰符(例如 .stop.prevent.capture )?我必须使用另一个 Prop (如 capture )并使用 v-if ,但它会使组件模板变得非常困惑。如果我将处理程序留在模板中,在我使用它的地方,我可以根据需要以干净灵活的方式修改事件声明。

Vue.component('base-button', {
  prop: {
    clickHandler: {
      type: Function,
      required: true
    }
  },
  template: `
    <button>
      <slot />
    </button>
  `
});

<base-button :click-handler="handler">
  Click me
</base-button>

最佳答案

v-on 指令在普通/ native DOM 元素或 Vue 自定义元素组件上使用时表现不同,如 API 文档中所述:

When used on a normal element, it listens to native DOM events only. When used on a custom element component, it listens to custom events emitted on that child component.

在您的情况下,您将它应用于您的自定义 <base-button> element 组件,因此它只会监听自定义事件,即您明确 $emit 的事件在此组件实例上。

native "click"底层事件的冒泡阶段 <button>不会触发你的 @click听众……

…除非你使用 .native修饰符:

.native - listen for a native event on the root element of component.

Vue.component('base-button', {
  template: `
    <button>
      <slot />
    </button>
  `
});

new Vue({
  el: '#app',
  data: {
    handler(event) {
      console.log('submit from where the component was used');
      //console.log(event);
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>

<div id="app">
  <base-button @click.native="handler">
    Click
  </base-button>
</div>

关于vue.js - 为什么 v-on 在外部模板中使用 Vue 组件时不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50581999/

相关文章:

vue.js - vue-router — 未捕获( promise )错误 : Redirected from "/login" to "/" via a navigation guard

javascript - 如何修复GTM中的 "This language feature is only supported for ECMASCRIPT6 mode"?

vue.js - 从脚本标签内的方法关闭 v-edit-dialog

javascript - 如何在对话框工具栏 Vuetifyjs + Vuejs 下截取抽屉导航

vue.js - Vuex 存储状态在控制台中未定义,但 Vue 工具显示工作正常

laravel - @apply 在 Laravel Mix 中的 Vue 组件中不起作用

vue.js - 如何在 Vue 中将 v-model 与功能模板组件一起使用?

javascript - Vue Js : How to separate 'methods' , 'data' , 'computed' 等..在单独的js文件中

vue.js - 如何使用vue-router在vuejs中创建一个404组件

vue.js - 错误 : Undefined variable in VueJS