collapse-list.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <template>
  2. <el-scrollbar>
  3. <div class="com-collapse" :style="{ height: allowScroll ? scrollHeight : 'auto' }">
  4. <div class="collapse-box" v-for="(menu, i) in list" :key="menu" :class="{ active: menuIndex == i }">
  5. <div class="box-text" @click="menuClick(i)">
  6. {{ menu.text }}
  7. </div>
  8. <div class="collapse-items">
  9. <div class="item" v-for="(item, j) in menu.children" :key="item" @click.stop="itemClick(item, j)" :class="{ active: itemIndex == j }">
  10. <span class="dot" :class="'bg-' + item.color"></span>
  11. <span class="value"> {{ item.text }}</span>
  12. </div>
  13. </div>
  14. </div>
  15. </div>
  16. </el-scrollbar>
  17. </template>
  18. <script>
  19. export default {
  20. // 名称
  21. name: "List",
  22. // 使用组件
  23. components: {},
  24. // 传入参数
  25. props: {
  26. // 标题 ""不显示
  27. title: {
  28. type: String,
  29. default: "",
  30. },
  31. // 列表面板高度 fill auto 27.778vh
  32. height: {
  33. type: String,
  34. default: "fill",
  35. },
  36. /**
  37. {
  38. id:'',
  39. text: "某某风电场",
  40. children: [{
  41. id:'',
  42. text:'2E01',
  43. color:'green'
  44. }]
  45. }
  46. */
  47. list: {
  48. type: Array,
  49. default: () => [
  50. {
  51. id: "1",
  52. text: "某某风电场",
  53. children: [
  54. {
  55. id: "1",
  56. text: "2E01",
  57. color: "green",
  58. },
  59. {
  60. id: "2",
  61. text: "2E01",
  62. color: "green",
  63. },
  64. {
  65. id: "3",
  66. text: "2E01",
  67. color: "green",
  68. },
  69. ],
  70. },
  71. {
  72. id: "2",
  73. text: "某某风电场",
  74. children: [
  75. {
  76. id: "1",
  77. text: "2E01",
  78. color: "green",
  79. },
  80. {
  81. id: "2",
  82. text: "2E01",
  83. color: "green",
  84. },
  85. {
  86. id: "3",
  87. text: "2E01",
  88. color: "green",
  89. },
  90. ],
  91. },
  92. ],
  93. },
  94. allowScroll: {
  95. type: Boolean,
  96. default: false,
  97. },
  98. scrollHeight: {
  99. type: String,
  100. default: "100%",
  101. },
  102. },
  103. // 自定义事件
  104. emits: {
  105. // 选中事件
  106. click: null,
  107. },
  108. computed: {},
  109. // 数据
  110. data () {
  111. return {
  112. menuIndex: 0,
  113. itemIndex: 0,
  114. };
  115. },
  116. // 函数
  117. methods: {
  118. menuClick (index) {
  119. if (this.menuIndex == index) {
  120. this.menuIndex = -1;
  121. } else {
  122. this.menuIndex = index;
  123. }
  124. this.itemIndex = -1;
  125. },
  126. itemClick (item, index) {
  127. this.itemIndex = index;
  128. this.wpId = item.wpId;
  129. this.wtId = item.id;
  130. this.$emit("click", item);
  131. },
  132. setDefaultActiveMenu (menu) {
  133. menu.forEach((pEle, pIndex) => {
  134. let findResult = pEle.children.find(cEle => {
  135. return cEle.wpId === this.wpId;
  136. });
  137. if (findResult) this.menuIndex = pIndex;
  138. pEle.children.forEach((cEle, cIndex) => {
  139. if (cEle.id === this.wtId) {
  140. this.itemIndex = cIndex
  141. }
  142. });
  143. });
  144. }
  145. },
  146. // 生命周期钩子
  147. beforeCreate () {
  148. // 创建前
  149. },
  150. created () {
  151. // 创建后
  152. },
  153. beforeMount () {
  154. // 渲染前
  155. },
  156. mounted () {
  157. this.wpId = this.$route.params.wpId || "";
  158. this.wtId = this.$route.params.wtId || "";
  159. this.setDefaultActiveMenu(this.list);
  160. },
  161. beforeUpdate () {
  162. // 数据更新前
  163. },
  164. updated () {
  165. // 数据更新后
  166. },
  167. watch: {
  168. list (res) {
  169. this.setDefaultActiveMenu(res)
  170. }
  171. }
  172. };
  173. </script>
  174. <style lang="less">
  175. .com-collapse {
  176. .collapse-box {
  177. cursor: pointer;
  178. .box-text {
  179. padding: 0.741vh 1.481vh;
  180. background: fade(@white, 10);
  181. &:hover {
  182. color: #fff;
  183. background: fade(@purple, 60);
  184. }
  185. }
  186. .collapse-items {
  187. display: none;
  188. .item {
  189. padding: 0.741vh 1.481vh;
  190. display: flex;
  191. align-items: center;
  192. .dot {
  193. display: inline-block;
  194. width: 0.741vh;
  195. height: 0.741vh;
  196. margin-right: 1.111vh;
  197. }
  198. .value {
  199. flex: auto;
  200. }
  201. &.active {
  202. color: #fff;
  203. cursor: pointer;
  204. }
  205. }
  206. }
  207. &.active {
  208. .box-text {
  209. color: @white;
  210. background: fade(@purple, 60);
  211. }
  212. & > .collapse-items {
  213. display: block;
  214. }
  215. }
  216. }
  217. }
  218. </style>