Vue实战:树形组件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/b954960630/article/details/87931368

一、展示

在这里插入图片描述
点击粗体能展开节点:
在这里插入图片描述
在这里插入图片描述
点击“+” ,还能插入new stuff节点:
在这里插入图片描述
还能为没有孩子的节点添加多个子节点,如图为 hello节点添加:
在这里插入图片描述


二、源码

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>Document</title>
    <link rel="stylesheet" href="./Vuetest.css">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
</head>
<body>
    <script type="text/x-template" id="item-template">
        <li>
            <div :class="{bold: isFolder}" @click="toggle">
                {{ model.name }}
                <span v-if="isFolder">{{ isOpen ? '-' : '+'}}</span>
            </div>
            <ul v-if="isOpen && isFolder">
                <item v-for="(item, index) in model.children"
                    :model="item"
                    :key="index"
                />
                <li class="add" @click="handleAddClick">+</li>
            </ul>
        </li>
    </script>
    
    <p>(You can double click on an item to turn it into a folder.)</p>

    <ul id="app">
        <item :model="treeData"/>
    </ul>
    
    <script>
        let data = {
            name: 'My Tree',
            children: [
                { name: 'hello' },
                { name: 'wat' },
                {   
                    name: 'child folder',
                    children: [
                        {
                            name: 'child folder',
                            children: [
                                { name: 'hello' },
                                { name: 'wat' }
                            ]
                        },
                        { name: 'hello' },
                        { name: 'wat' },
                        {
                            name: 'child folder',
                            children: [
                                { name: 'hello' },
                                { name: 'wat' }
                            ]
                        }
                    ]
                }
            ]
        }
        
        Vue.component('item', {
            template: '#item-template',
            props: ['model'],
            data() {
                return {
                    isOpen: false
                };
            },
            computed: {
                isFolder() {
                    let getChild = this.model.children;
                    return getChild && getChild.length;
                }
            },
            methods: {
                toggle() {
                    if(this.isFolder) {
                        this.isOpen = !this.isOpen;
                    }else {
                        Vue.set(this.model, 'children', []);
                        this.model.children.push({name: 'new stuff'});
                        this.open = true;
                    }
                },
                handleAddClick() {
                    this.model.children.push({
                        name: 'new stuff'
                    });
                },
            },
        });

        let vm = new Vue({
            el: '#app',
            data: {
                treeData: data
            }
        })
    </script>
</body>
</html>
./Vuetest.css
body {
  font-family: Menlo, Consolas, monospace;
  color: #444;
}
.item {
  cursor: pointer;
}
.bold {
  font-weight: bold;
}
ul {
  padding-left: 1em;
  line-height: 1.5em;
  list-style-type: dot;
}

猜你喜欢

转载自blog.csdn.net/b954960630/article/details/87931368