gpt4 book ai didi

javascript - Vue 组件回收导致 watch 意外起火

转载 作者:行者123 更新时间:2023-12-03 02:20:52 24 4
gpt4 key购买 nike

我正在为 vue 创建一个可重用的复选框组件,并且遇到了一个由 vue 回收未使用组件引起的有趣问题。

通过一个例子可以更好地看出这一点:

Vue.component("checkbox", {
template: `
<div>
<slot></slot>:
<input type="checkbox" v-model="checked" v-on:change="updateVModel"/>
<span>changed!</span>
</div>
`,
props: {
value: {
type: Boolean,
required: true
}
},
data(){
return {checked: this.value};
},
watch: {
value(val){
this.changeAnimation();
this.checked = val;
}
},
methods: {
changeAnimation(){
let $span = this.$el.querySelector("span");
$span.classList.remove("animate");
setTimeout(() => $span.classList.add("animate"), 50);
},
updateVModel(){
this.changeAnimation();//this line is redundant since watch.value runs anyway
this.$emit("input", this.checked);
}
}
});

new Vue({
el: "#menu",
data: {
menu: 0,
checked0: true,
checked1: false
}
});
span{
transition: 1s;
opacity: 0;
}
span.animate{
animation: notice-me .3s ease-in-out 4 alternate
}


@keyframes notice-me{
0%{
opacity: 0;
}
100%{
opacity: 1;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<div id="menu">
<div v-if="menu == 0">
<button v-on:click="menu = 1">Go to menu 1</button>
<h3>Menu 0</h3>
<checkbox v-model="checked0">checked0</checkbox>
<checkbox v-model="checked0">checked0</checkbox>
</div>
<div v-else>
<button v-on:click="menu = 0">Go to menu 0</button>
<h3>Menu 1</h3>
<checkbox v-model="checked1">checked1</checkbox>
<checkbox v-model="checked1">checked1</checkbox>
</div>
</div>

每当值发生变化时,无论是来自用户单击(使用 v-on:click )还是变量本身发生变化(使用 watch.value ),我都会这样制作我的组件,即“更改!”在复选框旁边闪烁几次。一切工作正常,但是当我们使用“更改为菜单”按钮更改菜单并且checked0和checked1是不同的值时,问题就出现了。 “changed”会闪烁,尽管它不应该闪烁。

这显然是由 vue 回收组件并将它们用于另一个变量引起的。由于变量的值与旧的不同,watch.value运行,在我们期望它不会发生时触发动画。

我做了一些研究,发现我可以给出所有不同的复选框 vue keys像这样:<checkbox v-model="checked1" key="thing1">checked1</checkbox> ,但我想优雅地解决这个问题并允许 vue 回收它想要的任何东西。应该有一种方法来检测值是否因实际发生变化或由于回收而发生变化。

所以我的问题是如何解决这个问题,或者如何以不同的方式编写代码来避免它?

最佳答案

一个key实际上应该与条件渲染(通过 v-for 或 v-if)单元相关联。它应该与该单元的任何独特之处绑定(bind)在一起。对于您的情况,您可以使用 menu:

  <div v-if="menu == 0" :key="menu">
<button v-on:click="menu = 1">Go to menu 1</button>
<h3>Menu 0</h3>
<checkbox v-model="checked0">checked0</checkbox>
<checkbox v-model="checked0">checked0</checkbox>
</div>
<div v-else :key="menu">
<button v-on:click="menu = 0">Go to menu 0</button>
<h3>Menu 1</h3>
<checkbox v-model="checked1">checked1</checkbox>
<checkbox v-model="checked1">checked1</checkbox>
</div>

关于javascript - Vue 组件回收导致 watch 意外起火,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49163924/

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