从递归子组件更新父数据

时间:2018-12-18 09:59:35

标签: vue.js vuejs2 vue-component

为此,我将使用html和vuejs实现文件树视图,我有一个递归组件来实现具有多个根的文件树,如下所示: FieldWhatever 我要保存最新单击的项目,怎么办?

这是组件的相对代码:


Root 1
 - elemnt 1.1
 - elemnt 1.2
 - ...
Root 2
 - element 2.1
 - element 2.2

这是HTML

Vue.component('item', {
        template: `
        <li>
            <div @click='toggle(category)'>
                {{category.name}}

            <ul v-show="open" v-if="isFolder">
                <item v-for='category in category.children' :category='category'></item>
            </ul>
        </li>
        `,
        props: {
            category: Object
        },
        data(){
            return {
                open: false
            }
        },
        computed: {
            isFolder: function() {
                return this.category.children && this.category.children.length
            }
        },
        methods: {
            toggle(category){
                if (this.isFolder) {
                    this.open = !this.open
                }
            }
        }
    })

1 个答案:

答案 0 :(得分:0)

您遇到的问题是深度反应,VueJS文档提供了很好的解释:Reactiviy in Depth - How Changes Are Tracked

有几种触发组件渲染的方法。最明显的一个是this.$forceUpdate()。但是,它迫使任何组件都必须重新渲染,我不建议您使用它。如果在短时间内触发几次,它可能会变慢。

接下来的两个解决方案仅在没有其他组件的情况下进行了比较。

触发渲染的第一种方式:

<script>
export default {
    data: () => {
        return {
            treeData: []
        }
    },
    methods: {
        updateTree () {
            const treeData = JSON.parse(JSON.stringify(this.treeData))
            this.treeData = []
            this.$nextTick(function () => {
                this.treeData = treeData
            })
        }
    }
}
</script>

或者您可以简单地在父级上使用v-if并从子级中调用this.$emit('updateTree')

<template>
    <child-component @update="updateTree" :treeData="treeData" />
</template>

<script>
import ChildComponent from '../components/ChildComponent'
export default {
    data: () => {
        return {
            showTree: true,
            treeData: []
        }
    },
    components: { 'child-component' : ChildComponent },
    methods: {
        fetchAPIData () {
            // ... ajax
            this.treeData = apiResponse
        },
        updateTree () {
            this.showTree = false
            this.$nextTick(function () => {
                this.showTree = true
            })
        }
    },
    mounted () {
        this.fetchAPIData()
    }
}
</script>