Skip to content

Vue

本节主要介绍如何在Vue 3应用中使用VoerkaI18n

创建Vue 3应用一般采用ViteVue Cli来创建工程。在Vue3应用中引入voerkai18n来添加国际化应用需要由两个插件来简化应用。

  • @voerkai18n/vue

    Vue插件,在初始化Vue应用时引入,提供访问当前语言切换语言自动更新等功能。

  • @voerkai18n/plugins

    编译期插件,在vite.config.js中配置,用来实现自动文本映射等功能,参考IdMap

使用方法

第1步:安装依赖

首先安装@voerkai18n/cli到全局.

bash
npm install -g @voerkai18n/cli
bash
yarn global add @voerkai18n/cli
bash
pnpm  add -g @voerkai18n/cli

第2步:初始化

接着VoerkaI18n init初始化工程。

bash
> voerkai18n init

初始化完成后,会创建一个语言工作目录,默认位置是src/languages。文件夹结构如下:

  • myapp
    • src
      • languages
        • messages
        • paragraphs
        • translates/提取需要翻译的内容
          • messages提取的需要翻译的内容
          • paragraphs提取的需要翻译的段落
        • prompts执行AI翻译的相关提示词
        • api.json API接口
        • component.ts 翻译组件
        • index.ts 入口文件
        • settings.json 配置文件
        • storage.ts 存储管理
        • loader.ts 加载器
        • transform.ts 翻译变换
        • formatters.json 格式化器配置
    • package.json
    • index.ts

第3步:启用Vue支持

接下需要voerkai18n apply来启用Vue支持。

bash
> voerkai18n apply

执行voerkai18n apply命令后,选择Vue3后,会执行以下操作:

  • 安装@voerkai18n/vue
  • 更新languages的相关文件,主要是languages/component.{ts|js}

第4步:配置应用

修改main.ts文件,引入@voerkai18n/vue

ts
import { i18nScope } from "./languages"
import { router } from "./router"
import { i18nPlugin } from '@voerkai18n/vue'

i18nScope.ready(()=>{
    createApp(App)
      .use(i18nPlugin,{         
        i18nScope               
      })                        
      .use(router)
      .mount('#app')
})

i18nPlugin插件的作用为Vue组件提供:

  • 提供全局组件实例t函数
  • 全局的Translate组件
  • $t函数提供响应式支持

第5步:配置插件

修改vite.config.{ts|js}文件,引入@voerkai18n/plugins/vite

ts
import i18nPlugin from '@voerkai18n/plugins/vite'

module.exports = {
    configureWebpack: {
      plugins: [
        vue(),
        i18nPlugin()
      ] 
    }
  }
  • @voerkai18n/plugins/vite插件的作用为Vue应用提供自动文本映射功能。

第6步:翻译内容

接下来就可以直接在Vue组件中使用t函数和Translate组件进行翻译。

vue
<template>
	<div>
        <h1>
          <Translate message="请输入用户名称"/>
        </h1>
        <div>
            <span>
              <Translate message="用户名:" />
            </span>
            <input type="text" :placeholder="t('邮件/手机号码/帐号')"/>
            <span>
              <Translate message="密码:" />
            </span>
            <input type="password" :placeholder="t('至少6位的密码')"/>            
            <Translate id="notice">
              大段文本内容
            </Translate>
    	</div>            
    </div>
        <button @click="login">
          <Translate message="登录" />
        </button>
    </div>
</template>

提示

  • 使用t函数和Translate组件时来包裹要翻译的内容。
  • 大段落文本内容可以使用Translate组件来包裹。
  • t函数和Translate已经由@voerkai18n/vue插件自动注入到组件中,不需要额外导入。

第7步:切换语言

引入useVoerkaI18n来实现切换语言的功能。

vue
<template>
  <div>
    <button  
      v-for="(lang, index) in languages"
      @click="i18nScope.change(lang.name)"
      type="button"       
      :class="{'red-text': activeLanguage === lang.name }"
      >  
      {{ lang.name }}     
      </button>
  </div>
</template>

<script setup>
import { i18nScope} from './languages';
import { useVoerkaI18n } from '@voerkai18n/vue';   
const { activeLanguage,languages } =  useVoerkaI18n(i18nScope)
</script>

指南

手动配置

voerkai18n apply负责自动配置Vue应用支持,也可以手动配置.

  • 编辑languages/component.{ts|js}文件
ts
import { 
  createTranslateComponent, 
  type VueTranslateComponentType 
} from "@voerkai18n/vue";
export const component = createTranslateComponent()
export type TranslateComponentType = VueTranslateComponentType
  • 编辑languages/transform.{ts|js}文件
ts
import { createTranslateTransform,type VueTransformResultType } from "@voerkai18n/vue"
export const transform = createTranslateTransform()
export type TransformResultType = VueTransformResultType

启用插件

ts
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { i18nScope } from "./languages"
import { router } from "./router"
import { i18nPlugin } from '@voerkai18n/vue'

i18nScope.ready(()=>{
    createApp(App)
        .use(i18nPlugin,{i18nScope})
        .use(router)
        .mount('#app')
})

插件参数:

参数 类型 默认值 说明
scope VoerkaI18nScope 语言作用域

启用i18nPlugin插件后

  • 提供一个全局t函数,可以全局直接访问。这样就不用再在每个组件中额外引入t函数了
  • 提供一个全局$activeLangauge属性代表当前激活的语言,该属性是一个ref对象,会在切换文时自动更新。
  • 提供一个全局Translate组件,这样就可以在组件中直接使用Translate组件了,不需要额外导入。

翻译组件

使用voerkai18n apply -f vue后,会更新languages/component.ts,导出一个Vue 3组件,该组件可以在切换语言时自动重新渲染。也可以手动更新修改languages/component.ts,内容如下:

