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
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
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
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
2
3
4
5
6
注意,在 setup 脚本中,一般使用 useI18n 方法来获取,通用的方式是使用 i18n.global.t(),该方法可以在所有 js/ts 文件中使用。 见issue (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
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
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
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
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 变量,它最终会直接在网站生效。但它的缺陷也很明显,就是无法生成统一主题色,需要一个个设置。
上次更新: 2022/03/31, 18:10:01