LayerManagement.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <template>
  2. <div class="layer">
  3. <div class="layer-header">
  4. <span>组件图层</span>
  5. <Button type="text" shape="circle" size="small">
  6. <CloseOutlined />
  7. </Button>
  8. </div>
  9. <div class="line"></div>
  10. <InputSearch
  11. allowClear
  12. size="small"
  13. placeholder="请输入图层名称"
  14. @search="handleFilterLayer"
  15. />
  16. <div class="layer-list">
  17. <VueDraggable
  18. v-if="layerList.length"
  19. :list="layerList"
  20. ghost-class="item-ghost"
  21. chosen-class="item-chosen"
  22. animation="300"
  23. itemKey="id"
  24. @end="dragEnd"
  25. >
  26. <template #item="{ element }">
  27. <LayerItem :data="element" />
  28. </template>
  29. </VueDraggable>
  30. <Empty
  31. v-else
  32. description="暂无图层"
  33. :image="Empty.PRESENTED_IMAGE_SIMPLE"
  34. :style="{ marginTop: '100px' }"
  35. />
  36. </div>
  37. </div>
  38. </template>
  39. <script setup lang="ts">
  40. import type { CustomElement } from "#/project";
  41. import { ref, watch } from "vue";
  42. import { Button, InputSearch, Empty } from "ant-design-vue";
  43. import { CloseOutlined } from "@ant-design/icons-vue";
  44. import VueDraggable from "vuedraggable";
  45. import LayerItem from "./LayerItem.vue";
  46. import { useProjectStore } from "@/store/modules/project";
  47. const projectStore = useProjectStore();
  48. const filter = ref<string>("");
  49. const layerList = ref<CustomElement[]>([]);
  50. watch(
  51. () => [
  52. projectStore.elements,
  53. filter.value,
  54. ],
  55. () => {
  56. const list = projectStore.elements.filter((item) =>
  57. item.name.includes(filter.value)
  58. );
  59. layerList.value = list.sort((a, b) => b.zIndex - a.zIndex);
  60. },
  61. {
  62. immediate: true,
  63. deep: true
  64. }
  65. );
  66. const handleFilterLayer = (value: string) => {
  67. filter.value = value;
  68. };
  69. const dragEnd = (event: CustomEvent & {newIndex: number}) => {
  70. const length = layerList.value.length;
  71. layerList.value.forEach((item, index) => {
  72. projectStore.updateElement(item.key, "zIndex", length - index);
  73. });
  74. projectStore.setSelectedElementKeys([layerList.value[event.newIndex].key]);
  75. };
  76. </script>
  77. <style lang="less" scoped>
  78. .layer {
  79. position: absolute;
  80. height: 100%;
  81. display: flex;
  82. flex-direction: column;
  83. padding: 8px;
  84. &-header {
  85. height: 24px;
  86. display: flex;
  87. justify-content: space-between;
  88. font-size: 12px;
  89. line-height: 24px;
  90. color: #666;
  91. margin-bottom: 8px;
  92. }
  93. &-list {
  94. flex: 1;
  95. overflow-y: auto;
  96. margin-top: 8px;
  97. .item-ghost {
  98. border-bottom: dashed 1px #ccc;
  99. }
  100. }
  101. .line {
  102. width: calc(100% + 16px);
  103. border-top: solid 1px #eee;
  104. margin-bottom: 8px;
  105. margin-left: -8px;
  106. }
  107. }
  108. </style>