【问题标题】:VueJS v-if = array[index] is not workingVueJS v-if = array[index] 不工作
【发布时间】:2023-03-06 11:46:02
【问题描述】:

我想制作一个当鼠标悬停在图像上时获取文本框的组件。

下面是 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 没有更新。我们不能将 array[index] 用于 v-if 还是有其他原因?

【问题讨论】:

  • 您是否反对在每个 item 上使用布尔值而不是单独的 show 数组?

标签: vue.js vuejs2


【解决方案1】:

问题不在于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,则可以使用扩展运算符轻松克隆数组:

this.show[index] = !this.show[index]
this.show = [...this.show]

.map 也可以工作,因为它返回一个新数组

this.show = this.show.map((el, i) =>
  i === index ? !el : el
)

【讨论】:

  • 这很简洁,我仍在查看您列出的其他解决方案,但是.. vue.set 不起作用。 -- 示例:jsfiddle.net/qnq2munr/1
  • @robertotomás 您使用的是 Vue 1.0,模板语法存在一些差异。开发过程中也不要使用缩小的js,否则看不到错误信息。
  • 我遇到了同样的问题,这真的很有用。非常感谢;)
  • 在 switch 部分和 created 中的初始化都使用 Vue.set 确实有效。
  • 其实上面是不正确的。我只需要更改初始化以使用 Vue.set,而不是 changeStatus 函数(或者在我的情况下是 seeMe 函数)
【解决方案2】:

您可以使用 JS object 而不是 array 并获得相同的效果。换句话说,将show: [false, false, false], 替换为show: {0:false, 1:false, 2:false},。

【讨论】:

  • 非常感谢,我已经断断续续地处理了这个问题 6 个月,这对我来说立竿见影并立即奏效,谢谢。
  • 这里不起作用,即使使用这种对象方法 =(
【解决方案3】:

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

this.$set(this.show, index, !this.show[index])

【讨论】:

    猜你喜欢
    • 2018-01-07
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 2021-02-21
    • 2021-11-25
    • 1970-01-01
    • 2020-11-15
    • 2019-01-03
    相关资源
    最近更新 更多