0
点赞
收藏
分享

微信扫一扫

移动端tree组件父子组件联动。

生态人 2024-10-09 阅读 24

 

<!--
 * @Author: yeminglong
 * @Date: 2024-09-27 10:14:30
 * @LastEditors: yeminglong
 * @LastEditTime: 2024-09-27 16:49:05
 * @Description:
 -->
<script>
import TreeItem from '@/views/test/TreeItem.vue'

export default {
	name: 'TreeList',
	components: { TreeItem },
	props: {
		data: Array,
		props: {
			label: 'name',
			children: 'children'
		},
		nodeKey: String
	},
	provide: {
		// 当前选中的节点
		currentNode: {
			data: null
		}
	},
	watch: {
		data: {
			handler(data) {
				const { props } = this
				const treeList = []
				const deep = (list = [], parent = null) => {
					for (const item of list) {
						const node = {
							checked: false,
							isHalf: false,
							data: item,
							children: []
						}
						if (!parent) {
							treeList.push(node)
						} else {
							parent.children.push(node)
						}

						if (
							item[props.children] &&
							item[props.children].length
						) {
							deep(item.children, node)
						}
					}
				}

				deep(data, null)
				this.treeList = treeList
			},
			deep: true,
			immediate: true
		}
	},
	data() {
		return {
			treeList: []
		}
	},
	methods: {
		change({ checked }) {
			const children = this?.children ?? []
			const count = children.filter(v => v.checked).length
			if (!checked && count > 0) {
				return false
			}
			this.checked = checked
		}
	}
}
</script>

<template>
	<div>
		<div
			class="root-item"
			v-for="(item, index) in treeList"
			:key="`children-${(nodeKey && item.data[nodeKey]) || index}`"
		>
			<TreeItem
				:half-value.sync="item.isHalf"
				:value="item.checked"
				@input="value => (treeList[index].checked = value)"
				:node-key="nodeKey"
				:props="props"
				:data="item.data"
				:label="item.data[props.label]"
				:children="item.children"
				@change="change"
			>
				<template #label="{ data, label }">
					<slot name="label" v-bind="{ data, label }">
						{{ label }}
					</slot>
				</template>
			</TreeItem>
		</div>
	</div>
</template>

<style scoped lang="scss">
.root-item {
	//background: #f5f8fd;
	//border-radius: 12px;
	//padding: 38px 50px;
	margin: 20px 0 20px 0;
}
</style>

 

<!--
 * @Author: yeminglong
 * @Date: 2024-09-25 09:57:50
 * @LastEditors: yeminglong
 * @LastEditTime: 2024-09-27 18:14:55
 * @Description:
 -->
<script>
export default {
	name: 'TreeItem',
	inject: ['currentNode'],
	props: {
		level: {
			type: Number,
			default: 0
		},
		halfValue: Boolean,
		value: Boolean,
		nodeKey: String,
		props: {
			label: 'name',
			children: 'children'
		},
		data: Object,
		label: String,
		children: Array
	},
	computed: {
		isHalf() {
			const children = this.children || []
			const checkedList = children.filter(v => v.checked && !v.isHalf)

			if (!children.length) {
				return false
			}
			return (
				children.length !== checkedList.length ||
				children.filter(v => v.isHalf).length > 0
			)
			// if (children.length && checkedList.length) {
			// 	return children.length !== checkedList.length
			// }
			// return false
		}
	},
	watch: {
		value: {
			handler(checked) {
				this.checked = checked
			},
			immediate: true
		},
		isHalf(halfValue) {
			this.$emit('update:halfValue', halfValue)
		},
		checked(checked) {
			this.$emit('input', checked)
			this.$emit('change', { checked, data: this.data })
			if (this.level >= this.currentNode.data?.level) {
				this.checkedChildren(checked)
			}
		}
	},
	data() {
		return {
			checked: false,
			foldUp: false
		}
	},
	methods: {
		handleClick() {
			const checked = !this.checked
			this.currentNode.data = { checked, ...this.$props }
			this.checked = checked
		},

		checkedChildren(checked) {
			const children = this?.children
			if (children && children.length) {
				for (const child of children) {
					child.checked = checked
				}
			}
		},
		change({ checked }) {
			const children = this?.children ?? []
			const count = children.filter(v => v.checked).length
			if (!checked && count > 0) {
				return false
			}
			this.checked = checked
		}
	}
}
</script>

