96 lines
1.9 KiB
Vue
Raw Normal View History

2025-07-01 16:11:57 +08:00
<template>
<view>
<scroll-view scroll-y="true" class="scroll-view">
<tree-node
v-for="item in data"
:key="item[idKey]"
:node="item"
:children-key="childrenKey"
:label-key="labelKey"
:id-key="idKey"
2025-07-09 15:08:55 +08:00
:checked-bg-color="checkedBgColor"
:multiple="multiple"
2025-07-01 16:11:57 +08:00
:checked-ids="checkedIds"
2025-07-23 16:59:21 +08:00
:default-expanded="defaultExpanded"
2025-07-01 16:11:57 +08:00
@check-change="handleCheckChange"
/>
</scroll-view>
</view>
</template>
<script>
import TreeNode from './TreeNode.vue';
export default {
name: 'TreeView',
components: {
TreeNode
},
props: {
data: {
type: Array,
required: true
},
childrenKey: {
type: String,
default: 'children'
},
labelKey: {
type: String,
default: 'text'
},
idKey: {
type: String,
default: 'id'
},
value: {
type: Array,
default: () => []
2025-07-09 15:08:55 +08:00
},
checkedBgColor: { type: String, default: '#fff' },
2025-07-23 16:59:21 +08:00
multiple: { type: Boolean, default: true },
defaultExpanded: { type: Boolean, default: false }
2025-07-01 16:11:57 +08:00
},
data() {
return {
checkedIds: [...this.value]
}
},
watch: {
value(val) {
this.checkedIds = [...val];
}
},
methods: {
handleCheckChange(event) {
2025-07-09 15:08:55 +08:00
const { id, label, checked } = event;
if (this.multiple) {
const idx = this.checkedIds.indexOf(id);
if (checked && idx === -1) {
this.checkedIds.push(id);
} else if (!checked && idx !== -1) {
this.checkedIds.splice(idx, 1);
}
} else {
// 单选只保留当前id
this.checkedIds = checked ? [id] : [];
2025-07-01 16:11:57 +08:00
}
2025-07-09 15:08:55 +08:00
2025-07-01 16:11:57 +08:00
this.$emit('input', this.checkedIds.slice());
this.$emit('change', this.checkedIds.slice());
2025-07-09 15:08:55 +08:00
this.$emit('node-click', id, checked, label);
2025-07-01 16:11:57 +08:00
}
}
}
</script>
<style scoped lang="scss">
/* 保持你的样式 */
.scroll-view {
2025-07-01 18:08:04 +08:00
// margin: 10rpx 26rpx;
width: calc(100%);
2025-07-01 16:11:57 +08:00
max-height: 60vh;
border-radius: 6rpx;
background-color: white;
}
</style>