如何在VUE中构造嵌套的反应数据

时间:2018-07-19 13:19:20

标签: vue.js vuejs2

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

显示该列表
<div v-for="item in items">
    <checkbox v-model="item.checked">
</div>

现在我的问题是关于选中的属性。当遍历未定义长度,未知键的列表时,似乎必须创建checked属性并将其附加到item对象,

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

1 个答案:

答案 0 :(得分:0)

  

默认情况下,计算属性是仅使用吸气剂的[...]

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>