tree-view-node.vue 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. <template>
  2. <view class="fx-col">
  3. <view class="fx-row items-center" @click="toggleNode({node, deep})">
  4. <!-- 左侧图标 -->
  5. <view class="w-40">
  6. <slot name="icon" v-bind="{node, deep}">
  7. <uv-icon v-if="node.children?.length" :name="node.expanded ? 'arrow-down':'arrow-right'"/>
  8. </slot>
  9. </view>
  10. <view class="flex-1 py-20 fx-row gap-20 items-center mx-border-b">
  11. <!-- 中间名称 -->
  12. <slot name="node" v-bind="{node, deep}">
  13. <view class="flex-1 fx-col gap-5">
  14. <text class="text-main font-[PingFang]" :class="{'text-sm':deep>0}">
  15. {{ node.name }}
  16. </text>
  17. <text class="text-content text-xs" :class="{'text-xs':deep==0,'text-2xs':deep>0}">
  18. 共{{ node.questionsCount }}道题
  19. </text>
  20. </view>
  21. </slot>
  22. <!-- 右侧命令 -->
  23. <slot name="command" v-bind="{node, deep}"/>
  24. </view>
  25. </view>
  26. <!-- 子节点 -->
  27. <uv-transition :show="node.expanded">
  28. <view v-if="node.expanded" class="ml-30">
  29. <uv-loading-icon :show="node.loading === true" class="py-20"/>
  30. <tree-view-node v-for="child in node.children" :node="child" :deep="deep+1"
  31. @node-click="toggleNode">
  32. <template v-for="(sFn, name) in $slots" #[name]="scope">
  33. <slot :name="name" v-bind="scope"/>
  34. </template>
  35. </tree-view-node>
  36. </view>
  37. </uv-transition>
  38. </view>
  39. </template>
  40. <script>
  41. export default {
  42. name: "tree-view-node",
  43. props: {
  44. node: {
  45. type: Object,
  46. default: () => ({})
  47. },
  48. deep: {
  49. type: Number,
  50. default: 0
  51. }
  52. },
  53. emits: ['node-click'],
  54. methods: {
  55. toggleNode({node, deep}) {
  56. // 切换节点展开状态
  57. if (node.children && node.children.length) {
  58. node.expanded = !node.expanded;
  59. }
  60. // 触发点击事件
  61. this.$emit('node-click', {node, deep});
  62. }
  63. }
  64. }
  65. </script>
  66. <style scoped>
  67. </style>