“外部”数组的 Vue3 反应性

Ale*_*lex 2 vue.js vuejs3

在将现有应用程序从 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>
Run Code Online (Sandbox Code Playgroud)

我知道我可以调用app.dataArray.push,或者调用$forceUpdate等,但是有没有办法强制 Vue 简单地监视现有数组?

我想更广泛的问题是:如何将 Vue3 绑定到任意纯 JS 对象?该对象可能太复杂而无法重写,或者可能来自我无法控制的外部 API。这在 Vue2 或 Angular 中很简单(与任何普通对象的双向绑定,无论它是否是实例/组件的一部分)

PS 这看起来像是 Vue3 中的一个巨大的突破性变化,但在任何地方都没有提到。

更新:

根据 @Dimava 的回答,看起来修复上述代码最不痛苦的方法是:

var numbers = [1,2,3]; //this is my external array
numbers = Vue.shallowReactive(numbers); //convert to a reactive proxy
Run Code Online (Sandbox Code Playgroud)

Dim*_*ava 6

您需要使数组Reactive\xc2\xb9

\n
import { reactive, ref } from 'vue'   \nconst numbers = [1,2,3];\nconst reactiveNumbers = reactive(numbers)\nreactiveNumbers.push(4)\n\n// or, if you will need to reassign the whole array\nconst numbersRef = ref(numbers)\nnumbersRef.value.push(4)\nnumbersRef.value = [3, 2, 1]\n\n// or, in the old style, if you are old\nconst data = reactive({\n  numbers: [1, 2, 3]\n})\ndata.numbers.push(4)\ndata.numbers = [3, 2, 1]\n
Run Code Online (Sandbox Code Playgroud)\n

\xc2\xb9 (或者ShallowReactive如果它包含许多大对象,出于性能原因不应做出反应)

\n