|
23 | 23 | :aria-expanded="isOpen" |
24 | 24 | :aria-haspopup="true" |
25 | 25 | role="combobox"> |
26 | | - <span class="block truncate"> |
27 | | - {{ selectedLabel || placeholder }} |
28 | | - </span> |
| 26 | + <div class="flex space-x-3 items-center truncate"> |
| 27 | + <!-- 如果是SVG字符串 --> |
| 28 | + <div v-if="selectedOption && getSvgIcon(selectedOption)" v-html="getSvgIcon(selectedOption)" class="w-6 h-6"/> |
| 29 | + |
| 30 | + <!-- 如果是SVG URL --> |
| 31 | + <img v-else-if="selectedOption && getSvgUrl(selectedOption)" :src="getSvgUrl(selectedOption)" class="w-6 h-6" alt="icon"/> |
| 32 | + |
| 33 | + <span>{{ selectedLabel || placeholder }}</span> |
| 34 | + </div> |
29 | 35 | <span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2"> |
30 | 36 | <ChevronUpIcon class="h-5 w-5 text-gray-400 transition-transform duration-200" |
31 | 37 | :class="{ 'rotate-180': isOpen }" |
|
71 | 77 | @keydown.enter.prevent="selectOption(option)" |
72 | 78 | @keydown.space.prevent="selectOption(option)" |
73 | 79 | :class="[ |
74 | | - 'relative cursor-pointer select-none py-1 my-1 pl-3 pr-9 transition-colors duration-150', |
| 80 | + 'relative flex space-x-3 items-center cursor-pointer select-none py-1 my-1 pl-3 pr-9 transition-colors duration-150', |
75 | 81 | isSelected(option) |
76 | 82 | ? 'bg-blue-400 text-white' |
77 | 83 | : 'text-gray-900 hover:bg-blue-50', |
|
80 | 86 | :aria-selected="isSelected(option)" |
81 | 87 | role="option" |
82 | 88 | tabindex="-1"> |
| 89 | + <!-- 如果是SVG字符串 --> |
| 90 | + <div v-if="getSvgIcon(option)" v-html="getSvgIcon(option)" class="w-6 h-6"/> |
| 91 | + |
| 92 | + <!-- 如果是SVG URL --> |
| 93 | + <img v-else-if="getSvgUrl(option)" :src="getSvgUrl(option)" class="w-6 h-6" alt="icon"/> |
| 94 | + |
83 | 95 | <span :class="['block truncate', isSelected(option) ? 'font-medium' : 'font-normal']"> |
84 | 96 | {{ getOptionLabel(option) }} |
85 | 97 | </span> |
@@ -112,6 +124,8 @@ interface Option |
112 | 124 | label: string |
113 | 125 | value: any |
114 | 126 | disabled?: boolean |
| 127 | + svgIcon?: string |
| 128 | + svgUrl?: string |
115 | 129 |
|
116 | 130 | [key: string]: any |
117 | 131 | } |
@@ -177,6 +191,8 @@ const normalizedOptions = computed(() => { |
177 | 191 | ...option, |
178 | 192 | label: option[props.labelKey] || option.label, |
179 | 193 | value: option[props.valueKey] || option.value, |
| 194 | + svgIcon: option.svgIcon || '', |
| 195 | + svgUrl: option.svgUrl || '', |
180 | 196 | disabled: option.disabled || false |
181 | 197 | } |
182 | 198 | }) |
@@ -240,6 +256,8 @@ const updateDropdownPosition = async () => { |
240 | 256 | // 方法 |
241 | 257 | const getOptionValue = (option: Option) => option.value |
242 | 258 | const getOptionLabel = (option: Option) => option.label |
| 259 | +const getSvgUrl = (option: Option) => option.svgUrl |
| 260 | +const getSvgIcon = (option: Option) => option.svgIcon |
243 | 261 |
|
244 | 262 | const isSelected = (option: Option) => { |
245 | 263 | return option.value === props.modelValue |
|
0 commit comments