当鼠标悬停在图像上时,我想制作一个获取文本框的组件。
下面是HTML模板。
<section class="item-container" v-for="(item, index) in items">
<div class="image-box" @mouseenter="changeStatus(index)">
<img class="image" src="item.link" alt>
</div>
<div class="text-box" @mouseleave="changeStatus(index)" v-if="show[index]">
<h4>{{ item.name }}</h4>
<p>{{ item.content }}</p>
</div>
</section>
以下是app.js
new Vue({
el: '#app',
data: {
show: [false, false, false],
items: [
{
name: 'Author 1',
content: 'Content 1'
},
{
name: 'Author 2',
content: 'Content 2'
},
{
name: 'Author 3',
content: 'Content 3'
}
]
},
methods: {
changeStatus: function(index) {
this.show[index] = !this.show[index];
console.log(this.show);
console.log(this.show[index]); // console gets it as expected
}
}
});
当我执行上面的代码时,我发现show属性已经改变。但是,v-if未更新。我们不能将数组[index]用于v-if或者还有其他原因吗?
答案 0 :(得分:23)
问题不在于v-if
,这是因为Vue无法直接检测到数组元素的变化,这是JavaScript的限制之一。
因此,Vue为此提供了一些辅助函数,如Vue.set
更改此this.show[index] = !this.show[index]
到Vue.set(this.show, index, !this.show[index])
然后它应该工作。
Vue.set
不是唯一的解决方案,有几种方法可以实现这一点,以防您可能想知道。
您可以使用JavaScript数组的本机方法,Vue将挂钩这些方法,以便检测更改。
以下是.splice
this.show.splice(index, 1, !this.show[index])
另一种方法是完全替换阵列。如果您使用的是ES6,则可以使用spread运算符轻松克隆阵列:
this.show[index] = !this.show[index]
this.show = [...this.show]
.map
也可以,因为它会返回一个新数组
this.show = this.show.map((el, i) =>
i === index ? !el : el
)
答案 1 :(得分:1)
您可以使用JS 对象而不是数组并获得相同的效果。换句话说,将show: [false, false, false],
替换为show: {0:false, 1:false, 2:false},
。
答案 2 :(得分:1)
可以使用的方法中的组件:
this.$set(this.show, index, !this.show[index])