为什么不能使用v-on速记来绑定“ on”?

时间:2019-10-10 13:16:03

标签: vue.js

文档say

<a @click="doSomething"> ... </a>

的简写
<a v-on:click="doSomething"> ... </a>

为什么在所有情况下都无法使用此简写?例如,

<v-dialog v-model="dialog" width="500">
  <template v-slot:activator="{ on }">
    <v-btn dark v-on="on">Working button</v-btn>
    <v-spacer />          
    <v-btn dark @on="on">Non-working button</v-btn>
  </template>
  <v-card>
    <v-card-title>Some Dialog</v-card-title>
      <v-card-text>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
     </v-card-text>
  </v-card>
</v-dialog>

“工作按钮”有效,但“非工作按钮”无效。似乎v-on速记仅适用于事件。但是,如果这是真的,我还没有看到它的记录。

在此示例中,我使用的是Vuetify,但我的问题是关于Vue.js的。

以下是以上的CodePen:https://codepen.io/keeganwitt/pen/bGGVeZY

2 个答案:

答案 0 :(得分:3)

v-on:click的缩写是@click而不是@on

,因此您可以使用@click代替v-on="on"。但是,此处slotProp on是具有click(函数)属性的对象。所以您可以像下面一样使用它

<v-btn dark @click="on.click">Now working button</v-btn>

但是建议使用v-on="on",因为on对象下可能有多个属性

例如:如果on{ click: fn(), mouseup: fn() }

<v-btn dark @click="on.click" @mouseup="on.mouseup" >Now working button</v-btn>
<!-- same as -->
<v-btn dark v-on="on">Now working button</v-btn>

答案 1 :(得分:1)

因此,您的示例中的@onv-on:on的简写,这意味着事件处理程序正在侦听子组件以发出on事件。 v-btn组件永远不会发出on事件,因此什么也没有发生。

这不是您要问的重点,但是从技术上讲,您可以使用v-on速记绑定到on事件:

Vue.config.devtools = false;
Vue.config.productionTip = false;

Vue.component('toggle', {
  template: `
    <button @click="onClick"> 
      {{ isOn ? 'On' : 'Off' }}
    </button>
  `,
  data() {
    return {
      isOn: false
    };
  },
  methods: {
    onClick() {
      this.isOn = !this.isOn;
    
      if (this.isOn) {
        this.$emit('on');
      } else {
        this.$emit('off');
      }
    }
  }
});

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

<div id="app">
  <toggle @on="alert('on')" @off="alert('off')"/>
</div>


我认为让您感到困惑的是v-on="on"语法。从代码中看不出来,但是在这种情况下将on变量设置为v-on的值不是函数,而是对象。

From the vue docs on v-on

  

从2.4.0+开始,v-on还支持绑定到不带参数的事件/侦听器对对象。请注意,使用对象语法时,它不支持任何修饰符。

因此,on变量在这种情况下可能看起来像这样:

{ click: onClick, mouseover: onMouseover }

以这种方式传递所有事件侦听器可以减少样板代码。在v2.4之前,您需要执行以下操作:

<template v-slot:activator="{ onClick, onMouseover }">
  <v-btn 
    dark 
    @click="onClick" 
    @mouseover="onMouseover"
  > 
    Working button
  </v-btn>
</template>