Using Vue to implement tree view

This is the first article since learning to code

Using a simple tree view implementation, familiar with the recursive use of components

This is the simulated treemap data

let all={
        name:'all',
        children:{
            A:{
                name:'A',
                children:{
                    a1: {
                        name:'a1',
                        children:{
                            a11: {   
                                name:'a11',
                                children:null
                            },
                            a12:{   
                                name:'a12',
                                children:null
                            }
                        }
                    },
                    a2:{
                        name:'a2',
                        children:{
                            b21:{   
                                name:'b21',
                                children:null
                            }
                        }
                    }
                }
            },
           B:{
                name:'B',
                children:{
                    b1:{
                        name:'b1',
                        children:{
                            b11: {   
                                name:'b11',
                                children:null
                            },
                            b12:{   
                                name:'b12',
                                children:null
                            }
                        }
                    },
                    b2:{
                        name:'b2',
                        children:{
                            b21:{   
                                name:'b21',
                                children:null
                            }
                        }
                    }
                }
            }
        }
    }


code show as below

treelist.view

<template>
<div>
    <ul>
        <li   >
            <span @click="isshow()">{{treelist.name}}</span>
                <tree  v-for="item in treelist.children"   
                    v-if="isFolder"
                    v-show="open"
                    :treelist="item"
                    :keys="item"
                ></tree>
        </li>
    </ul>
</div>
  
</template>
<script>
export default {
    name:'tree',
    props:['treelist'],
    data(){
        return{
            open:false
        }
    },computed:{
        isFolder:function(){
            return this.treelist.children
         }
        }
    ,methods:{
        isshow(){
            if (this.isFolder) {
                this.open =!this.open
            }
        }
    }
}
</script>
<style lang="less">


</style>

index.html

<!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>Tree Map</title>
</head>
<body>
    <div id="app">
        <tree :treelist="treeList"></tree>
       
    </div>
</body>
</html>

index.js

import View from 'view';

import tree from '../components/treelist.vue'

let all={
        name:'all',
        children:{
            A:{
                name:'A',
                children:{
                    a1: {
                        name:'a1',
                        children:{
                            a11: {   
                                name:'a11',
                                children:null
                            },
                            a12:{   
                                name:'a12',
                                children:null
                            }
                        }
                    },
                    a2:{
                        name:'a2',
                        children:{
                            b21:{   
                                name:'b21',
                                children:null
                            }
                        }
                    }
                }
            },
           B:{
                name:'B',
                children:{
                    b1:{
                        name:'b1',
                        children:{
                            b11: {   
                                name:'b11',
                                children:null
                            },
                            b12:{   
                                name:'b12',
                                children:null
                            }
                        }
                    },
                    b2:{
                        name:'b2',
                        children:{
                            b21:{   
                                name:'b21',
                                children:null
                            }
                        }
                    }
                }
            }
        }
    }
    






const app=new View({
    el:"#app",
    components:{
        'tree':tree
    },
    data:{
        treeList:all
    }
})

After stepping on the pit, I found a similar case on the Vue official website, link →  Portal

After referring to the method on the official website, I tried to implement it


The difference between writing this way and the idea when I stepped on the pit is that such a component is only responsible for one object, traverses the objects in each children, and passes them into the components one by one for processing. My first attempt was to pass the entire children into itself. One component handles multiple objects, (the failure case of the first attempt, please see the bottom if you are interested)

What is the benefit of such a component handling an object write?

I can now customize the switch inside the component

I defined the variable open in data, because the components are recursive, so each component has its own open

Then why can't I use this method when I step on the pit for the first time, because my first attempt is that a component handles multiple objects, which is equivalent to a switch to control all objects in children. When the switch is turned on, it will cause this same All objects of the class are expanded


Traverse children and pass in the components themselves one by one Use v-show to control whether to display 




Defines a computed property to determine whether to continue execution based on children 



Bind a custom event on the span tag

Change the value of open 

<span @click="isshow()">{{treelist.name}}</span>

achieve effect





The following is the pit I stepped on when I first tried it

Record it here, and leave an impression when you encounter similar problems in the future

The first time I got this error


I have been looking for a problem for a long time, and found that it is because I forgot to write the name in the component. I must fill in the name when I use it myself, and it is consistent with the label name.


The initial implementation method uses component recursion to display the name of the current level, and passes all the objects in the children to itself and then performs the same operation until the children have no data. It is worth mentioning that if there is no data here If v-if is not added, it will become an infinite loop, and it will continue to be executed, so we need to judge whether the currently executed object has a next level.

Here my data has been slightly changed, so the first time I pass in the data is (index.html page)


Then I define an event to handle the closing and opening of each layer, and I use the popup to see if the value of Isopen has changed


Let's look at the results

刚进入页面时,括号中的undefined是 Isopen 当前的值,因为此时未被定义,所以为undefined


然后我点击了A


因为此时isopen已被反转值,所以此时isopen为true


但是页面仍毫无变化,不说展开功能,就连undefined也没变化



经过一番百度 ,发现原来是vue本身已经不允许这样直接更改 Props接受过来的值了

Vue2.0以后子组件不能更改父组件的值,只能通过子组件$emit(),父组件$on()进行响应更改

第一次写文章,语言描述能力还有欠缺,望大家见谅,哪里有不对的麻烦大家指出,这也是互相学习的过程,

希望大家如果遇到类似问题不要被困扰太久,

溜了溜了~

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326073111&siteId=291194637
Recommended