v-on="..." 语法在 VueJS 中是啥意思?

Posted

技术标签:

【中文标题】v-on="..." 语法在 VueJS 中是啥意思?【英文标题】:What does v-on="..." syntax mean in VueJS?v-on="..." 语法在 VueJS 中是什么意思? 【发布时间】:2019-12-22 17:56:09 【问题描述】:

我遇到了一个 v-dialog component 的 Vuetify 示例,它的作用域插槽称为 activator,定义如下:

  <template v-slot:activator=" on ">
    <v-btn
      color="red lighten-2"
      dark
      v-on="on"
    >
      Click Me
    </v-btn>
  </template>

我了解scoped slots from VueJS docs 的用途和destructuring slot props 的概念,但我不明白此示例中v-on="on" 的含义。特别是当事件没有用v-on 指令指定时意味着什么?

VueJS docs on v-on 仅显示其与明确指定的事件名称(例如v-on:click="...")结合使用,但没有说明仅将其用作v-on="..."

有人可以在 Vuetify 示例中解释这种语法及其用法吗?

【问题讨论】:

vuejs.org/v2/api/#v-on : @Estradiaz 请将其发布为答案 @adiga 这就是答案。但是,OP 要求解释它在上述示例中的使用方式,其中on 未在激活器中以外的任何地方定义,并在v-on 中使用。 @briosheje on 可能是该组件的data 的属性? (顺便说一句,对 vue 不太熟悉) @adiga 我也不熟悉,但我认为文档的简单链接实际上并没有帮助,因为如果你看一下这个例子,仍然不清楚“on”是如何工作的那个上下文。 【参考方案1】:

TLDR:

基本用法

<!-- object syntax (2.4.0+) --> 
<button v-on=" mousedown: doThis, mouseup: doThat "></button>]

所以基本上@click="..." 等于v-on:click="..." 等于v-on="click:..."


TLDR:

vuetify 实现:

genActivator () 
      const node = getSlot(this, 'activator', Object.assign(this.getValueProxy(), 
        on: this.genActivatorListeners(),
        attrs: this.genActivatorAttributes(),
      )) || []

      this.activatorNode = node

      return node
    

一些见解:


如果您想抽象组件并一次传递多个侦听器而不是编写多行赋值,这很有用。


考虑一个组件:

export default 

  data() 
    return 
      on: 
        click: console.log,
        contextmenu: console.log
      ,
      value: "any key value pair"
    
  

<template>
  <div>
    <slot name="activator" :on="on" :otherSlotPropName="value" >
      <defaultComponent v-on="on" />
    </slot>
  </div>
</template>

鉴于上面的组件,您可以访问插槽属性并将它们传递给您的自定义组件:

<ExampleComponent>
  <template v-slot:activator=" on, otherSlotPropName ">
    <v-btn
      color="red lighten-2"
      dark
      v-on="on"
    >
      Click Me
    </v-btn>
  </template>
 <ExampleComponent />

在纯 javascript 中更容易看到它:

比较上面的组件 - 使用 render function 而不是模板:

export default 

  data() 
    return 
      on: 
        click: console.log,
        contextmenu: console.log
      ,
      value: "any key value pair"
    
  ,
  render(h)

    return h('div', [
      this.$scopedSlots.activator &&
      this.$scopedSlots.activator(
        on: this.on,
        otherSlotPropName: this.value
      )
      || h('defaultComponent', 
        listeners: this.on
      
    ]
  


在源码中:

如果v-on="eventsObject" 为空白,则将调用方法bindObjectListener,从而将事件分配给data.on

这发生在createComponent scope。

最后listeners 被传递为VNodeComponentOptions 并由updateListeners 更新。


Vue 扩展的地方 - 检查了 Vuetify 实现:

当考虑到可以加入和扩展 vue 实例时,可以说服自己任何组件都可以简化为更原子的版本。

这就是 vuetify 在例如v-dialog 组件通过创建一个activator mixin

目前可以追踪activatable挂载的on的内容:

const simplyfiedActivable = 

  mounted()
    this.activatorElement = this.getActivator()
  ,
  watch
    activatorElement()
      // if is el?
      this.addActivatorEvents()
    
  ,
  methods: 
    addActivatorEvents()
      this.listeners = this.genActivatorListeners()
    ,
    genActivatorListeners()
      return 
        click: ...,
        mouseenter: ...,
        mouseleave: ...,
      
    ,
genActivator () 
      const node = getSlot(this, 'activator', Object.assign(this.getValueProxy(), 
        on: this.genActivatorListeners(),
        attrs: this.genActivatorAttributes(),
      )) || []

      this.activatorNode = node

      return node
    ,
  

有了上面的 sn-p,剩下的就是将它实现到实际的组件中:

// vuetify usage/implemention of mixins 
const baseMixins = mixins(
  Activatable,
  ...other
)

const sympliefiedDialog = baseMixins.extend(
  ...options,
  render(h)
    
    const children = []
    children.push(this.genActivator())
    return h(root, ...options, children)
  
)

【讨论】:

我还是不明白:/

以上是关于v-on="..." 语法在 VueJS 中是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

vue.js 事件绑定

vue记录

vue教程1-04 事件 v-on:click="函数"

vuejs v-on="click"为啥会刷新页面

Vue:基础语法、创建组件、组件间传值、实例生命周期

vue中的事件监听机制