javascript VueJS中v-on="...”语法是什么意思?

5tmbdcev  于 5个月前  发布在  Java
关注(0)|答案(1)|浏览(57)

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

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

字符串
我从VueJS文档中理解了scoped slot的目的和解构slot props的概念,但我不明白v-on="on"在这个例子中的含义。特别是当事件没有用v-on指令指定时,它意味着什么?
VueJS docs on v-on只显示了它与显式指定的事件名称(例如v-on:click="...")结合使用的情况,但没有解释仅将其用作v-on="..."
有人能解释一下这个语法和它在Vuetify示例中的用法吗?

jhdbpxl9

jhdbpxl91#

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函数而不是template:

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范围内。
最后,listeners作为VNodeComponentOptions传递,并由updateListeners更新。

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

当考虑到可以连接和扩展vue示例时,可以说服自己任何组件都可以简化为更原子的版本。
这就是vuetify通过创建activator mixinv-dialog组件中使用的内容。
现在我们可以追踪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
    },
}
}

有了上面的代码片段,剩下的就是将其实现到实际的组件中:

// 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)
  }
})

相关问题