refactor(components): 重构核心组件代码块顺序
- 调整App.vue和所有通用组件为template→script→style顺序 - 涉及NovaDialog、UserCenter、IconSelect等核心组件 - 统一组件结构,提升代码可读性和维护性 - 符合项目新的Vue组件代码块排布规范
This commit is contained in:
parent
696c8b1417
commit
797c42aea1
22
src/App.vue
22
src/App.vue
@ -1,3 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<n-config-provider
|
||||||
|
class="wh-full" inline-theme-disabled :theme="appStore.colorMode === 'dark' ? darkTheme : null"
|
||||||
|
:locale="naiveLocale.locale" :date-locale="naiveLocale.dateLocale" :theme-overrides="appStore.theme"
|
||||||
|
>
|
||||||
|
<naive-provider>
|
||||||
|
<router-view />
|
||||||
|
</naive-provider>
|
||||||
|
</n-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { naiveI18nOptions } from '@/utils'
|
import { naiveI18nOptions } from '@/utils'
|
||||||
import { darkTheme } from 'naive-ui'
|
import { darkTheme } from 'naive-ui'
|
||||||
@ -10,14 +21,3 @@ const naiveLocale = computed(() => {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<n-config-provider
|
|
||||||
class="wh-full" inline-theme-disabled :theme="appStore.colorMode === 'dark' ? darkTheme : null"
|
|
||||||
:locale="naiveLocale.locale" :date-locale="naiveLocale.dateLocale" :theme-overrides="appStore.theme"
|
|
||||||
>
|
|
||||||
<naive-provider>
|
|
||||||
<router-view />
|
|
||||||
</naive-provider>
|
|
||||||
</n-config-provider>
|
|
||||||
</template>
|
|
||||||
|
|||||||
@ -1,6 +1,3 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<naive-provider>
|
<naive-provider>
|
||||||
<div id="loading-container">
|
<div id="loading-container">
|
||||||
@ -34,6 +31,9 @@
|
|||||||
</naive-provider>
|
</naive-provider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
#loading-container {
|
#loading-container {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
|
|||||||
@ -1,6 +1,3 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<n-el
|
<n-el
|
||||||
tag="div"
|
tag="div"
|
||||||
@ -16,6 +13,9 @@
|
|||||||
</n-el>
|
</n-el>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.el {
|
.el {
|
||||||
color: var(--n-text-color);
|
color: var(--n-text-color);
|
||||||
|
|||||||
@ -1,3 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<n-popselect :value="appStore.storeColorMode" :render-label="renderLabel" :options="options" trigger="click" @update:value="appStore.setColorMode">
|
||||||
|
<CommonWrapper>
|
||||||
|
<icon-park-outline-moon v-if="appStore.storeColorMode === 'dark'" />
|
||||||
|
<icon-park-outline-sun-one v-if="appStore.storeColorMode === 'light'" />
|
||||||
|
<icon-park-outline-laptop-computer v-if="appStore.storeColorMode === 'auto'" />
|
||||||
|
</CommonWrapper>
|
||||||
|
</n-popselect>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useAppStore } from '@/store'
|
import { useAppStore } from '@/store'
|
||||||
import IconAuto from '~icons/icon-park-outline/laptop-computer'
|
import IconAuto from '~icons/icon-park-outline/laptop-computer'
|
||||||
@ -39,14 +49,4 @@ function renderLabel(option: any) {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<n-popselect :value="appStore.storeColorMode" :render-label="renderLabel" :options="options" trigger="click" @update:value="appStore.setColorMode">
|
|
||||||
<CommonWrapper>
|
|
||||||
<icon-park-outline-moon v-if="appStore.storeColorMode === 'dark'" />
|
|
||||||
<icon-park-outline-sun-one v-if="appStore.storeColorMode === 'light'" />
|
|
||||||
<icon-park-outline-laptop-computer v-if="appStore.storeColorMode === 'auto'" />
|
|
||||||
</CommonWrapper>
|
|
||||||
</n-popselect>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@ -1,11 +1,3 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
defineProps<{
|
|
||||||
/** 异常类型 403 404 500 */
|
|
||||||
type: '403' | '404' | '500'
|
|
||||||
}>()
|
|
||||||
const router = useRouter()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex-col-center h-full">
|
<div class="flex-col-center h-full">
|
||||||
<img
|
<img
|
||||||
@ -34,3 +26,11 @@ const router = useRouter()
|
|||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{
|
||||||
|
/** 异常类型 403 404 500 */
|
||||||
|
type: '403' | '404' | '500'
|
||||||
|
}>()
|
||||||
|
const router = useRouter()
|
||||||
|
</script>
|
||||||
|
|||||||
@ -1,11 +1,3 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
interface Props {
|
|
||||||
message: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const { message } = defineProps<Props>()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<n-tooltip :show-arrow="false" trigger="hover">
|
<n-tooltip :show-arrow="false" trigger="hover">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
@ -14,3 +6,11 @@ const { message } = defineProps<Props>()
|
|||||||
{{ message }}
|
{{ message }}
|
||||||
</n-tooltip>
|
</n-tooltip>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
interface Props {
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const { message } = defineProps<Props>()
|
||||||
|
</script>
|
||||||
|
|||||||
@ -1,3 +1,69 @@
|
|||||||
|
<template>
|
||||||
|
<n-input-group disabled>
|
||||||
|
<n-button v-if="value" :disabled="disabled" type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<nova-icon :icon="value" />
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
<n-input :value="value" readonly :placeholder="$t('components.iconSelector.inputPlaceholder')" />
|
||||||
|
<n-button type="primary" ghost :disabled="disabled" @click="showModal = true">
|
||||||
|
{{ $t('common.choose') }}
|
||||||
|
</n-button>
|
||||||
|
</n-input-group>
|
||||||
|
<n-modal
|
||||||
|
v-model:show="showModal" preset="card" :title="$t('components.iconSelector.selectorTitle')" size="small" class="w-800px" :bordered="false"
|
||||||
|
>
|
||||||
|
<template #header-extra>
|
||||||
|
<n-button type="warning" size="small" ghost @click="clearIcon">
|
||||||
|
{{ $t('components.iconSelector.clearIcon') }}
|
||||||
|
</n-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<n-tabs :value="currentTab" type="line" animated placement="left" @update:value="handleChangeTab">
|
||||||
|
<n-tab-pane v-for="(list, index) in iconList" :key="list.prefix" :name="index" :tab="list.title">
|
||||||
|
<n-flex vertical>
|
||||||
|
<n-flex size="small">
|
||||||
|
<n-tag
|
||||||
|
v-for="(_v, k) in list.categories" :key="k"
|
||||||
|
:checked="currentTag === k" round checkable size="small"
|
||||||
|
@update:checked="handleSelectIconTag(k)"
|
||||||
|
>
|
||||||
|
{{ k }}
|
||||||
|
</n-tag>
|
||||||
|
</n-flex>
|
||||||
|
|
||||||
|
<n-input
|
||||||
|
v-model:value="searchValue" type="text" clearable
|
||||||
|
:placeholder="$t('components.iconSelector.searchPlaceholder')"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<n-flex :size="2">
|
||||||
|
<n-el
|
||||||
|
v-for="(icon) in visibleIcons" :key="icon"
|
||||||
|
class="hover:(text-[var(--primary-color)] ring-1) ring-[var(--primary-color)] p-1 rounded flex-center"
|
||||||
|
:title="`${list.prefix}:${icon}`"
|
||||||
|
@click="handleSelectIcon(`${list.prefix}:${icon}`)"
|
||||||
|
>
|
||||||
|
<nova-icon :icon="`${list.prefix}:${icon}`" :size="24" />
|
||||||
|
</n-el>
|
||||||
|
<n-empty v-if="visibleIcons.length === 0" class="w-full" />
|
||||||
|
</n-flex>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<n-flex justify="center">
|
||||||
|
<n-pagination
|
||||||
|
v-model:page="currentPage"
|
||||||
|
:item-count="filteredIcons.length"
|
||||||
|
:page-size="200"
|
||||||
|
/>
|
||||||
|
</n-flex>
|
||||||
|
</n-flex>
|
||||||
|
</n-tab-pane>
|
||||||
|
</n-tabs>
|
||||||
|
</n-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
interface Props {
|
interface Props {
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
@ -121,68 +187,5 @@ function clearIcon() {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<style scoped>
|
||||||
<n-input-group disabled>
|
</style>
|
||||||
<n-button v-if="value" :disabled="disabled" type="primary">
|
|
||||||
<template #icon>
|
|
||||||
<nova-icon :icon="value" />
|
|
||||||
</template>
|
|
||||||
</n-button>
|
|
||||||
<n-input :value="value" readonly :placeholder="$t('components.iconSelector.inputPlaceholder')" />
|
|
||||||
<n-button type="primary" ghost :disabled="disabled" @click="showModal = true">
|
|
||||||
{{ $t('common.choose') }}
|
|
||||||
</n-button>
|
|
||||||
</n-input-group>
|
|
||||||
<n-modal
|
|
||||||
v-model:show="showModal" preset="card" :title="$t('components.iconSelector.selectorTitle')" size="small" class="w-800px" :bordered="false"
|
|
||||||
>
|
|
||||||
<template #header-extra>
|
|
||||||
<n-button type="warning" size="small" ghost @click="clearIcon">
|
|
||||||
{{ $t('components.iconSelector.clearIcon') }}
|
|
||||||
</n-button>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<n-tabs :value="currentTab" type="line" animated placement="left" @update:value="handleChangeTab">
|
|
||||||
<n-tab-pane v-for="(list, index) in iconList" :key="list.prefix" :name="index" :tab="list.title">
|
|
||||||
<n-flex vertical>
|
|
||||||
<n-flex size="small">
|
|
||||||
<n-tag
|
|
||||||
v-for="(_v, k) in list.categories" :key="k"
|
|
||||||
:checked="currentTag === k" round checkable size="small"
|
|
||||||
@update:checked="handleSelectIconTag(k)"
|
|
||||||
>
|
|
||||||
{{ k }}
|
|
||||||
</n-tag>
|
|
||||||
</n-flex>
|
|
||||||
|
|
||||||
<n-input
|
|
||||||
v-model:value="searchValue" type="text" clearable
|
|
||||||
:placeholder="$t('components.iconSelector.searchPlaceholder')"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<n-flex :size="2">
|
|
||||||
<n-el
|
|
||||||
v-for="(icon) in visibleIcons" :key="icon"
|
|
||||||
class="hover:(text-[var(--primary-color)] ring-1) ring-[var(--primary-color)] p-1 rounded flex-center"
|
|
||||||
:title="`${list.prefix}:${icon}`"
|
|
||||||
@click="handleSelectIcon(`${list.prefix}:${icon}`)"
|
|
||||||
>
|
|
||||||
<nova-icon :icon="`${list.prefix}:${icon}`" :size="24" />
|
|
||||||
</n-el>
|
|
||||||
<n-empty v-if="visibleIcons.length === 0" class="w-full" />
|
|
||||||
</n-flex>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<n-flex justify="center">
|
|
||||||
<n-pagination
|
|
||||||
v-model:page="currentPage"
|
|
||||||
:item-count="filteredIcons.length"
|
|
||||||
:page-size="200"
|
|
||||||
/>
|
|
||||||
</n-flex>
|
|
||||||
</n-flex>
|
|
||||||
</n-tab-pane>
|
|
||||||
</n-tabs>
|
|
||||||
</n-modal>
|
|
||||||
</template>
|
|
||||||
|
|||||||
@ -1,3 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<n-popselect :value="appStore.lang" :options="options" trigger="click" @update:value="appStore.setAppLang">
|
||||||
|
<CommonWrapper>
|
||||||
|
<icon-park-outline-translate />
|
||||||
|
</CommonWrapper>
|
||||||
|
</n-popselect>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useAppStore } from '@/store'
|
import { useAppStore } from '@/store'
|
||||||
|
|
||||||
@ -14,12 +22,4 @@ const options = [
|
|||||||
]
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<n-popselect :value="appStore.lang" :options="options" trigger="click" @update:value="appStore.setAppLang">
|
|
||||||
<CommonWrapper>
|
|
||||||
<icon-park-outline-translate />
|
|
||||||
</CommonWrapper>
|
|
||||||
</n-popselect>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@ -1,3 +1,16 @@
|
|||||||
|
<template>
|
||||||
|
<n-loading-bar-provider>
|
||||||
|
<n-dialog-provider>
|
||||||
|
<n-notification-provider>
|
||||||
|
<n-message-provider>
|
||||||
|
<slot />
|
||||||
|
<NaiveProviderContent />
|
||||||
|
</n-message-provider>
|
||||||
|
</n-notification-provider>
|
||||||
|
</n-dialog-provider>
|
||||||
|
</n-loading-bar-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useDialog, useLoadingBar, useMessage, useNotification } from 'naive-ui'
|
import { useDialog, useLoadingBar, useMessage, useNotification } from 'naive-ui'
|
||||||
|
|
||||||
@ -20,17 +33,4 @@ const NaiveProviderContent = defineComponent({
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<n-loading-bar-provider>
|
|
||||||
<n-dialog-provider>
|
|
||||||
<n-notification-provider>
|
|
||||||
<n-message-provider>
|
|
||||||
<slot />
|
|
||||||
<NaiveProviderContent />
|
|
||||||
</n-message-provider>
|
|
||||||
</n-notification-provider>
|
|
||||||
</n-dialog-provider>
|
|
||||||
</n-loading-bar-provider>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@ -1,3 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<n-modal
|
||||||
|
v-model:show="visible"
|
||||||
|
:mask-closable="false"
|
||||||
|
:close-on-esc="false"
|
||||||
|
:auto-focus="autoFocus"
|
||||||
|
preset="card"
|
||||||
|
:loading="confirmLoading"
|
||||||
|
:show-icon="false"
|
||||||
|
:style="{
|
||||||
|
width: typeof width === 'number' ? `${width}px` : width,
|
||||||
|
}"
|
||||||
|
class="nova-dialog"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<!-- 头部插槽 -->
|
||||||
|
<template #header>
|
||||||
|
<div v-if="$slots.header" class="nova-dialog-custom-header">
|
||||||
|
<slot name="header" />
|
||||||
|
</div>
|
||||||
|
<div v-else class="nova-dialog-header">
|
||||||
|
<div class="nova-dialog-title">
|
||||||
|
{{ title }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 内容区域 -->
|
||||||
|
<div
|
||||||
|
class="nova-dialog-content"
|
||||||
|
:style="{
|
||||||
|
height: fullscreen ? 'auto' : (typeof height === 'number' ? `${height}px` : height),
|
||||||
|
overflow: height === 'auto' ? 'visible' : 'auto',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<slot name="content" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部操作区域 -->
|
||||||
|
<template #footer>
|
||||||
|
<div v-if="!footerHidden" class="nova-dialog-footer">
|
||||||
|
<NSpace justify="center">
|
||||||
|
<NButton
|
||||||
|
size="medium"
|
||||||
|
@click="handleCancel"
|
||||||
|
>
|
||||||
|
{{ cancelText }}
|
||||||
|
</NButton>
|
||||||
|
<NButton
|
||||||
|
type="primary"
|
||||||
|
size="medium"
|
||||||
|
:loading="confirmLoading"
|
||||||
|
@click="handleConfirm"
|
||||||
|
>
|
||||||
|
{{ confirmText }}
|
||||||
|
</NButton>
|
||||||
|
</NSpace>
|
||||||
|
</div>
|
||||||
|
<div v-else />
|
||||||
|
</template>
|
||||||
|
</n-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, toRefs } from 'vue'
|
import { ref, toRefs } from 'vue'
|
||||||
import { NButton, NSpace } from 'naive-ui'
|
import { NButton, NSpace } from 'naive-ui'
|
||||||
@ -93,69 +156,6 @@ defineExpose({
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<n-modal
|
|
||||||
v-model:show="visible"
|
|
||||||
:mask-closable="false"
|
|
||||||
:close-on-esc="false"
|
|
||||||
:auto-focus="autoFocus"
|
|
||||||
preset="card"
|
|
||||||
:loading="confirmLoading"
|
|
||||||
:show-icon="false"
|
|
||||||
:style="{
|
|
||||||
width: typeof width === 'number' ? `${width}px` : width,
|
|
||||||
}"
|
|
||||||
class="nova-dialog"
|
|
||||||
@close="handleClose"
|
|
||||||
>
|
|
||||||
<!-- 头部插槽 -->
|
|
||||||
<template #header>
|
|
||||||
<div v-if="$slots.header" class="nova-dialog-custom-header">
|
|
||||||
<slot name="header" />
|
|
||||||
</div>
|
|
||||||
<div v-else class="nova-dialog-header">
|
|
||||||
<div class="nova-dialog-title">
|
|
||||||
{{ title }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- 内容区域 -->
|
|
||||||
<div
|
|
||||||
class="nova-dialog-content"
|
|
||||||
:style="{
|
|
||||||
height: fullscreen ? 'auto' : (typeof height === 'number' ? `${height}px` : height),
|
|
||||||
overflow: height === 'auto' ? 'visible' : 'auto',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<slot name="content" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 底部操作区域 -->
|
|
||||||
<template #footer>
|
|
||||||
<div v-if="!footerHidden" class="nova-dialog-footer">
|
|
||||||
<NSpace justify="center">
|
|
||||||
<NButton
|
|
||||||
size="medium"
|
|
||||||
@click="handleCancel"
|
|
||||||
>
|
|
||||||
{{ cancelText }}
|
|
||||||
</NButton>
|
|
||||||
<NButton
|
|
||||||
type="primary"
|
|
||||||
size="medium"
|
|
||||||
:loading="confirmLoading"
|
|
||||||
@click="handleConfirm"
|
|
||||||
>
|
|
||||||
{{ confirmText }}
|
|
||||||
</NButton>
|
|
||||||
</NSpace>
|
|
||||||
</div>
|
|
||||||
<div v-else />
|
|
||||||
</template>
|
|
||||||
</n-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/* 弹框标题样式 */
|
/* 弹框标题样式 */
|
||||||
.nova-dialog :deep(.n-card-header) {
|
.nova-dialog :deep(.n-card-header) {
|
||||||
|
|||||||
@ -1,3 +1,19 @@
|
|||||||
|
<template>
|
||||||
|
<n-icon
|
||||||
|
v-if="icon"
|
||||||
|
:size="size"
|
||||||
|
:depth="depth"
|
||||||
|
:color="color"
|
||||||
|
>
|
||||||
|
<template v-if="isLocal">
|
||||||
|
<i v-html="getLocalIcon(icon)" />
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<Icon :icon="icon" />
|
||||||
|
</template>
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
|
|
||||||
@ -28,19 +44,3 @@ function getLocalIcon(icon: string) {
|
|||||||
return svg[`/src/assets/svg-icons/${svgName}.svg`]
|
return svg[`/src/assets/svg-icons/${svgName}.svg`]
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<n-icon
|
|
||||||
v-if="icon"
|
|
||||||
:size="size"
|
|
||||||
:depth="depth"
|
|
||||||
:color="color"
|
|
||||||
>
|
|
||||||
<template v-if="isLocal">
|
|
||||||
<i v-html="getLocalIcon(icon)" />
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<Icon :icon="icon" />
|
|
||||||
</template>
|
|
||||||
</n-icon>
|
|
||||||
</template>
|
|
||||||
|
|||||||
@ -1,3 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<n-pagination
|
||||||
|
v-if="count > 0"
|
||||||
|
v-model:page="page"
|
||||||
|
v-model:page-size="pageSize"
|
||||||
|
:page-sizes="[10, 20, 30, 50]"
|
||||||
|
:item-count="count"
|
||||||
|
:display-order="displayOrder"
|
||||||
|
show-size-picker
|
||||||
|
@update-page="changePage"
|
||||||
|
@update-page-size="changePage"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
interface Props {
|
interface Props {
|
||||||
count?: number
|
count?: number
|
||||||
@ -19,18 +33,4 @@ function changePage() {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<n-pagination
|
|
||||||
v-if="count > 0"
|
|
||||||
v-model:page="page"
|
|
||||||
v-model:page-size="pageSize"
|
|
||||||
:page-sizes="[10, 20, 30, 50]"
|
|
||||||
:item-count="count"
|
|
||||||
:display-order="displayOrder"
|
|
||||||
show-size-picker
|
|
||||||
@update-page="changePage"
|
|
||||||
@update-page-size="changePage"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
@ -1,46 +1,3 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { computed, h } from 'vue'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
import { useAuthStore } from '@/store/auth'
|
|
||||||
import { coiMsgBox } from '@/utils/coi'
|
|
||||||
import IconUser from '~icons/icon-park-outline/user'
|
|
||||||
import IconLogout from '~icons/icon-park-outline/logout'
|
|
||||||
|
|
||||||
const authStore = useAuthStore()
|
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
// 获取用户信息
|
|
||||||
const userInfo = computed(() => authStore.userInfo)
|
|
||||||
|
|
||||||
// 获取用户显示名称
|
|
||||||
const displayName = computed(() => {
|
|
||||||
if (!userInfo.value)
|
|
||||||
return '未知用户'
|
|
||||||
return userInfo.value.userName || '未知用户'
|
|
||||||
})
|
|
||||||
|
|
||||||
// 获取用户头像
|
|
||||||
const avatar = computed(() => {
|
|
||||||
if (!userInfo.value?.avatar)
|
|
||||||
return ''
|
|
||||||
return userInfo.value.avatar
|
|
||||||
})
|
|
||||||
|
|
||||||
// 处理个人中心点击
|
|
||||||
function handlePersonalCenter() {
|
|
||||||
router.push('/personal-center')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理退出登录
|
|
||||||
function handleLogout() {
|
|
||||||
coiMsgBox('确定要退出登录吗?', '退出确认').then(() => {
|
|
||||||
authStore.logout()
|
|
||||||
}).catch(() => {
|
|
||||||
// 取消操作
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<n-dropdown
|
<n-dropdown
|
||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
@ -93,6 +50,49 @@ function handleLogout() {
|
|||||||
</n-dropdown>
|
</n-dropdown>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, h } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useAuthStore } from '@/store/auth'
|
||||||
|
import { coiMsgBox } from '@/utils/coi'
|
||||||
|
import IconUser from '~icons/icon-park-outline/user'
|
||||||
|
import IconLogout from '~icons/icon-park-outline/logout'
|
||||||
|
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
const userInfo = computed(() => authStore.userInfo)
|
||||||
|
|
||||||
|
// 获取用户显示名称
|
||||||
|
const displayName = computed(() => {
|
||||||
|
if (!userInfo.value)
|
||||||
|
return '未知用户'
|
||||||
|
return userInfo.value.userName || '未知用户'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取用户头像
|
||||||
|
const avatar = computed(() => {
|
||||||
|
if (!userInfo.value?.avatar)
|
||||||
|
return ''
|
||||||
|
return userInfo.value.avatar
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理个人中心点击
|
||||||
|
function handlePersonalCenter() {
|
||||||
|
router.push('/personal-center')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理退出登录
|
||||||
|
function handleLogout() {
|
||||||
|
coiMsgBox('确定要退出登录吗?', '退出确认').then(() => {
|
||||||
|
authStore.logout()
|
||||||
|
}).catch(() => {
|
||||||
|
// 取消操作
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.dark .hover\:bg-gray-50:hover {
|
.dark .hover\:bg-gray-50:hover {
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user