Skip to content

Latest commit

 

History

History
292 lines (264 loc) · 8.37 KB

30-%E5%B8%83%E5%B1%80%E6%94%AF%E6%8C%81%E5%A4%9A%E8%AF%AD%E8%A8%80.md

File metadata and controls

292 lines (264 loc) · 8.37 KB

目标

完成布局配置多语言的功能

遗留问题解决

上节课我们遗留了一个多语言的问题,当我们切换多语言的时候,我们需要同时修改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
  })

然后测试效果。