tree.html 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <script src="../../dist/vue.global.js"></script>
  2. <!-- item template -->
  3. <script type="text/x-template" id="item-template">
  4. <li>
  5. <div
  6. :class="{bold: isFolder}"
  7. @click="toggle"
  8. @dblclick="changeType">
  9. {{model.name}}
  10. <span v-if="isFolder">[{{open ? '-' : '+'}}]</span>
  11. </div>
  12. <ul v-show="open" v-if="isFolder">
  13. <tree-item
  14. class="item"
  15. v-for="model in model.children"
  16. :model="model">
  17. </tree-item>
  18. <li class="add" @click="addChild">+</li>
  19. </ul>
  20. </li>
  21. </script>
  22. <!-- item script -->
  23. <script>
  24. const TreeItem = {
  25. name: 'TreeItem', // necessary for self-reference
  26. template: '#item-template',
  27. props: {
  28. model: Object,
  29. },
  30. data() {
  31. return {
  32. open: false,
  33. }
  34. },
  35. computed: {
  36. isFolder() {
  37. return this.model.children && this.model.children.length
  38. },
  39. },
  40. methods: {
  41. toggle() {
  42. if (this.isFolder) {
  43. this.open = !this.open
  44. }
  45. },
  46. changeType() {
  47. if (!this.isFolder) {
  48. this.model.children = []
  49. this.addChild()
  50. this.open = true
  51. }
  52. },
  53. addChild() {
  54. this.model.children.push({
  55. name: 'new stuff',
  56. })
  57. },
  58. },
  59. }
  60. </script>
  61. <p>(You can double click on an item to turn it into a folder.)</p>
  62. <!-- the app root element -->
  63. <ul id="demo">
  64. <tree-item class="item" :model="treeData"></tree-item>
  65. </ul>
  66. <script>
  67. const treeData = {
  68. name: 'My Tree',
  69. children: [
  70. { name: 'hello' },
  71. { name: 'wat' },
  72. {
  73. name: 'child folder',
  74. children: [
  75. {
  76. name: 'child folder',
  77. children: [{ name: 'hello' }, { name: 'wat' }],
  78. },
  79. { name: 'hello' },
  80. { name: 'wat' },
  81. {
  82. name: 'child folder',
  83. children: [{ name: 'hello' }, { name: 'wat' }],
  84. },
  85. ],
  86. },
  87. ],
  88. }
  89. Vue.createApp({
  90. components: {
  91. TreeItem,
  92. },
  93. data: () => ({
  94. treeData,
  95. }),
  96. }).mount('#demo')
  97. </script>
  98. <style>
  99. body {
  100. font-family: Menlo, Consolas, monospace;
  101. color: #444;
  102. }
  103. .item {
  104. cursor: pointer;
  105. }
  106. .bold {
  107. font-weight: bold;
  108. }
  109. ul {
  110. padding-left: 1em;
  111. line-height: 1.5em;
  112. list-style-type: dot;
  113. }
  114. </style>