I use vue to write Tree, using data to dynamically add child nodes, why does the page rendering not respond? It feels like there is a vue pit where everyone will be hit.

clipboard.png

Click the plus sign, the page does not respond, there is no change. Why?

the vue debugger shows that my children property has been inserted into the value, but the page is not rendered.

There is data in the

code, so you can run locally.

call page

<template>
    <div>
        <div class="grid-content ">
            <ul id="stuTree" class="yunTreeBox">
                  <yunTree  :menuArray = "stuResource"></yunTree>
          </ul>
        </div>
    </div>
</template>

<script>
    import yunTree from "./yunTree.vue"
    export default {
        data() {
            return {
                stuResource:[]
            };
        },
        mounted: function () {
            var self = this;
            setTimeout(function(){
       
                var stuArray= [{"resourceDesc":"    ","resourceId":101,"resourceParentId":-1,"resourceName":"","resourceUrl":""},{"resourceId":1,"resourceName":"","resourceUrl":"/main/blackboardWriting","resourceDesc":"--","resourceParentId":101,"resourceSort":1,"resourceType":1,"resourceProductId":1,"createDate":1526623438000,"updateDate":1526623440000,"selected":0,"resourceIcon":null,"resourceBeen":null},{"resourceId":2,"resourceName":"","resourceUrl":"/main/kezhongce","resourceDesc":"--","resourceParentId":101,"resourceSort":2,"resourceType":1,"resourceProductId":1,"createDate":1526623438000,"updateDate":1526623440000,"selected":0,"resourceIcon":null,"resourceBeen":null},{"resourceId":3,"resourceName":"","resourceUrl":"/main/demoShow","resourceDesc":"--","resourceParentId":101,"resourceSort":3,"resourceType":1,"resourceProductId":1,"createDate":1526623438000,"updateDate":1526623440000,"selected":0,"resourceIcon":null,"resourceBeen":null},{"resourceId":4,"resourceName":"","resourceUrl":"/main/tutoring","resourceDesc":"--","resourceParentId":101,"resourceSort":4,"resourceType":1,"resourceProductId":1,"createDate":1526623438000,"updateDate":1526623440000,"selected":0,"resourceIcon":null,"resourceBeen":null},{"resourceId":5,"resourceName":"","resourceUrl":"/main/subjectTest","resourceDesc":"--","resourceParentId":101,"resourceSort":5,"resourceType":1,"resourceProductId":1,"createDate":1526623438000,"updateDate":1526623440000,"selected":0,"resourceIcon":null,"resourceBeen":null},{"resourceId":6,"resourceName":"","resourceUrl":"/main/errorRecord","resourceDesc":"--","resourceParentId":101,"resourceSort":6,"resourceType":1,"resourceProductId":1,"createDate":1526623438000,"updateDate":1526623440000,"selected":0,"resourceIcon":null,"resourceBeen":null},{"resourceId":7,"resourceName":"","resourceUrl":"","resourceDesc":"--","resourceParentId":101,"resourceSort":7,"resourceType":1,"resourceProductId":1,"createDate":1526623438000,"updateDate":1526623440000,"selected":0,"resourceIcon":null,"resourceBeen":null},{"resourceId":8,"resourceName":"","resourceUrl":"/main/favourite","resourceDesc":"---","resourceParentId":7,"resourceSort":8,"resourceType":1,"resourceProductId":1,"createDate":1526623438000,"updateDate":1526623440000,"selected":0,"resourceIcon":null,"resourceBeen":null},{"resourceId":9,"resourceName":"","resourceUrl":"/main/schoolInfo","resourceDesc":"---","resourceParentId":7,"resourceSort":9,"resourceType":1,"resourceProductId":1,"createDate":1526623438000,"updateDate":1526623440000,"selected":0,"resourceIcon":null,"resourceBeen":null},{"resourceId":10,"resourceName":"","resourceUrl":"/main/peopleSet","resourceDesc":"---","resourceParentId":7,"resourceSort":10,"resourceType":1,"resourceProductId":1,"createDate":1526623438000,"updateDate":1526623440000,"selected":0,"resourceIcon":null,"resourceBeen":null}]

              self.stuResource = stuArray;
              
            },3000)
        },
        computed: {
        },
        methods:{
        },
        components: {
            yunTree
        }
    };

