父组件: <tree :list="deptList" @change="treeChange"></tree>
子组件: <template> <view> <view class="item--list" v-for="(item, index) in list" :key="index"> <view class="item--title" @click="selectNode(item)"> <uni-icons v-if="item.id === selectId" class="uni-checkbox" type="checkbox" size="18"></uni-icons> <uni-icons v-else class="uni-circle" type="circle" size="18"></uni-icons> <view>{{ item.label }}</view> <view v-if="item.children && item.children.length" class="open__and--close" @click.stop="handleOpenClose(item, index)"> <view v-if="item.isOpen" class="is-open"></view> <view v-if="!item.isOpen" class="is-close"></view> </view> </view> <view v-if="item.isOpen && item.children && item.children.length" class=""> <view class="item--list" v-for="(child, index) in item.children" :key="index"> <view class="item--title" @click="selectNode(child)"> <uni-icons v-if="child.id === selectId" class="uni-checkbox" type="checkbox" size="18"></uni-icons> <uni-icons v-else class="uni-circle" type="circle" size="18"></uni-icons> <view>{{ child.label }}</view> <view v-if="child.children && child.children.length" class="open__and--close" @click.stop="handleOpenClose(child, index)" ><view v-if="child.isOpen" class="is-open"></view> <view v-if="!child.isOpen" class="is-close"></view> </view> </view> <view v-if="child.isOpen && child.children && child.children.length" class=""> <view class="item--list" v-for="(node, index) in child.children" :key="index"> <view class="item--title" @click="selectNode(node)"> <uni-icons v-if="node.id === selectId" class="uni-checkbox" type="checkbox" size="18"></uni-icons> <uni-icons v-else class="uni-circle" type="circle" size="18"></uni-icons> <view>{{ node.label }}</view> <view v-if="node.children && node.children.length" class="open__and--close" @click.stop="handleOpenClose(node, index)" ><view v-if="node.isOpen" class="is-open"></view> <view v-if="!node.isOpen" class="is-close"></view> </view> </view> </view> </view> </view> </view> </view> </view> </template> <script> export default { name: 'treeItem', props: { list: { item: Array, default: () => [] } }, data() { return { selectId: '' } }, methods: { selectNode(val) { this.selectId = '' this.selectId = val.id this.$emit('change', val) }, handleOpenClose(item, index) { if (!item.hasOwnProperty('isOpen')) { item.isOpen = false } item.isOpen = !item.isOpen this.$forceUpdate() } } } </script> <style scoped> .item--list { padding-left: 25rpx; } .item--title { display: flex; align-items: center; font-size: 28rpx; border-bottom: 1rpx solid #f7f7f7; padding: 20rpx; } .open__and--close { margin-left: auto; font-size: 24rpx; padding-right: 32rpx; } .is-open { border-right: 2upx solid; height: 20upx; border-bottom: 2upx solid; width: 20upx; transform: rotate(45deg); } .is-close{ border-right: 2upx solid; height: 20upx; border-bottom: 2upx solid; width: 20upx; transform: rotate(-45deg); } .uni-checkbox { color: #007aff !important; } .uni-circle { color: #999 !important; } ::v-deep .uni-icons { padding-right: 16upx; } </style>