为什么Vue transition不识别数组变更,除非重新初始化数组?
问题根因分析
- 数组引用复用问题:
const result = this.items没有创建新数组,只是将原items数组的内存地址赋值给了result,后续所有交换元素的操作本质都是直接修改原this.items数组的内部元素,未生成新的数组实例。 - Vue 2响应式限制:Vue 2无法自动侦测「通过索引直接修改数组元素」的操作,打乱数组时的元素交换逻辑属于索引修改,默认不会触发视图更新。
- 清空数组后生效的原因:先将
items赋值为空数组属于全量替换响应式属性,Vue可以侦测到这次变化;后续再把result赋值给items是第二次全量替换,哪怕result和原数组是同一个引用,两次赋值操作已经触发了视图重渲染,因此可以看到排序变化。
正确实现方案
不需要提前清空数组,只需在打乱前先拷贝原数组生成新的数组引用即可:
shuffle () { // 浅拷贝原数组,生成全新的数组实例 const result = [...this.items] let currentIndex = result.length let randomIndex while (currentIndex !== 0) { randomIndex = Math.floor(Math.random() * currentIndex) currentIndex-- // 交换新数组内的元素,不会影响原数组 [result[currentIndex], result[randomIndex]] = [ result[randomIndex], result[currentIndex] ] } // 全量替换为新数组,触发响应式更新 this.items = result }
补充说明
原有transition-group配置和key绑定逻辑没有问题,只要数组触发响应式更新,transition-group就会自动根据key的位置变化触发对应的FLIP过渡动画。
内容的提问来源于stack exchange,提问作者okinava
相关产品推荐
相关产品推荐

