工具完成
This commit is contained in:
53
src/composables/useLanguage.ts
Normal file
53
src/composables/useLanguage.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import type { Language } from '@/types/tools'
|
||||
import { locales } from '@/config/i18n'
|
||||
|
||||
// 全局语言状态
|
||||
const currentLanguage = ref<Language>('zh')
|
||||
|
||||
export const useLanguage = () => {
|
||||
// 获取当前语言的翻译对象
|
||||
const translation = computed(() => locales[currentLanguage.value])
|
||||
|
||||
// 翻译函数
|
||||
const t = (key: string, params?: Record<string, string>) => {
|
||||
const keys = key.split('.')
|
||||
let value: any = translation.value
|
||||
|
||||
for (const k of keys) {
|
||||
value = value?.[k]
|
||||
}
|
||||
|
||||
let result = value || key
|
||||
|
||||
// 替换参数
|
||||
if (params && typeof result === 'string') {
|
||||
Object.keys(params).forEach(param => {
|
||||
result = result.replace(`{${param}}`, params[param])
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// 切换语言
|
||||
const switchLanguage = (lang: Language) => {
|
||||
currentLanguage.value = lang
|
||||
localStorage.setItem('preferred-language', lang)
|
||||
}
|
||||
|
||||
// 从本地存储恢复语言
|
||||
const restoreLanguage = () => {
|
||||
const saved = localStorage.getItem('preferred-language') as Language
|
||||
if (saved && (saved === 'zh' || saved === 'en')) {
|
||||
currentLanguage.value = saved
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
language: currentLanguage,
|
||||
t,
|
||||
switchLanguage,
|
||||
restoreLanguage
|
||||
}
|
||||
}
|
55
src/composables/useTheme.ts
Normal file
55
src/composables/useTheme.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
type Theme = 'light' | 'dark'
|
||||
|
||||
// 全局主题状态
|
||||
const currentTheme = ref<Theme>('dark')
|
||||
|
||||
export const useTheme = () => {
|
||||
// 切换主题
|
||||
const toggleTheme = () => {
|
||||
currentTheme.value = currentTheme.value === 'light' ? 'dark' : 'light'
|
||||
}
|
||||
|
||||
// 设置主题
|
||||
const setTheme = (theme: Theme) => {
|
||||
currentTheme.value = theme
|
||||
}
|
||||
|
||||
// 从本地存储恢复主题
|
||||
const restoreTheme = () => {
|
||||
const saved = localStorage.getItem('preferred-theme') as Theme
|
||||
if (saved && (saved === 'light' || saved === 'dark')) {
|
||||
currentTheme.value = saved
|
||||
} else {
|
||||
// 检测系统主题偏好
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
currentTheme.value = prefersDark ? 'dark' : 'light'
|
||||
}
|
||||
}
|
||||
|
||||
// 应用主题到DOM
|
||||
const applyTheme = (theme: Theme) => {
|
||||
const root = document.documentElement
|
||||
root.setAttribute('data-theme', theme)
|
||||
if (theme === 'dark') {
|
||||
root.classList.add('dark')
|
||||
} else {
|
||||
root.classList.remove('dark')
|
||||
}
|
||||
}
|
||||
|
||||
// 监听主题变化
|
||||
watch(currentTheme, (newTheme) => {
|
||||
applyTheme(newTheme)
|
||||
localStorage.setItem('preferred-theme', newTheme)
|
||||
}, { immediate: true })
|
||||
|
||||
return {
|
||||
theme: currentTheme,
|
||||
toggleTheme,
|
||||
setTheme,
|
||||
restoreTheme,
|
||||
applyTheme
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user