将现有应用程序从 Vue2 移植到 Vue3 时,我遇到了一个令人惊讶的问题。
如何让 Vue3 监视“外部”数组的变化?
这在 Vue2 中工作得很好,但在 Vue3 中停止工作:
<ul id="list">
<li v-for="t in dataArray"> {{t}} </li>
</ul>
<script>
var numbers = [1,2,3]; //this is my external array
var app = Vue.createApp({
data() { return { dataArray : numbers } } //bind Vue to my external array
}).mount("#list");
numbers.push(4); //UI not updating, but worked fine in Vue2
</script>
我知道我可以调用
app.dataArray.push
来代替,或者调用 $forceUpdate
等,但是有没有办法强制 Vue 简单地监视现有数组?
我想更广泛的问题是:如何将 Vue3 绑定到任意纯 JS 对象?该对象可能太复杂而无法重写,或者可能来自我无法控制的外部 API。这在 Vue2 或 Angular 中是微不足道的(与任何普通对象的双向绑定,无论它是否是实例/组件的一部分)
附注这看起来像是 Vue3 中的一个巨大的突破性变化,但根本没有在任何地方提到过。
更新:
根据@Dimava 的回答,看起来修复上述代码最不痛苦的方法是:
var numbers = [1,2,3]; //my external array that came from API
numbers = Vue.shallowReactive(numbers); //convert to a reactive proxy
你需要制作你的数组
Reactive
1
import { reactive, ref } from 'vue'
const numbers = [1,2,3];
const reactiveNumbers = reactive(numbers)
reactiveNumbers.push(4)
// or, if you will need to reassign the whole array
const numbersRef = ref(numbers)
numbersRef.value.push(4)
numbersRef.value = [3, 2, 1]
// or, in the old style, if you are old
const data = reactive({
numbers: [1, 2, 3]
})
data.numbers.push(4)
data.numbers = [3, 2, 1]
¹(或
ShallowReactive
,如果它包含许多出于性能原因不应响应的大对象)