ts
import { 
    createTranslateComponent, 
    type VueTranslateComponentType 
} from "@voerkai18n/vue";
export const component = createTranslateComponent(<options>) 
export type TranslateComponentType = VueTranslateComponentType

创建参数

createTranslateComponent方法用来构建Vue组件,类型如下:

ts
type CreateTranslateComponentOptions = {
    default?: string
    tagName?: string 
    class?  : string
    style?  : string
    loading?: Component | boolean | string
}
参数 类型 默认值 说明
default string 默认显示文本
tagName string div 标签名称
class string CSS类名
style string CSS样式
loading Component 是否显示加载中
  • loading参数用来提供一个加载中的Vue组件,当加载远程文本时显示。加载中组件仅在message参数是一个Function或提供段落id时有效。

组件参数

ts
type VoerkaI18nTranslateProps<
  Options extends VoerkaI18nTranslateOptions = VoerkaI18nTranslateOptions,
  Children = any> = {
    id?       : string;
    message?  : VoerkaI18nToBeTranslatedMessage;
    vars?     : VoerkaI18nTranslateVars;
    default?  : any;
    tag?      : string;
    options?  : Options;
    children? : Children;
    style?    : any;
    className?: string;
}
参数 类型 默认值 说明
id string 可选,段落ID
message VoerkaI18nToBeTranslatedMessage 可选,要翻译的文本
vars VoerkaI18nTranslateVars 可选,插值变量
default any 可选,默认文本
tag string 可选,标签名称
options Options 可选,选项
children Children 可选,子组件
style any 可选,样式
className string 可选,CSS类名
  • idmessage二选一,id优先级高于message

翻译变换

使用voerkai18n apply -f vue后会自动配置翻译变换,也可以手动更新languages/transform.ts,内容如下:

ts
import { createTranslateTransform,type VueTransformResultType } from "@voerkai18n/vue"
export const transform = createTranslateTransform()
export type TransformResultType = VueTransformResultType

useVoerkaI18n

useVoerkaI18n是一个Vue3Composition API函数,用来获取VoerkaI18n实例。

ts
import { useVoerkaI18n } from "@voerkai18n/vue"

const { 
  t, 
  activeLanguage,
  defaultLanguage, 
  changeLanguage,
  scope,
  manager
} = useVoerkaI18n()

使用useVoerkaI18n可以渲染出语言切换的组件:

vue
<template>
  <div>
    <button  
      v-for="(lang, index) in languages"
      @click="i18nScope.change(lang.name)"
      type="button"       
      :class="{'red-text': activeLanguage === lang.name }"
      >  
      {{ lang.name }}     
      </button>
  </div>
</template>

<script setup>
import { i18nScope} from './languages';
import { useVoerkaI18n } from '@voerkai18n/vue';   
const { activeLanguage,languages } =  useVoerkaI18n(i18nScope)
</script>

加载中

当使用翻译组件的动态翻译时,允许在翻译过程中显示加载中的状态。

可以按如下方式提供一个加载中的状态:

ts
import { 
  createTranslateComponent, 
  type VueTranslateComponentType 
} from "@voerkai18n/vue";
import Loading from './Loading.vue'  //! 您的加载中组件
export const component = createTranslateComponent({
  loading:Loading   //!
})
export type TranslateComponentType = VueTranslateComponentType

切换刷新陷阱

在使用VoerkaI18n时,新手经常会碰到的问题,就是切换语言后,Vue组件不会自动刷新。

比如以下代码在切换语言时自动刷新渲染:

vue
<template>
  <div>  
    <h1 :title="t('你好')">  
    <div> {{ title }} </div>
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { t } from '../languages'; 
const title = ref(t('你好'))
<script>

为什么以上代码在切换语言后不会自动刷新呢?

因为Vue组件的setup函数只会在组件初始化时执行一次,所以在setup函数中调用t函数时,t函数的执行结果已经固定,所以不会再随着语言的切换而刷新。

如何解决?

要解决这个问题,需要充分理解Vue的晌应式机制

  • 让翻译的结果成为响应式数据
  • 在语言切换时更新翻译的结果

重点就是让翻译的结果成为响应式数据,这样在语言切换时,Vue才会自动更新视图。

聪明的你一定想到了,可以使用ref等响应式API来包装翻译的结果,这样就可以实现自动刷新。

vue
<template>
  <div>  
    <div :title="t('你好')"> {{ title }} </div>
  </div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { t, i18nScope } from '../languages';

const title = ref(t('你好'))  

let subscriber
onMounted(()=>{
  subscriber = i18nScope.on('change',()=>{
    title.value = t('你好')
  })
})
onUnmounted(()=>{
  subscriber.off()
})
<script>

当语言切换时,i18nScope会触发change事件,我们在onMounted钩子中订阅change事件,当语言切换时,更新title的值,由于title是一个响应式值,所以这样就实现了自动刷新。

显然,这种方式比较繁琐,针对此种场景,VoerkaI18n提供了翻译变换机制来简化这个过程,参考翻译变换

引入翻译变换机制后,以上代码可以简化为:

vue
<template>
  <div>  
    <div :title="t('你好')"> {{ title }} </div>
  </div>
</template>
<script setup>
import { $t } from '../languages';
const title = $t('你好')
<script>
  • $t函数返回的是一个响应式值,所以在语言切换时,Vue会自动刷新视图。
  • $t函数会将翻译的结果转换为响应式数据,所以在语言切换时,Vue会自动刷新视图。
  • $t函数工作需要配合@voerkai18n/vue才可以工作。

提示

事实上,在所有响应式框架中,都会遇到这个问题,只要理解了响应式机制,就能很好的解决这个问题。

示例