[Vue] 关于数组值改变时视图不同步更新的问题

需求

        由循环生成的一组按钮,每个关联一个对话框,要求点击某一按钮时应弹出对应的对话框,代码片段如下:

<span v-for="(run, index) in runs" :key="index">
    <el-button type="text" @click="inputDialogVisible[index] = true">({{index}})</el-button>
        <el-dialog :visible.sync="inputDialogVisible[index]">
            <div slot="footer" class="dialog-footer">
                <el-button type="primary" @click="inputDialogVisible[index] = false">确 定</el-button>
            </div>
        </el-dialog>
</span>

<script>
import alignerApi from "@/api/corpus/aligner";

export default {
    data() {
        return {
            inputDialogVisible: [],
        };
    },
}
</script>

问题

        点击按钮时对话框未弹出,页面也没有更新。

解决

        查阅 Vue 官方文档“列表渲染”一节,找到“数组更新检测”部分:

变更方法

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

注意事项

由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。深入响应式原理中有相关的讨论。

        由此可见,Vue 只监视 inputDialogVisible 本身的改变,而忽略其内部对象的改变。

        在上述代码中, inputDialogVisible[index] = true 并没有改变 inputDialogVisible 本身,只是改变了数组内部的对象。由于没有调用变更方法,Vue 无法监测到变化而不会更新界面,导致对话框无法弹出。

        解决的方法是,将 inputDialogVisible[index] = true 这一逻辑由变更方法来实现,改为 inputDialogVisible.splice(index, 1, true)。

        注:包裹后的变更方法相当于执行了两步:第一步,调用原生方法;第二步,更新界面。

        变更后的代码片段如下:

<span v-for="(run, index) in runs" :key="index">
    <el-button type="text" @click="inputDialogVisible.splice(index, 1, true)">({{index}})</el-button>
        <el-dialog :visible.sync="inputDialogVisible[index]">
            <div slot="footer" class="dialog-footer">
                <el-button type="primary" @click="inputDialogVisible.splice(index, 1, false)">确 定</el-button>
            </div>
        </el-dialog>
</span>

<script>
import alignerApi from "@/api/corpus/aligner";

export default {
    data() {
        return {
            inputDialogVisible: [],
        };
    },
}
</script>

参考文献:

列表渲染 — Vue.js (vuejs.org)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值