sceneInGroupInEditor.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <template>
  2. <div
  3. class="scene-item"
  4. :class="isConfirmingDeletion ? '' : 'not-confirming-deletion'"
  5. >
  6. <img :src="sceneInfo.icon + ossImagePreviewUrlSuffix()" alt="" class="scene-image">
  7. <div class="right">
  8. <span v-if="!isRenaming" class="scene-title" v-title="sceneInfo.sceneTitle">{{sceneInfo.sceneTitle}}</span>
  9. <input v-if="isRenaming" class="scene-title-input" v-model="newName"
  10. ref="input-for-rename"
  11. maxlength="50"
  12. placeholder="输入名字"
  13. @blur="onInputNewNameComplete"
  14. @keydown.enter="onInputEnter"
  15. />
  16. <div class="right-bottom">
  17. <span class="scene-type">{{translateSceneType(sceneInfo.type)}}</span>
  18. <div class="icons">
  19. <i class="iconfont icon-editor_list_edit icon-edit" v-tooltip="'重命名'"
  20. @click="onRequestForRename"
  21. >
  22. </i>
  23. <i class="iconfont icon-editor_list_delete icon-delete" v-tooltip="'删除'"
  24. @click="onRequestForDelete"
  25. >
  26. </i>
  27. </div>
  28. </div>
  29. </div>
  30. <div class="deletion-confirm-wrap">
  31. <div class="deletion-confirm" :class="isConfirmingDeletion ? 'show' : 'hide'"
  32. v-clickoutside="onRequestForCancelDelete"
  33. @click="onConfirmDelete"
  34. >
  35. 删除
  36. </div>
  37. </div>
  38. </div>
  39. </template>
  40. <script>
  41. import { ossImagePreviewUrlSuffix } from '@/utils/other.js'
  42. export default {
  43. name: 'SceneInGroupInEditor',
  44. components: {
  45. },
  46. props: {
  47. sceneInfo: {
  48. type: Object,
  49. require: true,
  50. },
  51. },
  52. data() {
  53. return {
  54. isRenaming: false,
  55. newName: '',
  56. isConfirmingDeletion: false,
  57. }
  58. },
  59. methods: {
  60. ossImagePreviewUrlSuffix,
  61. translateSceneType(type) {
  62. if (type === 'pano') {
  63. return '全景'
  64. } else {
  65. return '三维'
  66. }
  67. },
  68. onRequestForRename() {
  69. this.isRenaming = true
  70. this.newName = this.sceneInfo.sceneTitle
  71. this.$nextTick(() => {
  72. this.$refs['input-for-rename'].focus()
  73. })
  74. },
  75. onInputNewNameComplete() {
  76. this.isRenaming = false
  77. this.$emit('rename', this.sceneInfo.id, this.newName)
  78. this.newName = ''
  79. },
  80. onInputEnter() {
  81. this.isRenaming = false // 会导致input blur,进而触发onInputNewNameComplete
  82. },
  83. onRequestForDelete() {
  84. this.isConfirmingDeletion = true
  85. },
  86. onRequestForCancelDelete() {
  87. this.isConfirmingDeletion = false
  88. },
  89. onConfirmDelete() {
  90. this.$emit('delete', this.sceneInfo.id)
  91. this.isConfirmingDeletion = false
  92. }
  93. }
  94. }
  95. </script>
  96. <style lang="less" scoped>
  97. .scene-item {
  98. position: relative;
  99. margin-top: 6px;
  100. margin-left: -12px;
  101. margin-right: -10px;
  102. padding-right: 10px;
  103. padding-top: 10px;
  104. padding-bottom: 10px;
  105. display: flex;
  106. border-radius: 4px;
  107. &:hover {
  108. background: #313131;
  109. }
  110. &.not-confirming-deletion:hover {
  111. .icons {
  112. display: block !important;
  113. }
  114. }
  115. .scene-image {
  116. flex: 0 0 auto;
  117. width: 64px;
  118. height: 64px;
  119. background: #B0B0B0;
  120. border-radius: 2px;
  121. object-fit: cover;
  122. }
  123. .right {
  124. margin-left: 10px;
  125. width: 0px;
  126. flex: 1 1 auto;
  127. display: flex;
  128. flex-direction: column;
  129. justify-content: space-between;
  130. .scene-title {
  131. word-break: break-all;
  132. display: -webkit-box;
  133. -webkit-box-orient: vertical;
  134. -webkit-line-clamp: 2;
  135. overflow: hidden;
  136. font-size: 14px;
  137. color: rgba(255, 255, 255, 0.6);
  138. }
  139. .scene-title-input {
  140. height: 30px;
  141. background: #1A1B1D;
  142. border-radius: 2px;
  143. border: 1px solid #404040;
  144. color: #fff;
  145. font-size: 14px;
  146. padding: 0 10px 0 16px;
  147. &:focus {
  148. border-color: #0076F6;
  149. }
  150. }
  151. .right-bottom {
  152. display: flex;
  153. justify-content: space-between;
  154. align-items: flex-end;
  155. .scene-type {
  156. color: #0076F6;
  157. line-height: 16px;
  158. }
  159. .icons {
  160. display: none;
  161. i {
  162. font-size: 16px;
  163. cursor: pointer;
  164. color: rgba(255, 255, 255, 0.6);
  165. }
  166. .icon-edit {
  167. &:hover {
  168. color: #0076F6;
  169. }
  170. }
  171. .icon-delete {
  172. margin-left: 11px;
  173. &:hover {
  174. color: #fa5555;
  175. }
  176. }
  177. }
  178. }
  179. }
  180. .deletion-confirm-wrap {
  181. position: absolute;
  182. top: 0;
  183. bottom: 0;
  184. right: 0;
  185. width: 44px;
  186. overflow: hidden;
  187. pointer-events: none;
  188. border-top-right-radius: 4px;
  189. border-bottom-right-radius: 4px;
  190. > .deletion-confirm {
  191. position: absolute;
  192. top: 0;
  193. bottom: 0;
  194. width: 100%;
  195. background: #FA5555;
  196. transition: right 0.3s;
  197. cursor: pointer;
  198. text-align: center;
  199. font-size: 12px;
  200. color: #fff;
  201. pointer-events: auto;
  202. &::after {
  203. content: '';
  204. height: 100%;
  205. vertical-align: middle;
  206. display: inline-block;
  207. }
  208. &.show {
  209. right: 0;
  210. }
  211. &.hide {
  212. right: -44px;
  213. }
  214. }
  215. }
  216. }
  217. </style>