VueJS v-if = array [index]无法正常工作

我想制作一个组件,当鼠标悬停在图像上方时,该组件会显示文本框。

以下是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不会更新。我们不能对v-if使用array [index]还是有其他原因?

十三小哥2020/03/19 14:43:22

您可以使用JS 对象而不是数组来获得相同的效果。换句话说,替换show: [false, false, false],show: {0:false, 1:false, 2:false},

乐米亚2020/03/19 14:43:22

在方法的组件中,可以使用:

this.$set(this.show, index, !this.show[index])
神奇老丝2020/03/19 14:43:22

问题不关乎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
)