Vue2中数组仅初始化时渲染?点击打乱后页面不更新问题
问题分析与解决方案
问题根源
页面不更新的核心原因有两个:
- 数组引用未变更:你的
shuffle函数是原地修改原数组,返回的还是同一个数组对象。Vue2的响应式系统无法检测到这种"同一引用下的内部元素顺序变化",它仅监听数组的引用变更和特定数组方法(如push/splice等)的调用。 - key值不合理:使用
index作为:key会导致Vue复用DOM元素。数组顺序打乱后,每个位置的index仍为0、1、2...,Vue会判定元素未发生变化,不会重新渲染对应内容。
修复方案
1. 修改shuffle函数,返回新数组
通过复制原数组生成副本再进行打乱操作,返回全新的数组引用,让Vue能感知到变化:
shuffle(a) { // 复制原数组生成新数组,避免原地修改 const arr = [...a]; let j, x, i; for (i = arr.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); x = arr[i]; arr[i] = arr[j]; arr[j] = x; } return arr; }
2. 替换合理的key值
你的数组元素是唯一的(A/B/C/D/E),直接用元素值作为key,确保Vue能正确识别元素变化:
<div class="flex flex-grow " v-for="(item,index) in selected11" :key="item" > {{ item }} {{ index }} </div>
可选临时方案(不推荐):强制触发更新
如果不想修改shuffle函数,可在操作后手动强制Vue更新DOM:
random(){ this.shuffle(this.selected11); this.$forceUpdate(); // 强制更新视图 }
这种方式跳过了Vue的响应式系统,仅作为临时补救,不建议长期使用。
修复后完整代码
<template> <div> <div @click="random()" > random </div> {{ selected11.length }} <div class="flex flex-grow " v-for="(item,index) in selected11" :key="item" > {{ item }} {{ index }} </div> </div> </template> <script> export default { name: 'Choice', data() { return { selected11:[], } }, created() { this.selected11 = ['A', 'B', 'C', 'D','E']; }, methods: { random(){ this.selected11 = this.shuffle( this.selected11 ); }, shuffle(a) { const arr = [...a]; let j, x, i; for (i = arr.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); x = arr[i]; arr[i] = arr[j]; arr[j] = x; } return arr; } } } </script>
内容的提问来源于stack exchange,提问作者user824624
相关产品推荐
相关产品推荐

