feat(components): 优化布局组件和工具函数

- 更新布局组件(layouts/components/)
  * 优化设置抽屉组件(SettingDrawer.vue)
  * 完善头部通知组件(Notices.vue)
  * 改进用户中心组件(UserCenter.vue)
  * 优化标签栏组件(TabBar.vue)

- 完善工具指令和Hooks
  * 更新复制指令(directives/copy.ts)
  * 优化标签滚动Hook(hooks/useTabScroll.ts)

提升用户界面交互体验
This commit is contained in:
Leo 2025-07-06 00:59:30 +08:00
parent 567e68234b
commit 72540884fa
6 changed files with 39 additions and 27 deletions

View File

@ -1,5 +1,6 @@
import type { App, Directive } from 'vue' import type { App, Directive } from 'vue'
import { $t } from '@/utils' import { $t } from '@/utils'
import { coiMsgError, coiMsgSuccess } from '@/utils/coi'
interface CopyHTMLElement extends HTMLElement { interface CopyHTMLElement extends HTMLElement {
_copyText: string _copyText: string
@ -11,12 +12,12 @@ export function install(app: App) {
function clipboardEnable() { function clipboardEnable() {
if (!isSupported.value) { if (!isSupported.value) {
window.$message.error($t('components.copyText.unsupportedError')) coiMsgError($t('components.copyText.unsupportedError'))
return false return false
} }
if (permissionWrite.value === 'denied') { if (permissionWrite.value === 'denied') {
window.$message.error($t('components.copyText.unpermittedError')) coiMsgError($t('components.copyText.unpermittedError'))
return false return false
} }
return true return true
@ -26,7 +27,7 @@ export function install(app: App) {
if (!clipboardEnable()) if (!clipboardEnable())
return return
copy(this._copyText) copy(this._copyText)
window.$message.success($t('components.copyText.message')) coiMsgSuccess($t('components.copyText.message'))
} }
function updataClipboard(el: CopyHTMLElement, text: string) { function updataClipboard(el: CopyHTMLElement, text: string) {

View File

@ -1,5 +1,6 @@
import type { NScrollbar } from 'naive-ui' import type { NScrollbar } from 'naive-ui'
import { ref, type Ref, watchEffect } from 'vue' import { ref, watchEffect } from 'vue'
import type { Ref } from 'vue'
import { throttle } from 'radash' import { throttle } from 'radash'
export function useTabScroll(currentTabPath: Ref<string>) { export function useTabScroll(currentTabPath: Ref<string>) {

View File

@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { useAppStore } from '@/store' import { useAppStore } from '@/store'
import { coiMsgBox, coiMsgSuccess } from '@/utils/coi'
import LayoutSelector from './LayoutSelector.vue' import LayoutSelector from './LayoutSelector.vue'
const appStore = useAppStore() const appStore = useAppStore()
@ -58,17 +59,21 @@ const palette = [
'#4b4b4b', '#4b4b4b',
] ]
function resetSetting() { async function resetSetting() {
window.$dialog.warning({ try {
title: t('app.resetSettingTitle'), await coiMsgBox(
content: t('app.resetSettingContent'), t('app.resetSettingContent'),
positiveText: t('common.confirm'), t('app.resetSettingTitle'),
negativeText: t('common.cancel'), t('common.confirm'),
onPositiveClick: () => { t('common.cancel'),
appStore.resetAlltheme() 'warning',
window.$message.success(t('app.resetSettingMeaasge')) )
}, appStore.resetAlltheme()
}) coiMsgSuccess(t('app.resetSettingMeaasge'))
}
catch {
//
}
} }
</script> </script>

View File

@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { group } from 'radash' import { group } from 'radash'
import { coiMsgSuccess } from '@/utils/coi'
import NoticeList from '../common/NoticeList.vue' import NoticeList from '../common/NoticeList.vue'
const MassageData = ref<Entity.Message[]>([ const MassageData = ref<Entity.Message[]>([
@ -84,7 +85,7 @@ function handleRead(id: number) {
const data = MassageData.value.find(i => i.id === id) const data = MassageData.value.find(i => i.id === id)
if (data) if (data)
data.isRead = true data.isRead = true
window.$message.success(`id: ${id}`) coiMsgSuccess(`id: ${id}`)
} }
const massageCount = computed(() => { const massageCount = computed(() => {
return MassageData.value.filter(i => !i.isRead).length return MassageData.value.filter(i => !i.isRead).length

View File

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useAuthStore } from '@/store' import { useAuthStore } from '@/store'
import { renderIcon } from '@/utils/icon' import { renderIcon } from '@/utils/icon'
import { coiMsgBox } from '@/utils/coi'
import IconBookOpen from '~icons/icon-park-outline/book-open' import IconBookOpen from '~icons/icon-park-outline/book-open'
import IconGithub from '~icons/icon-park-outline/github' import IconGithub from '~icons/icon-park-outline/github'
import IconLogout from '~icons/icon-park-outline/logout' import IconLogout from '~icons/icon-park-outline/logout'
@ -48,17 +49,21 @@ const options = computed(() => {
}, },
] ]
}) })
function handleSelect(key: string | number) { async function handleSelect(key: string | number) {
if (key === 'loginOut') { if (key === 'loginOut') {
window.$dialog?.info({ try {
title: t('app.loginOutTitle'), await coiMsgBox(
content: t('app.loginOutContent'), t('app.loginOutContent'),
positiveText: t('common.confirm'), t('app.loginOutTitle'),
negativeText: t('common.cancel'), t('common.confirm'),
onPositiveClick: () => { t('common.cancel'),
logout() 'info',
}, )
}) logout()
}
catch {
//
}
} }
if (key === 'userCenter') if (key === 'userCenter')
router.push('/userCenter') router.push('/userCenter')

View File

@ -102,7 +102,6 @@ function handleContextMenu(e: MouseEvent, route: RouteLocationNormalized) {
function onClickoutside() { function onClickoutside() {
showDropdown.value = false showDropdown.value = false
} }
</script> </script>
<template> <template>