select-back.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <template>
  2. <div class="back-layout">
  3. <template v-for="back in backs" :key="back.value">
  4. <div v-if="back.children" class="child-layout-parent">
  5. <Dropdown placement="bottom">
  6. <div class="child-layout" :class="{ active: activeParent === back.value }">
  7. <ui-icon type="menu" />
  8. <BackItem
  9. :type="back.type"
  10. :label="back.label"
  11. :url="back.image"
  12. :active="activeParent === back.value"
  13. />
  14. </div>
  15. <template #overlay>
  16. <Menu
  17. :selectedKeys="[value]"
  18. :default-active="value[1]?.toString()"
  19. active-text-color="#ffd04b"
  20. >
  21. <MenuItem
  22. v-for="item in back.children"
  23. :key="item.value"
  24. @click="
  25. value[1] !== item.value && $emit('update:value', [null, item.value])
  26. "
  27. :index="item.value.toString()"
  28. >
  29. <span
  30. :style="{
  31. color:
  32. value[1] === item.value ? 'var(--colors-primary-base) ' : '#fff',
  33. }"
  34. >{{ item.label }}</span
  35. >
  36. </MenuItem>
  37. </Menu>
  38. </template>
  39. </Dropdown>
  40. </div>
  41. <BackItem
  42. v-else
  43. :type="back.type"
  44. :label="back.label"
  45. :url="back.image"
  46. :active="value[0] === back.value"
  47. @click="value[0] !== back.value && $emit('update:value', [back.value, null])"
  48. />
  49. </template>
  50. <!-- 上传入口 -->
  51. <!-- <ui-input
  52. class="img-input"
  53. type="file"
  54. width="88px"
  55. height="88px"
  56. preview
  57. :accept="'.png'"
  58. :disable="true"
  59. :multiple="false"
  60. :maxSize="audioSize"
  61. >
  62. <template v-slot:replace>
  63. <p class="audio-tip">
  64. <ui-icon type="add" />
  65. </p>
  66. </template>
  67. </ui-input> -->
  68. </div>
  69. </template>
  70. <script lang="ts" setup>
  71. import { Dropdown, MenuItem, Menu } from "ant-design-vue";
  72. import { computed, ref } from "vue";
  73. import BackItem from "./back-item.vue";
  74. import { fetchMapTiles } from "@/api/map-tile";
  75. import { sysTiles } from "@/store";
  76. const props = defineProps<{
  77. value: [string | null | undefined, number | null | undefined];
  78. }>();
  79. defineEmits<{
  80. (e: "update:value", value: [string | null, number | null]): void;
  81. }>();
  82. const backs = computed(() => [
  83. { label: "无", type: "icon", image: "icon-without", value: "none" },
  84. {
  85. label: "地图",
  86. type: "map",
  87. image: "https://4dkk.4dage.com/fusion/default/images/map.png",
  88. value: "dt",
  89. children: sysTiles.value.map((t) => ({ label: t.name, value: t.id })),
  90. },
  91. {
  92. label: "蓝天白云",
  93. type: "img",
  94. image: "https://4dkk.4dage.com/fusion/default/images/pic_ltby@2x.png",
  95. value: "https://4dkk.4dage.com/fusion/default/images/蓝天白云.jpg",
  96. },
  97. {
  98. label: "乌云密布",
  99. type: "img",
  100. image: "https://4dkk.4dage.com/fusion/default/images/pic_wymb@2x.png",
  101. value: "https://4dkk.4dage.com/fusion/default/images/乌云密布.jpg",
  102. },
  103. {
  104. label: "夜空",
  105. type: "img",
  106. image: "https://4dkk.4dage.com/fusion/default/images/pic_yk@2x.png",
  107. value: "https://4dkk.4dage.com/fusion/default/images/夜空.jpg",
  108. },
  109. {
  110. label: "傍晚",
  111. type: "img",
  112. image: "https://4dkk.4dage.com/fusion/default/images/pic_bw@2x.png",
  113. value: "https://4dkk.4dage.com/fusion/default/images/傍晚.jpg",
  114. },
  115. ]);
  116. const activeParent = computed(() => {
  117. for (const back of backs.value) {
  118. if (back.value === props.value[0]) {
  119. return back.value;
  120. } else if (back.children) {
  121. for (const c of back.children) {
  122. if (c.value === props.value[1]) {
  123. return back.value;
  124. }
  125. }
  126. }
  127. }
  128. });
  129. </script>
  130. <style lang="scss" scoped>
  131. .back-layout {
  132. display: grid;
  133. grid-template-columns: repeat(3, 1fr);
  134. gap: 20px;
  135. .img-input{
  136. border: 1px solid #F5F5F5;
  137. border-radius: 6px;
  138. }
  139. }
  140. .child-layout-parent {
  141. position: relative;
  142. }
  143. .child-layout {
  144. position: absolute;
  145. top: 0;
  146. left: 0;
  147. height: 88px;
  148. > .icon {
  149. position: absolute;
  150. font-size: 22px;
  151. left: 50%;
  152. top: 50%;
  153. transform: translate(-50%, -50%);
  154. z-index: 2;
  155. }
  156. &::after {
  157. content: "";
  158. position: absolute;
  159. z-index: 1;
  160. background: rgba(0, 0, 0, 0.5);
  161. inset: 0;
  162. border-radius: 4px;
  163. cursor: pointer;
  164. }
  165. &.active::after {
  166. inset: 0px;
  167. }
  168. }
  169. </style>