闲扯 vue3出来好一段时间了,我一直也没怎么用,因为公司项目一开始用的vue2。迫于前端太卷,要时刻学习,跟进时代,最近着手用vue3+vite写一个练手项目。先不透露项目是啥,后面会开源的。 刚开始写vue3时也是处处不顺,因为思维还停留在vue2上,慢慢习惯了也还不错。个人感觉vue3学习了React的优点,把响应式这块完全丢给用户了。 习惯了vue全家桶一把梭,且没写过React的人可能有点适应不过来。 简介 不用第三方i18n是因为我觉得i18n应该是一个很简单的,自己实现的功能 目标: 更改语言后,所有的$i18n()均要同步更改 <template> <span>{{ $i18n('articles') }}</span> </template> 这个博客项目的i18n都是我自己写的,因为基于vue2,就简单地在Vue.prototype上加一个函数就行了: const i18n = [ { name: '中文', default: true, values: { articles: '文章', // ... ... } },{ name: 'English', values: { articles: 'Articles', // ... ... } } ] Vue.prototype.$i18n = function (value){ const langs = i18n.find(v=>v.name===this.$store.state.lang)||i18n.find(v=>!!v.default) return langs.values[value]!==undefined?langs.values[value]:value }vue3实现 在vue3中,其实已经不需要用vuex了,vue3提供的ref,reactive,computed和provide,inject已经够用了,而且很轻量。 于是乎,我就想着能不能把之前项目的i18n转到vue3上来。简单写了下,确实实现了,但不知性能如何,下面贴代码和注释: /** * main.ts */ import { createApp, ref } from 'vue'; import {defaultLang} from "./i18n"; // 给app加一个全局ref属性:lang const app = createApp(App); app.config.globalProperties.$lang = ref(localStorage.getItem("lang")||defaultLang) // ... .../** * i18n.ts * 这个挺简单的,就是单纯i18n的实现 */ import { computed } from 'vue' export const langMap = [ { name: '中文', values: { articles: '文章', // ... ... } },{ name: 'English', values: { articles: 'Articles', // ... ... } }, ] export const defaultLang = "中文" export default function (val: string){ return computed(()=>{ const lang = langMap.find(v=>v.name===this.$lang.value); if (lang){ return lang.values[val] } return val }).value // 返回 computed().value } 由于i18n基本所有地方都会用到,所以我干脆把它放到mixin里了。这样的话,所有vue组件都会有一个$i18n方法,而且这个方法返回的是一个computed(xxx).value,所以它会自动更新。 /** * i18n-mixin.ts */ import i18n from '../i18n' export default { // ... ... methods:{ // this 会传到 i18n $i18n: i18n } } 说明:需要在所有vue里把这个mixin手动引入(即mixins: [i18nMixin]),这是目前已知的缺点。(更新:深入学习vue3后,发现有更好的方法,使用composition api实现i18n模块化解耦)
如何简单地在vue3中实现i18n
闲扯
vue3出来好一段时间了,我一直也没怎么用,因为公司项目一开始用的vue2。迫于前端太卷,要时刻学习,跟进时代,最近着手用vue3+vite写一个练手项目。先不透露项目是啥,后面会开源的。 刚开始写vue3时也是处处不顺,因为思维还停留在vue2上,慢慢习惯了也还不错。个人感觉vue3学习了React的优点,把响应式这块完全丢给用户了。 习惯了vue全家桶一把梭,且没写过React的人可能有点适应不过来。
简介
不用第三方i18n是因为我觉得i18n应该是一个很简单的,自己实现的功能
目标: 更改语言后,所有的
$i18n()
均要同步更改<template> <span>{{ $i18n('articles') }}</span> </template>
这个博客项目的i18n都是我自己写的,因为基于vue2,就简单地在
Vue.prototype
上加一个函数就行了:const i18n = [ { name: '中文', default: true, values: { articles: '文章', // ... ... } },{ name: 'English', values: { articles: 'Articles', // ... ... } } ] Vue.prototype.$i18n = function (value){ const langs = i18n.find(v=>v.name===this.$store.state.lang)||i18n.find(v=>!!v.default) return langs.values[value]!==undefined?langs.values[value]:value }
vue3实现
在vue3中,其实已经不需要用
vuex
了,vue3提供的ref
,reactive
,computed
和provide
,inject
已经够用了,而且很轻量。 于是乎,我就想着能不能把之前项目的i18n转到vue3上来。简单写了下,确实实现了,但不知性能如何,下面贴代码和注释:/** * main.ts */ import { createApp, ref } from 'vue'; import {defaultLang} from "./i18n"; // 给app加一个全局ref属性:lang const app = createApp(App); app.config.globalProperties.$lang = ref(localStorage.getItem("lang")||defaultLang) // ... ...
/** * i18n.ts * 这个挺简单的,就是单纯i18n的实现 */ import { computed } from 'vue' export const langMap = [ { name: '中文', values: { articles: '文章', // ... ... } },{ name: 'English', values: { articles: 'Articles', // ... ... } }, ] export const defaultLang = "中文" export default function (val: string){ return computed(()=>{ const lang = langMap.find(v=>v.name===this.$lang.value); if (lang){ return lang.values[val] } return val }).value // 返回 computed().value }
由于i18n基本所有地方都会用到,所以我干脆把它放到mixin里了。这样的话,所有vue组件都会有一个
$i18n
方法,而且这个方法返回的是一个computed(xxx).value
,所以它会自动更新。/** * i18n-mixin.ts */ import i18n from '../i18n' export default { // ... ... methods:{ // this 会传到 i18n $i18n: i18n } }
说明:需要在所有vue里把这个mixin手动引入(即
mixins: [i18nMixin]
),这是目前已知的缺点。(更新:深入学习vue3后,发现有更好的方法,使用composition api
实现i18n
模块化解耦)