基本用法
<!-- object syntax (2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>]
所以基本上@click="..." 等于v-on:click="..." 等于v-on="{click:...}"
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)
}
})