LayerItem.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <template>
  2. <div
  3. class="list-item"
  4. :class="{
  5. 'list-item-active': projectStore.selectedElementKeys.includes(data.key),
  6. }"
  7. @mouseenter="isHover = true"
  8. @mouseleave="isHover = false"
  9. @click="handleActive"
  10. >
  11. <template v-if="!isEditing">
  12. <span class="list-item-visible">
  13. <EyeOutlined v-if="data.visible && isHover" @click="handleVisible(false)" />
  14. <EyeInvisibleOutlined v-if="!data.visible" @click="handleVisible(true)" />
  15. </span>
  16. <span class="layer-name">
  17. <Tooltip :title="data.name">
  18. <span @dblclick="isEditing = true">{{ data.name }}</span>
  19. </Tooltip>
  20. </span>
  21. <span class="layer-action">
  22. <span v-show="isHover">
  23. <Dropdown :trigger="['click']">
  24. <Tooltip title="更多">
  25. <MoreOutlined />
  26. </Tooltip>
  27. <template #overlay>
  28. <Menu @click="handleMenuClick">
  29. <MenuItem key="rename"><EditOutlined />重命名</MenuItem>
  30. <MenuItem key="del"><DeleteOutlined />删除</MenuItem>
  31. </Menu>
  32. </template>
  33. </Dropdown>
  34. </span>
  35. <Tooltip title="解锁" v-if="data.locked">
  36. <LockOutlined @click="handleLock(false)"/>
  37. </Tooltip>
  38. <span v-else v-show="isHover">
  39. <Tooltip title="锁定">
  40. <UnlockOutlined @click="handleLock(true)"/>
  41. </Tooltip>
  42. </span>
  43. </span>
  44. </template>
  45. <Input
  46. v-else
  47. v-model:value="layerName"
  48. placeholder="请输入图层名称"
  49. size="small"
  50. :status="!layerName ? 'error' : undefined"
  51. @blur="handleChangeName"
  52. />
  53. </div>
  54. </template>
  55. <script setup lang="ts">
  56. import type { CustomElement } from "#/project";
  57. import { defineProps, ref } from "vue";
  58. import { Tooltip, Dropdown, Menu, MenuItem, Input } from "ant-design-vue";
  59. import {
  60. EyeOutlined,
  61. EyeInvisibleOutlined,
  62. MoreOutlined,
  63. LockOutlined,
  64. UnlockOutlined,
  65. EditOutlined,
  66. DeleteOutlined,
  67. } from "@ant-design/icons-vue";
  68. import { useProjectStore } from "@/store/modules/project";
  69. const props = defineProps<{
  70. data: CustomElement;
  71. }>();
  72. const projectStore = useProjectStore();
  73. const layerName = ref<string>(props.data.name);
  74. const isEditing = ref(false);
  75. const isHover = ref(false);
  76. const handleMenuClick = ({ key }: { key: "rename" | "del" }) => {
  77. if (key === "rename") {
  78. isEditing.value = true;
  79. } else {
  80. projectStore.removeElement(props.data.key);
  81. }
  82. };
  83. const handleChangeName = () => {
  84. isEditing.value = false;
  85. if (!layerName.value) {
  86. layerName.value = props.data.name;
  87. return;
  88. };
  89. projectStore.updateElement(props.data.key, "name", layerName.value);
  90. };
  91. const handleActive = () => {
  92. projectStore.setSelectedElementKeys([props.data.key]);
  93. };
  94. const handleLock = (locked: boolean) => {
  95. projectStore.updateElement(props.data.key, "locked", locked);
  96. };
  97. const handleVisible = (visible: boolean) => {
  98. projectStore.updateElement(props.data.key, "visible", visible);
  99. };
  100. </script>
  101. <style lang="less" scoped>
  102. .list-item {
  103. padding: 4px 8px;
  104. cursor: pointer;
  105. display: flex;
  106. align-items: center;
  107. justify-content: space-between;
  108. cursor: move;
  109. color: #666;
  110. font-size: 12px;
  111. line-height: 24px;
  112. &:hover {
  113. background: #e6f4ff;
  114. }
  115. &-visible {
  116. cursor: pointer;
  117. width: 10px;
  118. }
  119. .layer-name {
  120. width: 100px;
  121. overflow: hidden;
  122. text-overflow: ellipsis;
  123. white-space: nowrap;
  124. }
  125. &-active {
  126. background: #e6f4ff;
  127. color: #1677ff;
  128. }
  129. .layer-action {
  130. width: 30px;
  131. text-align: right;
  132. }
  133. }
  134. </style>