首页 > 解决方案 > 如何在 VUE 中构建嵌套的响应式数据

问题描述

我认为这是一个相当普遍的问题。您从 api 获取列表,然后通过显示该列表

<div v-for="item in items">
    <checkbox v-model="item.checked">
</div>

现在我的问题是关于检查的属性。当迭代一个未定义长度、未知键的列表时,似乎必须创建已检查的属性并将其附加到项目对象,就像这样

computed: {
    items () {
        var newList = Object.assign([], this.rootList) // shallow clone the api list
        for (var i of newList) {
            i.checked = false
            // or
            Vue.set(i, 'checked', false)
        }
        return newList
    }

然而,这并没有使我的复选框反应。但更重要的是,这种向 rootList 对象克隆添加新属性的方式,这是最佳实践吗?如果是这样,为什么这不是反应性的?即使使用 Vue.set

标签: vue.jsvuejs2

解决方案


计算属性默认情况下只有 getter [...]

https://vuejs.org/v2/guide/computed.html#Computed-Setter

由于现代 JavaScript 的限制(以及 Object.observe 的废弃),Vue 无法检测到属性的添加或删除。由于 Vue 在实例初始化期间执行 getter/setter 转换过程,因此数据对象中必须存在一个属性,以便 Vue 对其进行转换并使其成为响应式

https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

这可能会有所帮助:https ://jsfiddle.net/eywraw8t/187063/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <div v-for="item in items">
            <input type="checkbox" v-model="item.checked"> {{ item.name }}
        </div>

        <button @click="fetch">Fetch more items</button>
    </div>              

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
        new Vue({
            el: "#app",

            data: {
                items: []
            },

            methods: {
                fetch() {
                    let itemsFromApiResponse = [
                        { name: "Test 1" },
                        { name: "Test 2" },
                        { name: "Test 3" },
                    ];

                itemsFromApiResponse.forEach(item => this.items.push(Object.assign({ checked: false }, item)));
                }
            }
        })
    </script>
</body>
</html>

推荐阅读