purpose
The project needs to support multiple languages, so we need to extract the static text used in the project and use the language package for management. When switching the language setting, the text display of the whole project can be automatically switched.
The corresponding component VUE-I18N was found in the Vue project, and the code of the project was not changed much, so we used this component to modify the code in the project.
The installation
// script introduces <script SRC ="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-i18n/dist/vue-i18n.js"></script> // NPM install NPM install vue-i18n // yarn install yarn add vue-i18nCopy the code
Generally used in a project is through the installation package to run, script introduced less.
use
The i18N is configured in the project
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
const i18n = new VueI18n({
local: 'cn'}) new Vue({el:'#app'. I18n}) {cn: {name:'name'}, us: {name:'Name'}}Copy the code
The use of i18n
Simple to use
// HTML needs to wrap name around {{}}$t('name')}}
// js
$t('name')
Copy the code
Passable variable
// messages: {cn: {name:'Name: {name}'
},
us: {
name: 'Name: {name}'}}$t('name', {name: 'Jack'}) // messages: {cn: {Name:'Name: {0}{1}'
},
us: {
name: 'Name: {0}{1}'
}
}
// array
$t('name'['Jack'.'Job'])
// object
$t('name', {'0':'Jack'.'1': 'Job'])
Copy the code
The plural format
Use the separator |
// messages:
{
us: {
car: 'car | cars | {count} cars'}}$tc('car', x) // Select different car typesCopy the code
Time format
const dateTimeFormats = {
'us': {
short: {
year: 'numeric', month: 'short', day: 'numeric'
},
long: {
year: 'numeric', month: 'short', day: 'numeric',
weekday: 'short', hour: 'numeric', minute: 'numeric'}}, cn: {XXX}} const i18n = new VueI18n({locale:' ', messages, dateTimeFormats}) // Use$d(new Date(), 'short')
$d(new Date(), 'long')
$d(new Date(), 'short'.'cn')
Copy the code
Amount of symbols
const numberFormats = {
'en-US': {
currency: {
style: 'currency', currency: 'USD'}},'ja-JP': {
currency: {
style: 'currency', currency: 'JPY', currencyDisplay: 'symbol'Const i18n = new VueI18n({numberFormats}) // use$n(100, 'currency') / /The $10000.$n(100, 'currency'.'ja-JP') RMB 100 / /Copy the code
Provide a default language settingfallbackLocale
Provide a default full language to handle when a language does not exist
const messages = {
cn: {
name: 'Name:'} us: {}} const i18n = new VueI18n({locale: locale) {}} const i18n = new VueI18n({locale:'us',
fallbackLocale: 'cn',
messages
})
Copy the code
v-t
Can be used to reference variables, similar to$t
V – t instruction
New Vue({i18n: new VueI18n({locale:'en',
messages: {
en: { hello: 'hi {name}! ' },
ja: { hello: 'Kohii | | | | | | | | | | | | | | | | | | | | | | | | | | | | ' }
}
}),
computed: {
nickName () { return 'kazupon' }
},
data: { path: 'hello'}}).$mount('#object-syntax')
<div id="object-syntax"> <! -- literal --> <p v-t="{ path: 'hello', locale: 'ja', args: { name: 'kazupon' } }"></p> <! -- data biniding via data --> <p v-t="{ path: path, args: { name: nickName } }"></p>
</div>
<div id="object-syntax"> <p> Kohiko: From proverb to proverb! </p> <p>hi kazupon! </p> </div>Copy the code
$t versus v minus t
$t
Is a method call,v-t
It’s an instructionv-t
Performance than$t
Even better, there is a cache of custom instructions$t
It is more flexible and simpler to use
There e are some other uses, please refer to the official documentation for details.
To switch languages, use built-in variables:
// Switch the language this by setting locale.$i18n.locale = cn | us
Copy the code
Insert the components
If encountered such a scenario, how to deal with?
<p>I accept xxx <a href="/term">Terms of Service Agreement</a></p>
Copy the code
My first reaction was to divide it into two fields. Tag A does not belong to the translation content, as long as it is written as:
<p>{{ $t('xx1') }}<a href="/term"> {{$t('xx2') }}</a></p>
Copy the code
This is too unwieldy and can be handled as a component
// I81n <i18n path="term" tag="label" for="tos">
<a :href="url" target="_blank"> {{$t('tos') }}</a>
</i18n>
const messages = {
en: {
tos: 'Term of Service',
term: 'I accept xxx {0}.'
}
}
new Vue({
el: '#app',
i18n,
data: {
url: '/term'}})Copy the code
As you can see, two variables are still used to store information, but the tag is produced by tag and the path specifies the content of the tag.
$t(“)** $t(“)** $t(“)** $t(“)** $t(“)** $t(“)** $t(“)** $t(“)** $t(“)** $t(“)** $t(“)** $t(“)** $t(“)** $t(“)** $t(“)**”
More advanced use, you can control where AN HTML element is inserted, using place to specify where it appears in the HTML.
<i18n path="info" tag="p">
<span place="limit">{{ changeLimit }}</span>
<a place="action" :href="changeUrl"> {{$t('change') }}</a>
</i18n>
const messages = {
en: {
info: 'You can {action} until {limit} minutes from departure.',
change: 'change your flight',
refund: 'refund the ticket'
}
}
const i18n = new VueI18n({
locale: 'en',
messages
})
new Vue({
i18n,
data: {
changeUrl: '/change',
refundUrl: '/refund',
changeLimit: 15,
refundLimit: 30
}
}).$mount('#app')
// result
<p>
You can <a href="/change">change your flight</a> until <span>15</span> minutes from departure.
</p>
Copy the code
The unity of the sentence is preserved, but it may not be used if it is only for multi-language translation of nouns without grammar requirements.
Load language packs dynamically
It is not necessary to load all the language packages at one time, especially if the language packages are used. I also raised this problem before and found that the official website provides a solution.
//i18n-setup.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import messages from '@/lang'// Address of the language package, depending on the project Settings import axios from'axios'Use (VueI18n); use(VueI18n);export const i18n = new VueI18n({
locale: 'en', / /set locale
fallbackLocale: 'en', // Default language Settings, when other languages are not available, use en as the default language messages //set locale messages
})
const loadedLanguages = ['en'] // our default language that is prelaoded
function setI18nLanguage (lang) {
i18n.locale = lang
axios.defaults.headers.common['Accept-Language'] = lang // Set request header document.querySelector('html').setAttribute('lang', lang) // The root element adds the lang attributereturn lang
}
export function loadLanguageAsync (lang) {
if(i18n.locale ! == lang) {if(! loadedLanguages.includes(lang)) {return import(/* webpackChunkName: "lang-[request]" */ `@/lang/${lang}`).then(msgs => {
i18n.setLocaleMessage(lang, msgs.default)
loadedLanguages.push(lang)
return setI18nLanguage(lang)
})
}
return Promise.resolve(setI18nLanguage(lang))
}
returnResolve (lang)} // Handle router in vue-router's beforeEach global hook. BeforeEach ((to, from,) next) => { const lang = to.params.lang loadLanguageAsync(lang).then(() => next()) })Copy the code
Generation of language pack & replacement of original static text in project
This is the most important step,
- Pull out all the characters that appear
- replace
$t('xxx')
.$n
.$d
.v-t
And so on, according to the appropriate situation of their own choice - Maintain multiple versions of language files
Add a new directory languages under the project
- languages - lib - cn. Js / / Chinese language pack -- us. Js / / English language pack -.. // Other languages, not yet implemented -- index.js // Export language packageCopy the code
cn.js
export default {
common: {
message: 'message'
},
xxx: {
}
}
Copy the code
us.js
export default {
common: {
message: 'Messages'
},
xxx: {
}
}
Copy the code
index.js
import cn from './lib/cn.js'
export default {
cn,
us
}
Copy the code
Replace text
<template>
...
<div>{{$t('message')}}</div>
...
</template>
Copy the code
The problem
- Different languages, different formats, different lengths, may need to adjust the style of the project to keep it normal
- For a project that is already in use, generating the language package is a time-consuming and time-consuming step