NestedFolder.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <template>
  2. <div class="scene-group">
  3. <div
  4. class="top-bar"
  5. :class="{
  6. highlight: targetId === folderInfo.id,
  7. disabled: isDisabled,
  8. }"
  9. @click="onClickTopBar"
  10. :style="{
  11. paddingLeft: topBarPaddingLeft,
  12. }"
  13. >
  14. <i
  15. class="iconfont icon-edit_input_arrow icon-expand"
  16. :class="isExpanded ? '' : 'collapsed'"
  17. ></i>
  18. <img
  19. v-show="!isExpanded"
  20. class="folder collapsed"
  21. src="@/assets/images/icons/folder-blue-small-close.png"
  22. alt=""
  23. draggable="false"
  24. />
  25. <img
  26. v-show="isExpanded"
  27. class="folder opened"
  28. src="@/assets/images/icons/folder-blue-small-open.png"
  29. alt=""
  30. draggable="false"
  31. />
  32. <span class="group-name">{{
  33. folderInfo.id === 1
  34. ? $i18n.t("gather.root_dir")
  35. : folderInfo.name
  36. }}</span>
  37. </div>
  38. <div class="group-content" v-if="isExpanded">
  39. <div v-for="(item, index) of folderInfo.children" :key="item.id">
  40. <component
  41. :is="'NestedFolder'"
  42. :folderInfo="item"
  43. :level="level + 1"
  44. :targetId="targetId"
  45. :disabledFolderList="disabledFolderList"
  46. @targeted="onSonTargeted"
  47. />
  48. </div>
  49. </div>
  50. </div>
  51. </template>
  52. <script>
  53. import { mapGetters } from "vuex";
  54. export default {
  55. name: "NestedFolder",
  56. components: {},
  57. props: {
  58. folderInfo: {
  59. type: Object,
  60. required: true,
  61. },
  62. level: {
  63. type: Number,
  64. default: 1,
  65. },
  66. disabledFolderList: {
  67. type: Array,
  68. default: () => {
  69. return [];
  70. },
  71. },
  72. targetId: {
  73. required: true,
  74. },
  75. },
  76. data() {
  77. return {
  78. isExpanded: this.level === 1 ? true : false,
  79. };
  80. },
  81. computed: {
  82. topBarPaddingLeft() {
  83. return 12 + (this.level - 1) * 12 + "px";
  84. },
  85. sceneItemPaddingLeft() {
  86. return 18 + this.level * 12 + "px";
  87. },
  88. isDisabled() {
  89. return this.disabledFolderList.some((item) => {
  90. return item.id === this.folderInfo.id;
  91. });
  92. },
  93. },
  94. methods: {
  95. onClickTopBar() {
  96. if (!this.isDisabled) {
  97. this.isExpanded = !this.isExpanded;
  98. this.$emit("targeted", this.folderInfo.id);
  99. }
  100. },
  101. onSonTargeted(id) {
  102. this.$emit("targeted", id);
  103. },
  104. },
  105. mounted() {},
  106. destroyed() {},
  107. };
  108. </script>
  109. <style lang="less" scoped>
  110. .scene-group {
  111. user-select: none;
  112. .top-bar {
  113. position: relative;
  114. height: 40px;
  115. border-radius: 4px;
  116. display: flex;
  117. align-items: center;
  118. padding-right: 10px;
  119. &:hover {
  120. }
  121. &.highlight {
  122. background: #ebedf0;
  123. }
  124. &.disabled {
  125. opacity: 0.5;
  126. }
  127. > .icon-expand {
  128. display: inline-block;
  129. font-size: 12px;
  130. transform: scale(0.7);
  131. color: rgba(130, 134, 142, 1);
  132. flex: 0 0 auto;
  133. &.collapsed {
  134. display: inline-block;
  135. transform: scale(0.7) rotate(-90deg);
  136. }
  137. }
  138. > img.folder {
  139. margin-left: 7px;
  140. flex: 0 0 auto;
  141. width: 16px;
  142. &.collapsed {
  143. height: 16px;
  144. }
  145. &.opened {
  146. height: 14px;
  147. }
  148. }
  149. > .group-name {
  150. margin-left: 6px;
  151. display: inline-block;
  152. text-overflow: ellipsis;
  153. overflow: hidden;
  154. white-space: nowrap;
  155. flex: 1 1 auto;
  156. font-size: 14px;
  157. color: #323233;
  158. cursor: default;
  159. }
  160. }
  161. }
  162. </style>