index.vue 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. <template>
  2. <el-popover popper-class="app-icon-select" trigger="click" :hide-after="0" :width="selectorWidth"
  3. :visible="visible">
  4. <template #reference>
  5. <el-input ref="selectorInput" v-model="iconName" placeholder="请输入" @focus="popoverShow" @blur="popoverHide" />
  6. </template>
  7. <el-scrollbar :height="250">
  8. <ul @mousedown.self="inputFocus = true" @mouseup.self="inputFocus = false">
  9. <li :class="[key === iconName ? 'active' : '']" v-for="key in Object.keys(ElementIcons)" :key="key"
  10. @click="onIcon(key)">
  11. <app-icon :icon="key" />
  12. </li>
  13. </ul>
  14. </el-scrollbar>
  15. </el-popover>
  16. </template>
  17. <script lang="ts" setup>
  18. import { ref, computed, onMounted } from 'vue'
  19. import * as ElementIcons from '@element-plus/icons-vue'
  20. import AppIcon from '@pc/components/base/icon/index.vue'
  21. const emit = defineEmits(['update:modelValue'])
  22. const props = defineProps({
  23. modelValue: {
  24. type: String,
  25. default: ''
  26. },
  27. })
  28. const visible = ref(false)
  29. const inputFocus = ref(false)
  30. const selectorInput = ref()
  31. const selectorWidth = ref(0)
  32. const iconName = computed({
  33. get() {
  34. return props.modelValue
  35. },
  36. set(val) {
  37. emit('update:modelValue', val)
  38. }
  39. })
  40. const popoverShow = () => {
  41. visible.value = true
  42. }
  43. const popoverHide = () => {
  44. if (inputFocus.value) {
  45. selectorInput.value.focus()
  46. } else {
  47. visible.value = false
  48. }
  49. }
  50. const onIcon = (key: string) => {
  51. iconName.value = key
  52. popoverHide()
  53. }
  54. onMounted(() => {
  55. selectorWidth.value = selectorInput.value.$el.offsetWidth
  56. })
  57. </script>
  58. <style lang="less">
  59. @import './index.less';
  60. </style>