【问题标题】:Why v-on doen't work on Vue component while using it in outer template?为什么 v-on 在外部模板中使用时对 Vue 组件不起作用?
【发布时间】:2018-11-07 23:16:43
【问题描述】:

情况

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

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

当使用按钮时,我希望将处理程序绑定到此按钮上的单击事件:

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

Pen with above code

问题

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

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

非prop属性是传递给组件的属性, 但没有定义相应的道具。

虽然明确定义的道具是传递信息的首选 对于子组件,组件库的作者不能总是 预见可能使用它们的组件的上下文。那是 为什么组件可以接受任意属性,这些属性被添加到 组件的根元素。

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

道具解决方案

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

对我来说,这个解决方案的问题是我对处理程序的声明方式没有细粒度的控制。如果在BaseButton 的一种用法中我想在@click 上使用呢? Vue.js 暴露的一些事件修饰符(例如.stop、.prevent、.capture)?我必须使用另一个道具(如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>

【问题讨论】:

    标签: vue.js vue-component


    【解决方案1】:

    v-on 指令在用于普通/原生 DOM 元素或 Vue 自定义元素组件时的行为不同,如 API 文档中所述:

    在普通元素上使用时,它只侦听原生 DOM 事件。在自定义元素组件上使用时,它会侦听该子组件上发出的自定义事件。

    在您的情况下,您将其应用于您的自定义 &lt;base-button&gt; 元素组件,因此它只会侦听自定义事件,即您在此组件实例上明确 $emit 的事件。

    来自底层&lt;button&gt; 的原生"click" 事件冒泡阶段不会触发您的@click 侦听器...

    ...除非您使用.native 修饰符:

    .native - 监听组件根元素的原生事件。

    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>

    【讨论】:

    • 谢谢!我没注意到那个:)。
    猜你喜欢
    • 1970-01-01
    • 2019-09-04
    • 2017-05-19
    • 1970-01-01
    • 2020-09-12
    • 2018-11-23
    • 2021-11-24
    • 2018-01-06
    • 2021-11-08
    相关资源
    最近更新 更多