</script>

<style>
</style>

parent component of the tree
yunTree.vue

<template>
    <ul>
      <treeRecusive v-if="rootData" :itemData="rootData">
      </treeRecusive>
    </ul>
</template>
<script>
    import treeRecusive from "./treeRecursive.vue"
    export default {
        name:"yunTree",
        data() {
            return {
                rootData:null
            };
        },
        props: {
            menuArray: Array
        },
        watch:{
            menuArray(arry){
                this.assembleData(arry)
            }
        },
        computed: {
        },
        methods:{
            assembleData(menuArray){
                menuArray.forEach(function(item1,index){
                    item1.createTime = new Date().getTime();
                    menuArray.forEach(function(item2,index){
                        if(item1.resourceId==item2.resourceParentId){
                          if(item1.children){
                            item1.children.push(item2)
                          }else{
                            item1.children =[item2]
                          }
                        }
                    })
                })
                this.rootData = menuArray[0]||null;
            }
        },
        created(){
            this.assembleData(this.menuArray)
        },
        components: {
            treeRecusive
        }
    };

</script>
The subcomponents of the

tree recursively call
treeRecursive.vue

<template>
  <li>
    <div :class="{bold: isFolder}" @click="toggle" @dblclick="changeType">
      <span v-if="isFolder">[{{ open ? "-" : "+" }}]</span>
      {{ itemData.resourceName }}
    </div>
    <ul v-show="open" v-if="isFolder">
      <treeRecusive class="item" v-for="(itemData, index) in itemData.children" :key="itemData.createTime" :itemData="itemData">
      </treeRecusive>
      <li class="add" @click="addChild">+</li>
    </ul>
  </li>
</template>
<script>

export default {
  name:"treeRecusive",
  props: {
    itemData: Object
  },
  data() {
    return {
      open: false
    };
  },
  computed: {
    isFolder: function() {
      return this.itemData.children &&
        this.itemData.children.length
    }
  },
  methods: {
    toggle: function() {
      if (this.isFolder) {
        this.open = !this.open
      }
    },
    changeType: function() {
      if (!this.isFolder) {
        Vue.set(this.itemData, "children", [])
        this.addChild()
        this.open = true
      }
    },
    addChild: function() {
      this.itemData.children.push({
            resourceDesc:"",
            resourceId:"",
            resourceParentId:this.itemData.resourceId,
            resourceName:"",
            resourceUrl:"",
            createTime:new Date().getTime()
          })
    }
  },
  components: {}
};

</script>

props is


which forbids dynamic passing of values.

1. Props value is assigned to the child component's own properties
2.watch props change
3. Change your data attribute
so that the component dom will change
the sub-component code has been changed

<script>
export default {
  name: 'treeRecusive',
  props: {
    itemData: Object
  },
  data() {
    return {
      open: false,
      node: this.itemData
    }
  },
  computed: {
    isFolder: function() {
      return this.node.children && this.node.children.length
    }
  },
  methods: {
    toggle: function() {
      if (this.isFolder) {
        this.open = !this.open
      }
    },
    changeType: function() {
      if (!this.isFolder) {
        Vue.set(this.node, 'children', [])
        this.addChild()
        this.open = true
      }
    },
    addChild: function() {
      console.log('come here')
      this.node.children.push({
        resourceDesc: '',
        resourceId: '',
        resourceParentId: this.node.resourceId,
        resourceName: '',
        resourceUrl: '',
        createTime: new Date().getTime()
      })
    }
  },
  components: {},
  watch: {
    itemData: {
      handler: function(val, oldVal) {
        console.log('come here watch', val)
        this.node = val
      },
      deep: true
    }
  }
}
</script>

clipboard.png


clipboard.png

Is it really good to put ul, in

ul?


has been plagued by this problem for a long time


has encountered this problem before, you lazy load to introduce components to try

MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1bdfb6e-314aa.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1bdfb6e-314aa.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?