<template>
	<div class="tree-item" :class="`tree-item-${level}`">
		<div class="tree-item-header">
			<!--<van-checkbox-->
			<!--	v-model="checked"-->
			<!--	shape="square"-->
			<!--	@click.native="handleClick"-->
			<!-->-->
			<!--	<slot name="label" v-bind="{ data, label }">-->
			<!--		{{ label }}-->
			<!--	</slot>-->
			<!--</van-checkbox>-->

			<div class="checkbox-box">
				<span
					class="checkbox-box-toggle"
					:class="{ 'is-foldUp': foldUp }"
					:style="{
						visibility: children.length ? 'visible' : 'hidden'
					}"
					@click="
						() => {
							foldUp = !foldUp
						}
					"
				>
					<van-icon name="arrow" v-if="children.length" />
				</span>
				<span @click="handleClick">
					<span
						class="checkbox-box-input"
						:class="{ 'is-half': isHalf, 'is-checked': checked }"
					>
						<span class="half-line" v-if="isHalf"></span>
						<svg-icon
							class="checkbox-box-input-icon"
							icon-class="common-checked"
							v-if="checked && !isHalf"
						/>
					</span>
					<slot name="label" v-bind="{ data, label }">
						{{ label }}
					</slot>
				</span>
			</div>
		</div>
		<div
			class="tree-item-sub"
			v-if="children && children.length"
			v-show="foldUp"
		>
			<TreeItem
				v-for="(item, index) in children"
				:key="`children-${(nodeKey && item.data[nodeKey]) || index}`"
				:level="level + 1"
				:half-value.sync="item.isHalf"
				:value="item.checked"
				@input="value => (children[index].checked = value)"
				:node-key="nodeKey"
				:props="props"
				:data="item.data"
				:label="item.data[props.label]"
				:children="item.children"
				@change="change"
			>
				<template #label="{ data }">
					<slot name="label" v-bind="{ data, label }">
						{{ label }}
					</slot>
				</template>
			</TreeItem>
		</div>
	</div>
</template>

<style scoped lang="scss">
.tree-item {
	//margin: 5px 0 5px 0;
}

.tree-item-header {
	//margin-bottom: 20px;
}

.checkbox-box {
	display: inline-flex;
	align-items: center;

	> span {
		display: inline-flex;
		align-items: center;
	}

	.checkbox-box-toggle {
		width: 20px;
		height: 20px;
		display: inline-flex;
		align-items: center;
		justify-content: center;
		cursor: pointer;
		font-size: 15px;
		&.is-foldUp {
			transform: rotate(90deg);
		}
	}

	.checkbox-box-input {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 20px;
		height: 20px;
		border-radius: 5px;
		border: 1px solid rgb(200, 201, 204);
		background: #fff;
		color: #fff;
		margin-right: 10px;
		cursor: pointer;
		overflow: hidden;

		:deep(.checkbox-box-input-icon) {
			width: 15px;
			height: 15px;
			overflow: hidden;
		}

		&.is-checked {
			background: #0262f1;
		}

		.half-line {
			height: 2px;
			width: 60%;
			background: #fff;
		}
	}
}

.tree-item-sub {
	margin-left: 30px;
}
</style>

 

调用组件

 

<template>
    <TreeList :data="treeData" node-key="id" :props="{
					label: 'itemName',
					children: 'children'
				}" @change="change">
        <template #label="{ data }">
            {{ data.itemName }}({{ data.count }})
        </template>
    </TreeList>
