首页 > 解决方案 > 使用带有对象的嵌套数组时,以编程方式检查复选框不会呈现更改

问题描述

се我有一个包含类别的数组。每个类别都有孩子。

当父母被选中/取消选中时,它的孩子也必须被选中/取消选中。如果检查了所有子级,则还必须检查父级。

Vue 按预期更新字段,但不会重新渲染。我不明白为什么。

这是我的代码:

<template>
    <div class="card">
            <div class="card-body">
                    <ul class="list-tree">
                        <li v-for="category in categories" :key="category.id" v-show="category.show">
                            <div class="custom-control custom-checkbox">
                                <input :id="'category-' + category.id"
                                             v-model="category.checked"
                                             @change="checkParent(category)"
                                             type="checkbox"
                                             class="custom-control-input" />
                                <label class="custom-control-label"
                                             :for="'category-' + category.id">
                                    {{ category.name }}
                                </label>
                            </div>
                            <ul>
                                <li v-for="child in category.children" :key="child.id" v-show="child.show">
                                    <div class="custom-control custom-checkbox">
                                        <input :id="'category-' + child.id"
                                                     v-model="child.checked"
                                                     @change="checkChild(child, category)"
                                                     type="checkbox"
                                                     class="custom-control-input" />
                                        <label class="custom-control-label" :for="'category-' + child.id">
                                            {{ child.name }}
                                            <small class="counter">({{ child.products_count }})</small>
                                        </label>
                                    </div>
                                </li>
                            </ul>
                        </li>
                    </ul>
                </div>
    </div>
</template>

export default {

    data () {
        return {
            categories: [],
            listItemTemplate: { show: true, markedText: null, checked: false }
        }
    },

    methods: {

        checkParent (category) {
            category.children.forEach(child => {
                child.checked = category.checked
            })
        },            

        initializeCategories () {
            this.categories = []

            this.originalCategories.forEach(originalCategory => {
                var parent = this.copyObject(originalCategory)

                this.categories.push(parent)

                parent.children.forEach (child => {
                    child = this.copyObject(child)
                })
            })
        },

        copyObject (category) {
           return Object.assign(category,   {...this.listItemTemplate})
        }
    },

    computed: {
        ...mapState({
             originalCategories: state => state.categories,
        })

     },

     mounted () {
        this.initializeCategories()
     }

}

标签: vue.jsvuejs2

解决方案


您需要扩大范围,因为您仅在checkParent()方法内更改它,您正在更改的变量不会影响组件变量。

在类别迭代中使用索引而不是值来找到正确的类别,然后在整个组件的范围内应用更改:

<li v-for="(category, categoryIndex) in categories" :key="category.id" v-show="category.show">
     <div class="custom-control custom-checkbox">
                                    <input :id="'category-' + category.id"
                                                 v-model="category.checked"
                                                 @change="checkParent(categoryIndex)"
                                                 type="checkbox"
                                                 class="custom-control-input" />
                                    <label class="custom-control-label"
                                                 :for="'category-' + category.id">

                                    {{ category.name }}     
                     </label>
              </div> <!-- the rest of the code ... -->

然后在组件的方法中:

methods: {

    checkParent (categoryIndex) {
       let categoryChecked = this.categories[categoryIndex];
        this.categories[categoryIndex].children.forEach((child, childIndex) => {
            this.categories[categoryIndex].children[childIndex].checked = categoryChecked;
        })
    },     

推荐阅读