Vue组件使用口才模型,而不在更新时更新视图

时间:2019-03-19 11:13:24

标签: vue.js

我有一个Vue组件,该组件执行aJax调用并循环浏览页面。首先,它显示根页面,然后检查每个根是否有任何子代,如果这样,它将使用子代数据创建组件的另一个实例,然后对此进行同样的操作。

因此,它基本上是一个递归菜单。但是,我添加了一些管理控件来显示软删除的页面,当我单击此按钮时,我会再次获取包含软删除的记录的页面。

但是我的视图没有更新,页面数据是一个对象,所以显然我使用this.$set()是由于Vue内部的反应性。

谁能看到我的问题?

<template>

    <div>
        <div class="documentation__navigation--loading" v-if="loading">
            Loading...
        </div>
        <div class="documentation__navigation__admin" v-if="root">
            <label for="showDeleted" class="documentation__navigation__admin--deleted">
                Show Deleted
                <input type="checkbox" id="showDeleted" v-model="showDeleted">
            </label>
        </div>
        <ul class="menu-list">
            <draggable v-model="pages">
                <transition-group name="fade">
                    <li v-for="page in pages" v-if="page.display" :key="page.id">
                        <i :class="[{ active: page.expanded }, expandedIcon(page.expanded)]" v-if="nodes[page.id]" @click="page.expanded = !page.expanded"></i><a :class="{ current: page.current, deleted: page.deleted_at != '' }" :href="'/docs/' + page.link">{{ page.title }} <i :class="page.icon"></i></a>

                        <transition name="fade">
                            <tree-menu v-if="page.expanded && nodes[page.id]" :root="false" :data="nodes" :page-id="page.id" :key="'sub'+page.id" :pass-editable="editable" :current="page.link"></tree-menu>
                        </transition>
                    </li>
                </transition-group>
            </draggable>
            <li v-if="editable" class="add-new"><a :href="[ '/docs/add', current ].filter(Boolean).join('/')">Add New <i class="far fa-plus-circle"></i></a></li>
        </ul>
    </div>

</template>
<script>

    import Axios from 'axios';
    import draggable from 'vuedraggable';

    export default {
        components: {
            draggable
        },
        props: {
            data: {},
            ajax: {},
            token: {},
            pageId: {},
            current: {},
            root: {
                default: true,
                type: Boolean
            },
            passEditable: {
                default: false,
                type: Boolean
            },
            expandIcon: {
                default: 'fal fa-plus-square',
                type: String
            },
            collapseIcon: {
                default: 'fas fa-minus-square',
                type: String
            }
        },
        data() {
            return {
                nodes: {},
                pages: {},
                editable: this.passEditable,
                showDeleted: false,
                loading: false
            }
        },
        created() {
            if (!this.data) {
                this.getPages();
            }
            else {
                this.$set(this, 'pages', this.data[this.pageId]);
                this.$set(this, 'nodes', this.data);
            }
        },
        methods: {
            getPages: function() {
                const self = this;
                Axios.get(this.ajax, {
                    params: {
                        '_token': this.token,
                        'current': this.current,
                        'showDeleted': this.showDeleted
                    }
                })
                .then(function(response) {
                    self.$set(self, 'nodes', response.data);
                    self.$set(self, 'pages', response.data.root);
                    self.$set(self, 'editable', response.data.editable);
                });
            },
            expandedIcon: function(value) {
                if (value) {
                    return this.collapseIcon;
                }
                return this.expandIcon;
            }
        },
        watch: {
            showDeleted: function() {
                this.getPages();
            }
        }
    }
</script>

一些示例数据:

{
  "1": [
    {
      "id": 2,
      "title": "Video Frame",
      "content": "",
      "link": "web-vue\/video-frame",
      "name": "video-frame",
      "icon": "fas fa-file-video",
      "order": 0,
      "display": 1,
      "parent_id": 1,
      "expanded": 0,
      "updated_at": "2019-03-13 12:55:03",
      "created_at": null,
      "deleted_at": null
    },
    {
      "id": 4,
      "title": "Favourites",
      "content": "",
      "link": "web-vue\/favourites",
      "name": "favourites",
      "icon": "fas fa-heart",
      "order": 1,
      "display": 1,
      "parent_id": 1,
      "expanded": 1,
      "updated_at": null,
      "created_at": null,
      "deleted_at": null
    }
  ],
  "5": [
    {
      "id": 6,
      "title": "Favourites",
      "content": "",
      "link": "web-feature-favourites",
      "name": "web-feature-favourites",
      "icon": "fas fa-heart",
      "order": 0,
      "display": 1,
      "parent_id": 5,
      "expanded": 0,
      "updated_at": null,
      "created_at": null,
      "deleted_at": null
    }
  ],
  "4": [
    {
      "id": 7,
      "title": "Panel",
      "content": "",
      "link": "web-vue\/favourites\/favourites-panel",
      "name": "favourites-panel",
      "icon": "",
      "order": 1,
      "display": 1,
      "parent_id": 4,
      "expanded": 1,
      "updated_at": null,
      "created_at": null,
      "deleted_at": null,
      "current": true
    }
  ],
  "0": [
    {
      "id": 17,
      "title": "Job",
      "content": "dsadasfasfas",
      "link": "web-vue\/favourites\/test",
      "name": null,
      "icon": "fas fa-file-video",
      "order": 2,
      "display": 1,
      "parent_id": 0,
      "expanded": 0,
      "updated_at": "2019-03-19 10:10:36",
      "created_at": "2019-03-19 09:29:42",
      "deleted_at": "2019-03-19 10:10:36"
    }
  ],
  "root": [
    {
      "id": 3,
      "title": "Home",
      "content": "",
      "link": "web-home",
      "name": "web-home",
      "icon": "",
      "order": 0,
      "display": 1,
      "parent_id": null,
      "expanded": 0,
      "updated_at": null,
      "created_at": null,
      "deleted_at": null
    },
    {
      "id": 1,
      "title": "Vue Components",
      "content": "",
      "link": "web-vue",
      "name": "web-vue",
      "icon": "fab fa-vuejs",
      "order": 1,
      "display": 1,
      "parent_id": null,
      "expanded": 1,
      "updated_at": null,
      "created_at": null,
      "deleted_at": null
    },
    {
      "id": 5,
      "title": "Features",
      "content": "",
      "link": "web-features-home",
      "name": "web-features-home",
      "icon": "",
      "order": 2,
      "display": 1,
      "parent_id": null,
      "expanded": 0,
      "updated_at": null,
      "created_at": null,
      "deleted_at": null
    }
  ],
  "editable": true
}

编辑

只是做了更多测试,似乎第一个Component实例正在看到此更新,是子组件没有看到此更新,我的印象是,如果我的父组件获取了更新的数据,它将重新呈现子组件,然后将更新的数据当然传递给他们?

0 个答案:

没有答案