完成布局配置多语言的功能
上节课我们遗留了一个多语言的问题,当我们切换多语言的时候,我们需要同时修改i18n中的多语言信息,上节课我们只修改了我们自定义的多语言。我们先来解决一下这个遗留的问题。 在auto-lang.ts中添加:
import { defaultLocale, loadLanguageAsync } from '~/locales'
export const useAppLocale = createGlobalState(() => useStorage('locale', defaultLocale))
export const useAutoLang = () => {
const appLocale = useAppLocale()
+ const { locale, getLocaleMessage } = useI18n()
const setLanguage = async (lang: string) => {
try {
await loadLanguageAsync(lang)
appLocale.value = lang
+ locale.value = lang
}
catch (e) {
}
}
watch(appLocale, (lang) => {
+ if (lang && lang !== locale.value)
setLanguage(lang).then(() => {})
})
+ const naiveLocale = computed(() => getLocaleMessage(appLocale.value).naiveUI || {})
return {
naiveLocale,
}
}
测试效果在pages/index.vue.
接下来将我们之前所实现的布局功能我们来支持一下多语言。 首先我们先在lang目录下创建一个global的文件夹,然后创建zh-CN.ts和en-US.ts的文件。 在zh-CN.ts中:
export default {
'global.layout.setting.drawer.style': '整体风格设置',
'global.layout.setting.drawer.style.light': '亮色菜单风格',
'global.layout.setting.drawer.style.inverted': '反转色菜单风格',
'global.layout.setting.drawer.style.dark': '黑暗菜单风格',
'global.layout.setting.drawer.theme': '主题色',
'global.layout.setting.drawer.theme.default': '极光绿(默认)',
'global.layout.setting.drawer.theme.dustRed': '薄暮',
'global.layout.setting.drawer.theme.volcano': '火山',
'global.layout.setting.drawer.theme.orange': '日暮',
'global.layout.setting.drawer.theme.cyan': '明青',
'global.layout.setting.drawer.theme.blue': '拂晓蓝',
'global.layout.setting.drawer.theme.purple': '酱紫',
'global.layout.setting.drawer.theme.magenta': '洋红',
'global.layout.setting.drawer.layout': '导航模式',
'global.layout.setting.drawer.layout.side': '侧边菜单布局',
'global.layout.setting.drawer.layout.mix': '混合菜单布局',
'global.layout.setting.drawer.layout.top': '顶部菜单布局',
}
在 en-US.ts中:
export default {
'global.layout.setting.drawer.style': 'Page style setting',
'global.layout.setting.drawer.style.light': 'Light menu style',
'global.layout.setting.drawer.style.inverted': 'Inverted menu style',
'global.layout.setting.drawer.style.dark': 'Dark menu style',
'global.layout.setting.drawer.theme': 'Theme color',
'global.layout.setting.drawer.theme.default': 'Pine green (default)',
'global.layout.setting.drawer.theme.dustRed': 'Dust Red',
'global.layout.setting.drawer.theme.volcano': 'Volcano',
'global.layout.setting.drawer.theme.orange': 'Sunset',
'global.layout.setting.drawer.theme.cyan': 'Cyan',
'global.layout.setting.drawer.theme.blue': 'Blue',
'global.layout.setting.drawer.theme.purple': 'Purple',
'global.layout.setting.drawer.theme.magenta': 'Magenta',
'global.layout.setting.drawer.layout': 'Navigation mode',
'global.layout.setting.drawer.layout.side': 'Side menu layout',
'global.layout.setting.drawer.layout.mix': 'Mix menu layout',
'global.layout.setting.drawer.layout.top': 'Top menu layout',
}
然后我们在lang文件夹中的zh-CN.ts和en-US.ts中分别引入: zh-CN.ts
import { dateZhCN, zhCN } from 'naive-ui'
+ import global from './global/zh-CN'
export default {
+ ...global,
naiveUI: {
locale: zhCN,
dateLocale: dateZhCN,
},
}
en-US.ts
import { dateEnUS, enUS } from 'naive-ui'
+ import global from './global/en-US'
export default {
+ ...global,
naiveUI: {
locale: enUS,
dateLocale: dateEnUS,
},
}
接下来我们在setting-drawer中进行配置支持多语言: 在index.vue中
<template>
<n-drawer-content>
+- <Container v-if="layoutStyleList" :title="$t('global.layout.setting.drawer.style')">
<n-space size="large">
<template v-for="item in layoutStyleList" :key="item.id">
<CheckboxLayout
+- :title="$t(item.title)"
:layout="item.key"
:inverted="item.inverted"
:dark="item.dark"
:checked="item.id === layoutStyle"
@click="() => $emit('update:layoutStyle', item.id)"
/>
</template>
</n-space>
</Container>
+- <Container v-if="themeList" :title="$t('global.layout.setting.drawer.theme')">
<n-space>
<CheckboxTheme
v-for="item in themeList"
:key="item.key"
:color="item.color"
:checked="item.key === theme"
@click="onThemeChange(item.key)"
/>
</n-space>
</Container>
<n-divider />
+- <Container v-if="layoutList" :title="$t('global.layout.setting.drawer.layout')">
<n-space size="large">
<template v-for="item in layoutList" :key="item.key">
<CheckboxLayout
+- :title="$t(item.title)"
:layout="item.key"
:checked="item.key === layout"
@click="() => $emit('update:layout', item.key)"
/>
</template>
</n-space>
</Container>
</n-drawer-content>
</template>
接下来我们让我们的主题色也支持一下提示,在checkbox-theme.vue中。
<script lang="ts" setup>
import { CheckOutlined } from '@vicons/antd'
defineProps<{
color: string
checked?: boolean
+ title?: string
}>()
+ defineEmits(['click'])
</script>
<template>
+ <n-tooltip trigger="hover">
+ <template #trigger>
<div
:style="{ background: color }"
class="flex items-center justify-center w-20px h-20px"
@click="$emit('click', $event)"
>
<n-icon v-if="checked" size="16">
<CheckOutlined />
</n-icon>
</div>
+ </template>
+ {{ title }}
+ </n-tooltip>
</template>
<style scoped>
</style>
然后在index.vue中主题色的多语言的支持:
<template>
<CheckboxTheme
v-for="item in themeList"
:key="item.key"
:title="$t(item.title)"
:color="item.color"
:checked="item.key === theme"
@click="onThemeChange(item.key)"
/>
</template>
接下来我们在stores/app.ts中做调整如下:
const layoutList = computed<LayoutType[]>(() => {
return [{
id: 'side',
key: 'side',
title: 'global.layout.setting.drawer.layout.side',
}, {
id: 'top',
key: 'top',
title: 'global.layout.setting.drawer.layout.top',
}, {
id: 'mix',
key: 'mix',
title: 'global.layout.setting.drawer.layout.mix',
}]
})
const layoutStyleList = computed<LayoutType[]>(() => {
const list: LayoutType[] = [
{
id: 'light',
key: 'side',
title: 'global.layout.setting.drawer.style.light',
},
]
if (layout.layout !== 'mix') {
list.push({
id: 'inverted',
key: 'side',
inverted: true,
title: 'global.layout.setting.drawer.style.inverted',
})
}
else {
if (layout.layoutStyle !== 'dark')
updateLayoutStyle('light')
}
list.push({
id: 'dark',
key: 'side',
title: 'global.layout.setting.drawer.style.dark',
dark: true,
})
return list
})
然后让主题色支持多语言的提示信息。 在config/theme.ts中增加类型
export interface ThemeType {
color: string
key: string
+ title?: string
}
然后在app.ts中增加:
const themeList = computed<ThemeType[]>(() => {
const list = []
const myColors = isDark.value ? darkColors : colors
for (const key in myColors) {
const value = myColors[key]
list.push({
color: value.common?.primaryColor as string,
key,
+ title: `global.layout.setting.drawer.theme.${key}`,
})
}
return list
})
然后测试效果。