我正在尝试学习Vue.js并且来到一个练习示例,我需要实现一个自定义指令,这个指针可以解决虱子'v-on'。 这意味着我需要在自定义指令上捕获click事件并调用方法。
我想到的模板。
<template>
<h1 v-my-on:click="alertMe">Click</h1>
</template>
问题是我不知道如何捕获自定义指令中的click事件。请原谅以下笨拙的代码。
<script>
export default {
methods: {
alertMe() {
alert('The Alert!');
}
},
directives: {
'my-on': {
bind(el, binding, vnode) {
console.log('bind');
el.addEventListener('click',()=>{
console.log('bind');
vnode.context.$emit('click');
});
},
}
}
}
</script>
任何人都可以帮我理解这是如何运作的吗?我没有找到任何类似的例子。
答案 0 :(得分:4)
经过一番搜索,我找到了这个解决方案:
<template>
<h1 v-my-on:click="alertMe">Click me!</h1>
</template>
<script>
export default {
methods: {
alertMe() {
alert('The Alert!');
}
},
directives: {
'my-on': {
bind(el, binding) {
let type = binding.arg;
let myFunction = binding.value;
el.addEventListener(type, myFunction);
}
}
}
}
</script>
答案 1 :(得分:2)
据我所知,您找到的解决方案是您所寻找的最佳解决方案。但是,对于那些对Vue.JS不太了解的人,我想我会给出一个简短的解释。我还建议您查看Custom Directives或我的Medium article有关概念的官方Vue文档。
这是弗拉德(Vlad)来的代码,我会支持:
<template>
<h1 v-my-on:click="alertMe">Click me!</h1>
</template>
<script>
export default {
methods: {
alertMe() {
alert('The Alert!');
}
},
directives: {
'my-on': {
bind(el, binding) {
let type = binding.arg;
let myFunction = binding.value;
el.addEventListener(type, myFunction);
}
}
}
}
</script>
简而言之,基于指令对象定义,Vue指令在其所附加元素的生命周期中被调用。在示例中,定义的函数称为“绑定”,因此,当元素绑定到DOM中时,伪指令将调用该函数。
此函数接收其附加到“ el”的元素以及模板“绑定”中指令用法的不同内容。在模板的绑定用法中,冒号“:”后的值为“ arg”,在此示例中为字符串文字“ click”。引号“””内的值是“值”,在这种情况下是对函数“ alertMe”的对象引用。
然后,通过获取binding.arg和binding.value(及其各自的内容)定义的vars可用于创建事件侦听器,该事件侦听器包含在使用该指令的元素“ el”内部(el可修改) )。因此,在创建和绑定元素时,将在“ arg”定义的“ click”事件上创建此新的事件侦听器,它将调用由“ value”定义的“ alertMe”函数。
由于修改内容包含在元素中,因此您不必担心清理未绑定的情况,因为在破坏元素时,监听器也会被破坏。
这是对建议代码中发生的情况的基本描述。要查看有关指令及其用法的更多信息,请遵循建议的链接。希望有帮助!
答案 2 :(得分:1)
您需要为指令中发出的事件注册一个侦听器。
// emit a custom event
// binding.expression is alertMe
vnode.context.$emit(binding.expression);
// listen for the event
export default {
created(){
this.$on('alertMe', event => {
this.alertMe()
})
},
....
}
这不是调用方法alertMe
,而是将alertMe
作为绑定表达式传递给指令:
<h1 v-my-on:click="alertMe">Click</h1>
答案 3 :(得分:1)
@Vlad有一个很好的解决方案!
我还想补充一点:如果您想将参数传递给回调,它将以Vue处理表达式的方式使您感到困惑。简而言之,对于自定义指令,对引号之间的所有内容进行求值并传递结果值(因此,您可以通过binding.value(duh!)获得它,而对于内置指令,至少对于v-on ,当事件被触发时,引号之间的内容将在以后进行评估。
也许最好通过在自定义指令和内置v-on指令之间进行比较来证明这一点。假设您有一个与@Vlad完全一样的“ my-on”指令,并且与v-on一起使用:
内置:
<h1 v-on:click="myAlert('haha')"> Click me!</h1>
它可以按预期工作,当单击按钮时,会弹出警报窗口。
自定义:
<h1 v-my-on:click="myAlert('haha')">Click me!</h1>
一旦显示按钮,就会弹出警报窗口,当您单击它时,将触发该事件,但是没有可见的事件发生。这是因为“ myAlert('haha')”会在绑定(?)时立即求值,因此会进入警报窗口,并且其值将传递给您的指令(未定义或其他内容),因为其值不是函数,似乎没有任何作用即将发生。 现在,解决方法是使引号之间的任何内容在求值时都返回一个函数,例如v-my-on:click =“()=> {myAlert('haha')}”
希望有帮助。
参考:
答案 4 :(得分:0)
正如@Vlad所说的那样对我有用:
el.addEventListener('click',()=>{
console.log('bind');
vnode.context.$emit('click');
这是我的指令:
Vue.directive('showMenu', {
bind: function (el, binding, vnode) {
el.addEventListener('click', () => {
console.log('bind')
setTimeout(() => {
this.$emit('toggleDrawer')
}, 1000)
})
}
})
谢谢伙计!