夜听城嚣 夜听城嚣
首页
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 前端基建与架构
  • 专题分享

    • Git入门与开发
    • 前端面试题汇总
    • HTML和CSS知识点
  • 项目实践
  • 抓包工具
  • 知识管理
  • 工程部署
  • 团队规范
bug知多少
  • 少年歌行
  • 青年随笔
  • 文海泛舟
  • 此事躬行

    • 项目各工种是如何协作的
    • TBA课程学习
收藏

dwfrost

前端界的小学生
首页
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 前端基建与架构
  • 专题分享

    • Git入门与开发
    • 前端面试题汇总
    • HTML和CSS知识点
  • 项目实践
  • 抓包工具
  • 知识管理
  • 工程部署
  • 团队规范
bug知多少
  • 少年歌行
  • 青年随笔
  • 文海泛舟
  • 此事躬行

    • 项目各工种是如何协作的
    • TBA课程学习
收藏
  • 读书笔记

  • 专题分享

  • 项目实践

    • 圣诞节活动总结
    • vite踩坑之旅
    • vue3踩坑之旅
      • typescript实践
      • 迁移支付宝小程序踩坑记录
      • electron制作小程序上传工具总结
    • 框架应用

    • 前端一览
    • 项目实践
    frost
    2022-01-28

    vue3踩坑之旅

    # 引入 i18n v9

    为了兼容 vue3,i18n 官方升级到了 v9 版本,见文档 (opens new window)。使用方式如下:

    npm install vue-i18n@next
    
    1

    直接上代码,且加上 vant 国际化。

    // src/i18n/index.ts
    import { createI18n } from 'vue-i18n'
    
    import { Locale } from 'vant'
    // 引入英文语言包
    import zhCN from 'vant/es/locale/lang/zh-CN'
    import enUS from 'vant/es/locale/lang/en-US'
    import zhTW from 'vant/es/locale/lang/zh-TW'
    import ja from 'vant/es/locale/lang/ja-JP'
    
    import messages from './langs/index'
    import { store } from '@/store'
    
    // vant切换语言
    // https://vant-contrib.gitee.io/vant/v3/#/zh-CN/locale
    export const vantLocals = (lang: string) => {
      store.commit('changeLanguage', lang)
      switch (lang) {
        case 'cn':
          Locale.use('cn', zhCN)
          break
        case 'tw':
          Locale.use('tw', zhTW)
          break
        case 'en':
          Locale.use('en-US', enUS)
          break
        case 'ja':
          Locale.use('ja', ja)
          break
        case 'ko':
          // vant不支持韩文
          Locale.use('ko', enUS)
          break
        default:
          Locale.use('en', enUS)
          break
      }
    }
    
    const locale: string = store.state.present_language || 'en'
    vantLocals(locale)
    
    // https://vue-i18n.intlify.dev/
    export const i18n = createI18n({
      locale,
      messages,
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    import { createApp } from 'vue'
    
    import App from './App.vue'
    
    import { i18n } from './i18n'
    
    createApp(App)
      .use(i18n)
      .mount('#app')
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    使用如下

    <template>
      <div class="TestI18n-wrap">
        <van-button @click="change('cn')">中文</van-button>
        <van-button @click="change('en')">en</van-button>
        <p>{{ $t('message.hello') }}</p>
        <van-button @click="look">点击查看</van-button>
        <van-button @click="jslook">js点击查看</van-button>
        <van-calendar title="日历" :poppable="false" :show-confirm="false" :style="{ height: '500px' }" />
      </div>
    </template>
    <script setup lang="ts">
    type LangType = 'cn' | 'en' | 'ja'
    import { ref } from 'vue'
    import { useStore } from 'vuex'
    const store = useStore()
    
    import { i18n, vantLocals } from '@/i18n'
    import { useI18n } from 'vue-i18n'
    const { t } = useI18n()
    
    const change = (lang: LangType) => {
      i18n.global.locale = lang
      vantLocals(lang)
    }
    
    const look = () => {
      console.log(t('message.hello'))
      console.log('look', i18n.global.t('message.hello'))
    }
    
    import { jslook } from './util'
    </script>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    // ./util.ts
    import { i18n } from '@/i18n'
    
    export const jslook = () => {
      console.log(i18n.global.t('message.hello'))
    }
    
    1
    2
    3
    4
    5
    6

    注意,在 setup 脚本中,一般使用 useI18n 方法来获取,通用的方式是使用 i18n.global.t(),该方法可以在所有 js/ts 文件中使用。 见issue (opens new window)。

    # 自定义主题

    官方文档-自定义主题 (opens new window)

    官方提供了 2 种方式来自定义主题,如下

    • 通过 SCSS 变量
    • 通过 CSS 变量

    # 通过 SCSS 变量

    参考官方 demo (opens new window),需要安装unplugin-vue-components依赖,否则自定义主题不生效。

    npm i unplugin-vue-components -D
    
    1
    // vite.config.ts
    // 无需注册el-组件,会自动引入
    import Components from 'unplugin-vue-components/vite';
    import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
    
    export default defineConfig(({ mode }) => {
        css: {
          postcss: {
            plugins: [],
          },
          // https://cn.vitejs.dev/config/#css-preprocessoroptions
          preprocessorOptions: {
            scss: {
              // 全局scss变量
              additionalData: `@use "@/assets/css/customTheme.scss" as *;@use "@/assets/css/globalVariable.scss" as *;`,
            },
          },
        },
        plugins: [
            Components({
              // allow auto load markdown components under `./src/components/`
              extensions: ['vue', 'md'],
              // allow auto import and register components used in markdown
              include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
              resolvers: [
                ElementPlusResolver({
                  importStyle: 'sass',
                }),
              ],
              dts: 'src/components.d.ts', // 会自动生成一个components.d.ts文件
            }),
        ]
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    // main.ts
    import { createApp } from 'vue'
    import App from './App.vue'
    
    // 使用unplugin-vue-components/后就不需要下面一行了
    // import ElementPlus from 'element-plus';
    // import 'element-plus/dist/index.css'; // 如果cdn引入css,就不需要这一行了
    
    createApp(App).mount('#app')
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // @/assets/css/customTheme.scss
    // https://element-plus.gitee.io/zh-CN/guide/theming.html
    $--colors: (
      'primary': (
        'base': green,
      ),
      'success': (
        'base': #21ba45,
      ),
      'warning': (
        'base': #f2711c,
      ),
      'danger': (
        'base': #db2828,
      ),
      'error': (
        'base': #db2828,
      ),
      'info': (
        'base': #42b8dd,
      ),
    );
    
    @forward 'element-plus/theme-chalk/src/common/var.scss' with (
       // do not use same name, it will override.
       $colors: $--colors,
       $button-padding-horizontal: ("default": 50px)
    );
    
    // if you want to import all
    // @use "element-plus/theme-chalk/src/index.scss" as *;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    注意必须安装unplugin-vue-components依赖。另外,此依赖安装后,main.ts 中就不需要引入 element-plus 了,它也会帮我们全局注册 el-组件。

    # 通过 CSS 变量

    这个方式更简单,直接在 App.vue 下设置 css var 变量即可。

    <style>
      :root {
        --el-color-primary: #15ae6d;
      }
      .el-tag {
        --el-tag-text-color: red;
      }
      .el-button--primary {
        --el-button-font-color: #ffffff;
        --el-button-background-color: #15ae6d;
        --el-button-border-color: #15ae6d;
        --el-button-hover-color: #15ae6d;
        --el-button-active-font-color: #e6e6e6;
        --el-button-active-background-color: #15ae6d;
        --el-button-active-border-color: #15ae6d;
      }
    </style>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    此方式简单,但不会统一修改主题色,需要一个组件一个设置类名来覆盖,比较繁琐。

    而 SCSS 变量修改会根据 base 的基础色,自动设置相应层次的色值,比如品牌色,次级品牌色,置灰色等等,当然也可以进行相应的覆盖。

    # cdn 引入可以自定义主题吗

    看情况,SCSS 变量不可以,CSS 变量可以。

    官方建议如果使用 cdn 引入方式,需要自己构建。见issue (opens new window)。

    不过,可以自定义 CSS 变量,它最终会直接在网站生效。但它的缺陷也很明显,就是无法生成统一主题色,需要一个个设置。

    #最佳实践#vue
    上次更新: 2022/03/31, 18:10:01
    vite踩坑之旅
    typescript实践

    ← vite踩坑之旅 typescript实践→

    最近更新
    01
    提交代码时修改commit消息
    04-09
    02
    如何快速定位bug
    02-20
    03
    云端web项目开发踩坑
    08-25
    更多文章>
    Theme by Vdoing | Copyright © 2021-2025 dwfrost | 粤ICP备2021118995号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式
    ×