</template>
<script>
export default {
    name: 'index',
    data() {
        return {
            treeData: [{
                    "id": "JDBF",
                    "itemName": "测试节点-01",
                    "itemLevel": 1,
                    "parentItem": "ALL",
                    "itemIndex": "1",
                    "itemClass": "1",
                    "isParent": "1",
                    "count": 16680,
                    "children": [{
                            "id": "AIR",
                            "itemName": "测试节点-01",
                            "itemLevel": 1,
                            "parentItem": "JDBF",
                            "itemIndex": "4",
                            "itemClass": "1",
                            "isParent": "1",
                            "count": 4169,
                            "children": [{
                                    "id": "AIR_04",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "AIR",
                                    "itemIndex": "32",
                                    "itemClass": "1",
                                    "isParent": "1",
                                    "count": 0,
                                    "children": [{
                                            "id": "AIR_04_01",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_04",
                                            "itemIndex": "45",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        },
                                        {
                                            "id": "AIR_04_02",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_04",
                                            "itemIndex": "46",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        }
                                    ]
                                },
                                {
                                    "id": "AIR_03",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "AIR",
                                    "itemIndex": "31",
                                    "itemClass": "1",
                                    "isParent": "1",
                                    "count": 0,
                                    "children": [{
                                        "id": "AIR_03_01",
                                        "itemName": "测试节点-03",
                                        "itemLevel": 3,
                                        "parentItem": "AIR_03",
                                        "itemIndex": "42",
                                        "itemClass": "1",
                                        "isParent": "0",
                                        "count": 0,
                                        "children": []
                                    }]
                                },
                                {
                                    "id": "AIR_02",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "AIR",
                                    "itemIndex": "30",
                                    "itemClass": "1",
                                    "isParent": "1",
                                    "count": 174,
                                    "children": [{
                                            "id": "AIR_02_05",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_02",
                                            "itemIndex": "41",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        },
                                        {
                                            "id": "AIR_02_04",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_02",
                                            "itemIndex": "40",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 119,
                                            "children": []
                                        },
                                        {
                                            "id": "AIR_02_03",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_02",
                                            "itemIndex": "39",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 36,
                                            "children": []
                                        },
                                        {
                                            "id": "AIR_02_02",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_02",
                                            "itemIndex": "38",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 19,
                                            "children": []
                                        },
                                        {
                                            "id": "AIR_02_01",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_02",
                                            "itemIndex": "37",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        }
                                    ]
                                },
                                {
                                    "id": "AIR_01",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "AIR",
                                    "itemIndex": "29",
                                    "itemClass": "1",
                                    "isParent": "1",
                                    "count": 3995,
                                    "children": [{
                                            "id": "AIR_01_05",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_01",
                                            "itemIndex": "48",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        },
                                        {
                                            "id": "AIR_01_04",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_01",
                                            "itemIndex": "36",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 77,
                                            "children": []
                                        },
                                        {
                                            "id": "AIR_01_03",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_01",
                                            "itemIndex": "35",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 3852,
                                            "children": []
                                        },
                                        {
                                            "id": "AIR_01_02",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_01",
                                            "itemIndex": "34",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        },
                                        {
                                            "id": "AIR_01_01",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "AIR_01",
                                            "itemIndex": "33",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 66,
                                            "children": []
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            "id": "PWXK",
                            "itemName": "测试节点-01",
                            "itemLevel": 1,
                            "parentItem": "JDBF",
                            "itemIndex": "2",
                            "itemClass": "1",
                            "isParent": "1",
                            "count": 5236,
                            "children": [{
                                    "id": "PWXK_002",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "PWXK",
                                    "itemIndex": "6",
                                    "itemClass": "1",
                                    "isParent": "0",
                                    "count": 124,
                                    "children": []
                                },
                                {
                                    "id": "PWXK_004",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "PWXK",
                                    "itemIndex": "8",
                                    "itemClass": "1",
                                    "isParent": "0",
                                    "count": 2172,
                                    "children": []
                                },
                                {
                                    "id": "PWXK_003",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "PWXK",
                                    "itemIndex": "7",
                                    "itemClass": "1",
                                    "isParent": "0",
                                    "count": 0,
                                    "children": []
                                },
                                {
                                    "id": "PWXK_001",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "PWXK",
                                    "itemIndex": "5",
                                    "itemClass": "1",
                                    "isParent": "0",
                                    "count": 158,
                                    "children": []
                                },
                                {
                                    "id": "PWXK_005",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "PWXK",
                                    "itemIndex": "9",
                                    "itemClass": "1",
                                    "isParent": "0",
                                    "count": 2782,
                                    "children": []
                                }
                            ]
                        },
                        {
                            "id": "WATER",
                            "itemName": "测试节点-01",
                            "itemLevel": 1,
                            "parentItem": "JDBF",
                            "itemIndex": "3",
                            "itemClass": "1",
                            "isParent": "1",
                            "count": 7275,
                            "children": [{
                                    "id": "WATER_03",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "WATER",
                                    "itemIndex": "12",
                                    "itemClass": "1",
                                    "isParent": "1",
                                    "count": 151,
                                    "children": [{
                                        "id": "WATER_03_01",
                                        "itemName": "测试节点-03",
                                        "itemLevel": 3,
                                        "parentItem": "WATER_03",
                                        "itemIndex": "26",
                                        "itemClass": "1",
                                        "isParent": "0",
                                        "count": 151,
                                        "children": []
                                    }]
                                },
                                {
                                    "id": "WATER_04",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "WATER",
                                    "itemIndex": "13",
                                    "itemClass": "1",
                                    "isParent": "1",
                                    "count": 0,
                                    "children": [{
                                            "id": "WATER_04_02",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_04",
                                            "itemIndex": "28",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_04_01",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_04",
                                            "itemIndex": "27",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        }
                                    ]
                                },
                                {
                                    "id": "WATER_02",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "WATER",
                                    "itemIndex": "11",
                                    "itemClass": "1",
                                    "isParent": "1",
                                    "count": 333,
                                    "children": [{
                                            "id": "WATER_02_05",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_02",
                                            "itemIndex": "24",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 133,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_02_06",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_02",
                                            "itemIndex": "25",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_02_03",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_02",
                                            "itemIndex": "22",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 32,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_02_04",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_02",
                                            "itemIndex": "23",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 160,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_02_02",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_02",
                                            "itemIndex": "21",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 8,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_02_01",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_02",
                                            "itemIndex": "20",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        }
                                    ]
                                },
                                {
                                    "id": "WATER_01",
                                    "itemName": "测试节点-02",
                                    "itemLevel": 2,
                                    "parentItem": "WATER",
                                    "itemIndex": "10",
                                    "itemClass": "1",
                                    "isParent": "1",
                                    "count": 6791,
                                    "children": [{
                                            "id": "WATER_01_08",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_01",
                                            "itemIndex": "47",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_01_03",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_01",
                                            "itemIndex": "16",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 5129,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_01_07",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_01",
                                            "itemIndex": "19",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 1,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_01_05",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_01",
                                            "itemIndex": "18",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 0,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_01_04",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_01",
                                            "itemIndex": "17",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 1643,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_01_02",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_01",
                                            "itemIndex": "15",
                                            "itemClass": "1",
                                            "isParent": "0",
                                            "count": 3,
                                            "children": []
                                        },
                                        {
                                            "id": "WATER_01_01",
                                            "itemName": "测试节点-03",
                                            "itemLevel": 3,
                                            "parentItem": "WATER_01",
                                            "itemIndex": "14",
                                            "itemClass": "1",
                                            "isParent": "1",
                                            "count": 15,
                                            "children": []
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                },
                {
                    "id": "RCZL",
                    "itemName": "测试节点-01",
                    "itemLevel": 1,
                    "parentItem": "ALL",
                    "itemIndex": "1",
                    "itemClass": "2",
                    "isParent": "1",
                    "count": 0,
                    "children": []
                }
            ]
        }
    },
    methods: {
        change({ checked, data }) {}
    }
}
</script>

 

放出来一下效果图

 

移动端tree组件父子组件联动。_f5

用到的图标资源


举报

相关推荐

0 条评论