Vue使用index时,模板v-if内变更未触发视图更新问题
问题原因
Vue 2 的响应式系统无法检测到通过索引直接修改数组元素的变化——这就是你点击"show more"后控制台值已改变,但模板却没更新的核心原因。Vue 2 对数组的响应式监听仅覆盖了push、pop、splice等变异方法,直接索引赋值不在监听范围内。
修复方案
有两种简单的修复方式,任选其一即可:
方案一:使用this.$set触发响应式更新
通过Vue提供的$set方法修改数组元素,手动通知Vue更新视图:
修改后的完整代码
<template> <main> <div class="card" v-for="(item, index) in items" :key="index"> <div class="content"> <h3 class="card-title">{{item.name}} </h3> <p v-if="showMoreText[index]">{{ item.description }}</p> <p v-else>{{ item.description.substring(0, 100) }}...<span class="link" @click="showMore(index)">show more</span></p> </div> </div> </main> </template> <script> export default { data() { return { showMoreText: [] } }, props: { items: Array, }, created() { for (let i = 0; i < this.items.length; i++) { // 初始化时也用$set,确保响应式 this.$set(this.showMoreText, i, false); } }, methods: { showMore(index) { this.$set(this.showMoreText, index, !this.showMoreText[index]) } }, } </script>
方案二:改用对象存储展开状态
把showMoreText从数组改成对象,用索引作为键,Vue 2 能正常检测对象属性的修改:
修改后的完整代码
<template> <main> <div class="card" v-for="(item, index) in items" :key="index"> <div class="content"> <h3 class="card-title">{{item.name}} </h3> <p v-if="showMoreText[index]">{{ item.description }}</p> <p v-else>{{ item.description.substring(0, 100) }}...<span class="link" @click="showMore(index)">show more</span></p> </div> </div> </main> </template> <script> export default { data() { return { showMoreText: {} } }, props: { items: Array, }, created() { for (let i = 0; i < this.items.length; i++) { this.showMoreText[i] = false; } }, methods: { showMore(index) { this.showMoreText[index] = !this.showMoreText[index] } }, } </script>
内容的提问来源于stack exchange,提问作者Mads
相关产品推荐
相关产品推荐

