gpt4 book ai didi

vue.js - 有条件地将事件监听器和处理程序附加到 Vue 组件

转载 作者:行者123 更新时间:2023-12-05 02:49:04 24 4
gpt4 key购买 nike

我有一个 Vue 组件,它在我的应用程序中的多个地方使用。在其中一些情况下,我需要处理具有特定功能的点击事件,例如:

<div @click="checkNav" />

但是,我只想在需要时附加此处理程序,因此它不会在不需要时不必要地触发。

我试过将 prop 传递给组件并有条件地附加处理程序,如下所示:

<div @click="isCheckNeeded ? checkNav : null" />

然后在 props 中,我指定了:

isCheckNeeded {
type: Boolean,
required: false,
default: false,
}

但是,我的 checkNav 函数从未触发,我已经仔细检查了 isCheckNeeded 在 Vue devtools 中是否为真。

这种条件检查是不可能的,还是不推荐的?有没有更好的方法来有条件地附加事件监听器/处理程序?

最佳答案

查看模板的编译方式可能有助于理解问题的原因...

v-on接收一个方法名称,vue-template-compiler将其编译为方法查找,其中已解析的方法成为事件处理程序 [1] .例如,您的模板 <div @click="checkNav" />被编译成这个渲染函数:

with (this) {
return _c("div", { on: { click: checkNav } })
}

另一方面,inline event handler , <div @click="isCheckNeeded ? checkNav : null" />编译成这样:

with (this) {
return _c("div", {
on: {
click: function ($event) {
isCheckNeeded ? checkNav : null
},
},
})
}

注意这里的几件事:

  1. 表达式被包裹在一个匿名函数中,成为事件处理程序。
  2. 表达式的结果是方法名称(与方法调用相对)或null .评估方法名称实际上是空操作。

方案一:将方法名改为方法调用

这可能是最简单的解决方案,但它的缺点是总是在单击时调用处理程序(尽管虚假的 isCheckNeeded 会导致提前返回)。

<!-- BEFORE: -->
<!--
<div @click="isCheckNeeded ? checkNav : null" />
-->

<!-- AFTER: -->
<div @click="isCheckNeeded ? checkNav() : null" />

<!-- OR: -->
<div @click="isCheckNeeded && checkNav()" />

方案二:使用动态事件

这稍微复杂一些,但它的优点是只在必要时才注册事件处理程序。 isCheckNeeded 时,事件处理程序自动注销是假的。

<div @[clickEvent]="checkNav" />
...
<script>
export default {
computed: {
clickEvent() {
return this.isCheckNeeded ? 'click' : null
}
},
}
</script>

Vue.component('my-component', {
template: `<div @[clickEvent]="checkNav"><slot/></div>`,
props: {
isCheckNeeded: Boolean
},
computed: {
clickEvent() {
return this.isCheckNeeded ? 'click' : null
}
},
methods: {
checkNav() {
console.log('checkNav')
}
}
})

new Vue({
el: '#app',
data() {
return {
isCheckNeeded: false
}
}
})
.click-area {
border: solid 1px;
padding: 2rem;
margin: 1rem;
}
<script src="https://unpkg.com/vue@2.6.12"></script>

<div id="app">
<button @click="isCheckNeeded = !isCheckNeeded">Toggle click handler</button>
<pre>isCheckNeeded={{isCheckNeeded}}</pre>

<my-component :is-check-needed="isCheckNeeded">
<div class="click-area">
<span v-if="isCheckNeeded">Click me!</span>
<span v-else>Clicking ignored</span>
</div>
</my-component>
</div>

关于vue.js - 有条件地将事件监听器和处理程序附加到 Vue 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64175845/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com