重构IconPicker组件
This commit is contained in:
parent
d7be207545
commit
5217ca41d2
@ -17,19 +17,16 @@
|
||||
</template>
|
||||
</n-button>
|
||||
|
||||
<!-- 图标选择弹窗 -->
|
||||
<n-modal
|
||||
<!-- 图标选择抽屉 -->
|
||||
<n-drawer
|
||||
v-model:show="showPicker"
|
||||
preset="dialog"
|
||||
:title="t('Select Icon')"
|
||||
:positive-text="t('Confirm')"
|
||||
:negative-text="t('Cancel')"
|
||||
@positive-click="confirmSelection"
|
||||
@negative-click="cancelSelection"
|
||||
size="huge"
|
||||
:bordered="false"
|
||||
style="width: 90vw; max-width: 1200px;"
|
||||
:width="900"
|
||||
:placement="'right'"
|
||||
:trap-focus="false"
|
||||
:close-on-esc="true"
|
||||
>
|
||||
<n-drawer-content :title="t('Select Icon')" :closable="true">
|
||||
<template #default>
|
||||
<div class="icon-picker-content">
|
||||
<!-- 搜索栏和图标库选择 -->
|
||||
<div class="search-section">
|
||||
@ -104,13 +101,25 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</n-modal>
|
||||
</template>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
<template #footer>
|
||||
<div class="drawer-footer">
|
||||
<n-button @click="cancelSelection">{{ t('Cancel') }}</n-button>
|
||||
<n-button type="primary" @click="confirmSelection" :disabled="!tempSelectedIcon">
|
||||
{{ t('Confirm') }}
|
||||
</n-button>
|
||||
</div>
|
||||
</template>
|
||||
</n-drawer-content>
|
||||
</n-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { NButton, NModal, NInput, NSelect, useMessage } from 'naive-ui'
|
||||
import { ref, computed, onMounted, watch } from 'vue'
|
||||
import { NButton, NDrawer, NDrawerContent, NInput, NSelect, useMessage } from 'naive-ui'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { getIconLibraryConfig, getAvailableIconLibraries, DEFAULT_ICON_LIBRARY } from '@/shared/utils/icon-libraries'
|
||||
import { t } from '@/shared/i18n'
|
||||
@ -414,10 +423,27 @@ async function copyIconName(iconName: string) {
|
||||
message.success(`${t('Icon name copied to clipboard')}: ${fullIconName}`)
|
||||
}
|
||||
|
||||
// 监听 modelValue 变化
|
||||
watch(() => props.modelValue, (newValue) => {
|
||||
if (newValue !== selectedIcon.value) {
|
||||
selectedIcon.value = newValue || ''
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
// 组件挂载时加载图标
|
||||
onMounted(() => {
|
||||
loadAllIcons()
|
||||
})
|
||||
|
||||
// 暴露给外部的方法:打开选择器
|
||||
function open() {
|
||||
openPicker()
|
||||
}
|
||||
|
||||
// 使用 defineExpose 暴露方法
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -433,11 +459,18 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.icon-picker-content {
|
||||
height: 70vh;
|
||||
height: calc(100vh - 120px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.drawer-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.search-section {
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
@ -521,6 +554,7 @@ onMounted(() => {
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, nextTick } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { NInput } from 'naive-ui'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import IconPicker from '@/core/components/IconPicker.vue'
|
||||
@ -17,17 +17,12 @@ const iconValue = computed({
|
||||
}
|
||||
})
|
||||
|
||||
// IconPicker 组件引用(用于触发打开)
|
||||
// IconPicker 组件引用(用于调用打开方法)
|
||||
const iconPickerRef = ref<InstanceType<typeof IconPicker> | null>(null)
|
||||
|
||||
// 打开图标选择器
|
||||
async function openIconPicker() {
|
||||
await nextTick()
|
||||
// 通过点击隐藏的 IconPicker 按钮来打开弹窗
|
||||
const triggerButton = iconPickerRef.value?.$el?.querySelector('.icon-trigger') as HTMLElement
|
||||
if (triggerButton) {
|
||||
triggerButton.click()
|
||||
}
|
||||
function openIconPicker() {
|
||||
iconPickerRef.value?.open()
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -83,15 +78,15 @@ async function openIconPicker() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图标选择器(隐藏触发按钮,通过自定义按钮触发)-->
|
||||
<div v-if="canEdit" style="position: absolute; left: -9999px; opacity: 0; pointer-events: none;">
|
||||
<!-- 图标选择器(不渲染触发按钮,仅用于弹窗)-->
|
||||
<IconPicker
|
||||
v-if="canEdit"
|
||||
ref="iconPickerRef"
|
||||
:model-value="iconValue"
|
||||
@update:model-value="iconValue = $event"
|
||||
style="display: none;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user