index.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. <template>
  2. <div class="relative" :style="{ 'width': width }">
  3. <el-input v-model="modelValue" readonly placeholder="点击选择图标" @click="visible = !visible">
  4. <template #prepend>
  5. <svg-icon :icon-class="modelValue" />
  6. </template>
  7. </el-input>
  8. <el-popover shadow="none" :visible="visible" placement="bottom-end" trigger="click" :width="450">
  9. <template #reference>
  10. <div class="cursor-pointer text-[#999] absolute right-[10px] top-0 height-[32px] leading-[32px]"
  11. @click="visible = !visible">
  12. <i-ep-caret-top v-show="visible"></i-ep-caret-top>
  13. <i-ep-caret-bottom v-show="!visible"></i-ep-caret-bottom>
  14. </div>
  15. </template>
  16. <el-input v-model="filterValue" class="p-2" placeholder="搜索图标" clearable @input="filterIcons" />
  17. <el-scrollbar height="w-[200px]">
  18. <ul class="icon-list">
  19. <el-tooltip v-for="(iconName, index) in iconNames" :key="index" :content="iconName" placement="bottom"
  20. effect="light">
  21. <li :class="['icon-item', { active: modelValue == iconName }]" @click="selectedIcon(iconName)">
  22. <svg-icon color="var(--el-text-color-regular)" :icon-class="iconName" />
  23. </li>
  24. </el-tooltip>
  25. </ul>
  26. </el-scrollbar>
  27. </el-popover>
  28. </div>
  29. </template>
  30. <script setup lang="ts">
  31. import icons from '@/components/IconSelect/requireIcons';
  32. import { propTypes } from '@/utils/propTypes';
  33. const props = defineProps({
  34. modelValue: propTypes.string.isRequired,
  35. width: propTypes.string.def('400px')
  36. });
  37. const emit = defineEmits(['update:modelValue']);
  38. const visible = ref(false);
  39. const { modelValue, width } = toRefs(props);
  40. const iconNames = ref<string[]>(icons);
  41. const filterValue = ref('');
  42. /**
  43. * 筛选图标
  44. */
  45. const filterIcons = () => {
  46. if (filterValue.value) {
  47. iconNames.value = icons.filter((iconName) => iconName.includes(filterValue.value));
  48. } else {
  49. iconNames.value = icons;
  50. }
  51. };
  52. /**
  53. * 选择图标
  54. * @param iconName 选择的图标名称
  55. */
  56. const selectedIcon = (iconName: string) => {
  57. emit('update:modelValue', iconName);
  58. visible.value = false;
  59. };
  60. </script>
  61. <style scoped lang="scss">
  62. .el-scrollbar {
  63. max-height: calc(50vh - 100px) !important;
  64. overflow-y: auto;
  65. }
  66. .el-divider--horizontal {
  67. margin: 10px auto !important;
  68. }
  69. .icon-list {
  70. display: flex;
  71. flex-wrap: wrap;
  72. padding-left: 10px;
  73. margin-top: 10px;
  74. .icon-item {
  75. cursor: pointer;
  76. width: 10%;
  77. margin: 0 10px 10px 0;
  78. padding: 5px;
  79. display: flex;
  80. flex-direction: column;
  81. justify-items: center;
  82. align-items: center;
  83. border: 1px solid #ccc;
  84. &:hover {
  85. border-color: var(--el-color-primary);
  86. color: var(--el-color-primary);
  87. transition: all 0.2s;
  88. transform: scaleX(1.1);
  89. }
  90. }
  91. .active {
  92. border-color: var(--el-color-primary);
  93. color: var(--el-color-primary);
  94. }
  95. }
  96. </style>