TreeDemo.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <template>
  2. <div class="tree-demo">
  3. <h2>自定义树形组件演示</h2>
  4. <div class="demo-section">
  5. <h3>功能说明</h3>
  6. <ul>
  7. <li>这是一个完全使用原生HTML/CSS/JavaScript实现的树形组件</li>
  8. <li>不依赖任何第三方UI库</li>
  9. <li>父节点在子节点被部分选中时显示为半选状态</li>
  10. <li>即使所有子节点都被选中,父节点也不会自动变为全选状态</li>
  11. </ul>
  12. </div>
  13. <div class="demo-section">
  14. <h3>演示案例</h3>
  15. <p>如您所述:选择"成都市"时,其父级"四川省"应该显示为半选状态而不是全选状态</p>
  16. <div class="tree-container">
  17. <data-permission-tree :data="treeData" v-model="selectedKeys" />
  18. </div>
  19. <div class="result-section">
  20. <h4>当前选中的节点:</h4>
  21. <p>{{ selectedKeys }}</p>
  22. <h4>说明:</h4>
  23. <ul>
  24. <li>尝试选中"成都市",观察"四川省"的状态</li>
  25. <li>"四川省"应该显示为半选状态(方框中有横线)</li>
  26. <li>即使您选中"绵阳市"和"德阳市","四川省"仍然保持半选状态</li>
  27. <li>只有直接点击"四川省"复选框才会使其变为全选状态</li>
  28. </ul>
  29. </div>
  30. </div>
  31. </div>
  32. </template>
  33. <script setup lang="ts">
  34. import { ref } from 'vue'
  35. import DataPermissionTree from '@/components/DataPermisionTree/index.vue'
  36. import type { TreeData } from '@/components/DataPermisionTree/types'
  37. // 树形数据
  38. const treeData: TreeData[] = [
  39. {
  40. id: 1,
  41. name: '中国',
  42. children: [
  43. {
  44. id: 2,
  45. name: '四川省',
  46. children: [
  47. { id: 3, name: '成都市' },
  48. { id: 4, name: '绵阳市' },
  49. { id: 5, name: '德阳市' }
  50. ]
  51. },
  52. {
  53. id: 6,
  54. name: '广东省',
  55. children: [
  56. { id: 7, name: '广州市' },
  57. { id: 8, name: '深圳市' },
  58. { id: 9, name: '珠海市' }
  59. ]
  60. }
  61. ]
  62. }
  63. ]
  64. // 选中的节点ID
  65. const selectedKeys = ref<number[]>([])
  66. </script>
  67. <style scoped>
  68. .tree-demo {
  69. padding: 20px;
  70. max-width: 800px;
  71. margin: 0 auto;
  72. }
  73. .demo-section {
  74. margin-bottom: 30px;
  75. }
  76. .demo-section h3 {
  77. color: #333;
  78. margin-bottom: 15px;
  79. }
  80. .demo-section ul {
  81. padding-left: 20px;
  82. }
  83. .demo-section li {
  84. margin-bottom: 8px;
  85. line-height: 1.5;
  86. }
  87. .tree-container {
  88. margin: 20px 0;
  89. padding: 20px;
  90. border: 1px solid #ddd;
  91. border-radius: 4px;
  92. background-color: #f9f9f9;
  93. min-height: 200px;
  94. }
  95. .result-section {
  96. margin-top: 20px;
  97. padding: 15px;
  98. background-color: #e8f4ff;
  99. border-radius: 4px;
  100. }
  101. .result-section h4 {
  102. margin-top: 0;
  103. color: #333;
  104. }
  105. .result-section p {
  106. font-family: monospace;
  107. background-color: #fff;
  108. padding: 10px;
  109. border-radius: 4px;
  110. border: 1px solid #ddd;
  111. }
  112. .result-section ul {
  113. padding-left: 20px;
  114. margin: 10px 0;
  115. }
  116. .result-section li {
  117. margin-bottom: 8px;
  118. line-height: 1.5;
  119. }
  120. </style>