vue------多层列表嵌套【树结构】

子组件:

<template>
    <li class="tree-node">
        <h3 class="tree-node-name">{{data.name}}</h3>
        // 点击展示或隐藏
        <span class="drop-down" :class="{'drop-down-turn':!isShow}" @click="clickToggle"></span>
        <ul  v-for="(item,index) in data.children" :key="index" class="tree-item" v-if="isShow">
            <tree-node  v-if="item.children" :data="item" @click-item="clickItem"></tree-node>
            // 最里面一层数据可以选中,单独设置样式
             <li v-if="item.children"  @click="clickItem(item)">
            	<span :class="{'check-item': !item.children, 'active': item.checked}"></span>
            </li>
        </ul>
    </li>
</template>
export default {
    name:'tree-node',
    components: {},
    props: {
        data: {
            type: Object,
            default() {
                return {};
            }
        }
    },
    data() {
        return {
            // 是否显示
            isShow: true
        };
    },
    methods: {
        // 点击条目
        clickItem(item) {
            this.$emit('click-item', item);
        },
        // 切换显示与隐藏
        clickToggle() {
            this.isShow = !this.isShow;
        }
    }
};

父组件:

<div v-for="(item,index) in dataList" :key="index">
    <treeNode :data="item" @click-item="clickItem"></treeNode>
</div>
methods: {
        // 点击条目
        clickItem(item) {
            item.checked = !item.checked;
        }
}

20220218修改:
子组件:

<template>
    <li class="fd-tree-node">
        <h3  @click="clickItem(data)">{{data.name}}</h3>
        <ul v-for="(item,index) in data.children" :key="index">
            <tree-node v-if="item.children"
                       :class="{'no-children-item':!item.children.length, 'active': item.checked}"
                       :data="item" @click-item="clickItem(item,index)"></tree-node>
        </ul>
    </li>
</template>
export default {
    name:'tree-node',
    components: {},
    props: {
        data: {
            type: Object,
            default() {
                return {};
            }
        }
    },
    methods: {
        // 点击条目
        clickItem(item) {
            this.$emit('click-item', item);
        }
    }
};

父组件:

<div v-for="(item,index) in dataList" :key="index" >
     <treeNode :data="item" @click-item="clickItem"></treeNode>
</div>
		// 获取树的数据
        getTreeData() {
            this.requestGetTreeList()
                .then((data) => {
                    this.dataList = data.data;
                    this.operateData(this.dataList);
                });
        },
        // 处理数据
        operateData(data) {
            const _dataList = JSON.parse(JSON.stringify(data));
            //  循环真实数据
            _dataList.forEach((item) => {
                // 递归数据
                this.singleRecusion(item, null);
            });
            // 所有数据列表
            this.dataList = _dataList;
        },
        // 递归数据
        singleRecusion(item, itemP) {
            // 父节点id
            item.pId = itemP ? itemP.id : '-1';
            // 父节点名称
            item.pName = itemP ? itemP.name : '';
            // id 索引集合
            item.ids = itemP ? `${itemP.ids}>${item.id}` : item.id;
            // 循环子集
            if (Array.isArray(item.children) && item.children.length > 0) {
                //  子集循环
                item.children.forEach((itemC) => {
                    // 增加checked字段
                    itemC.checked = false;
                    // 递归
                    this.singleRecusion(itemC, item);
                });
            } else {
                item.children = [];
            }
            if (item.children.length === 0) {
                // 转成一维数组
                this.oneDimensionalDataList.push(item);
            }
        },
		// 点击条目
        clickItem(item) {
            item.checked = !item.checked;
            // 已选中
            if (item.checked) {
                this.checkedList.push(item);
            } else {
                // 未选中
                const _index = this.checkedList.findIndex((val) => val.name === item.name);
                this.checkedList.splice(_index, 1);
            }
        },
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值