前端VUE雙語實(shí)現(xiàn)方案詳細(xì)教程
一、封裝一個(gè)lib包
結(jié)構(gòu)如下

en.js
'use strict';
exports.__esModule = true;
exports.default = {
sp: {
input: {
amountError: 'Incorrect amount format'
},
table: {
total: 'Total:',
selected: 'Selected:',
tableNoData: 'No data',
tableNoDataSubtext: 'Tip: Suggest to recheck your filter.',
tableLoadingData: 'Searching...'
},
select: {
placeholder: 'Select'
},
preview: {
button: 'View'
}
}
};zh-CN.js
'use strict';
exports.__esModule = true;
exports.default = {
sp: {
input: {
amountError: '金額格式不正確'
},
table: {
total: '共計(jì):',
selected: '已選擇:',
tableNoData: '暫無數(shù)據(jù)',
tableNoDataSubtext: '提示:建議核實(shí)篩選條件',
tableLoadingData: '搜索中...'
},
select: {
placeholder: '請選擇'
},
preview: {
button: '查看'
}
}
};index.js
'use strict';
exports.__esModule = true;
exports.i18n = exports.use = exports.t = undefined;
var _zhCN = require('./lang/zh-CN');
var _zhCN2 = _interopRequireDefault(_zhCN);
var _vue = require('vue');
var _vue2 = _interopRequireDefault(_vue);
var _deepmerge = require('deepmerge');
var _deepmerge2 = _interopRequireDefault(_deepmerge);
var _format = require('element-ui/lib/locale/format');
var _format2 = _interopRequireDefault(_format);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var format = (0, _format2.default)(_vue2.default);
var lang = _zhCN2.default;
var merged = false;
var i18nHandler = function i18nHandler() {
var vuei18n = Object.getPrototypeOf(this || _vue2.default).$t;
if (typeof vuei18n === 'function' && !!_vue2.default.locale) {
if (!merged) {
merged = true;
_vue2.default.locale(_vue2.default.config.lang, (0, _deepmerge2.default)(lang, _vue2.default.locale(_vue2.default.config.lang) || {}, { clone: true }));
}
return vuei18n.apply(this, arguments);
}
};
var t = exports.t = function t(path, options) {
var value = i18nHandler.apply(this, arguments);
if (value !== null && value !== undefined) return value;
var array = path.split('.');
var current = lang;
for (var i = 0, j = array.length; i < j; i++) {
var property = array[i];
value = current[property];
if (i === j - 1) return format(value, options);
if (!value) return '';
current = value;
}
return '';
};
var use = exports.use = function use(l) {
lang = l || lang;
};
var i18n = exports.i18n = function i18n(fn) {
i18nHandler = fn || i18nHandler;
};
exports.default = { use: use, t: t, i18n: i18n };二、封裝i18n對象
結(jié)構(gòu)如下

index.js
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import elementLocale from 'element-ui/lib/locale';
import elementCnLocale from 'element-ui/lib/locale/lang/zh-CN'; // element-ui lang
import elementEnLocale from 'element-ui/lib/locale/lang/en'; // element-ui lang
import cnLocale from './lang/cn';
import enLocale from './lang/en';
import spuiEnLocale from 'lib/locale/lang/en';
import spuiCnLocale from 'lib/locale/lang/zh-CN';
import spuiLocale from 'lib/locale/index.js';
const messages = {
en: {
...elementEnLocale,
...enLocale,
...spuiEnLocale
},
cn: {
...elementCnLocale,
...cnLocale,
...spuiCnLocale
}
};
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: 'cn',
fallbackLocale: 'cn',
messages
});
// fix element-ui language switching issue.
elementLocale.i18n((key, value) => i18n.t(key, value));
spuiLocale.i18n(function(key, value) {
return i18n.t(key, value);
});
export default i18n;cn/index.js
export default {
common: {
merchantPlatform: '商戶平臺(tái)',
search: '查詢',
clear: '清除',
prev: '上一步',
next: '下一步',
done: '完成',
batchCopy: '一鍵復(fù)制',
currency: '幣種',
back: '返回',
submit: '提交',
confirm: '確認(rèn)',
add: '添加',
delete: '刪除',
edit: '編輯',
notify: '通知',
noLoginName: '未登錄',
logout: '賬號登出',
changePwd: '修改密碼',
total: '總計(jì)',
language: '語言設(shè)置',
languageList: [
{
value: 'en',
label: 'English'
},
{
value: 'cn',
label: '中文'
}
],
gotIt: '知道了',
tableNoData: '暫無數(shù)據(jù)',
tableNoDataSubtext: '提示:建議核實(shí)篩選條件',
talbeLoadingData: '搜索中...',
homeLoadingTitle: '正在加載資源',
homeLoadingSubTitle: '初次加載資源可能需要較多時(shí)間 請耐心等待',
action: '操作',
save: '保存',
cancel: '取消',
saveSuccessTip: '保存成功!',
deleteSuccessTip: '刪除成功',
yes: '是',
no: '否',
nonactivated: '未開通',
required: '必填',
view: '查看',
agree: '同意',
disagree: '不同意',
notice: '公告通知',
workOrderNotice: '工單通知',
timeZone: '時(shí)區(qū)',
mailLanguage: '郵件語言: ',
mailLanguageTitle: '選擇郵件語言',
mailLanguageContent: '所有與您綁定的商戶,都將以該語言給您發(fā)送郵件。',
noContractSigned: '當(dāng)前賬戶未開通該業(yè)務(wù)合同,請您聯(lián)系PayerMax商務(wù)負(fù)責(zé)人獲取進(jìn)一步幫助',
copySuccessfully: '復(fù)制成功',
copyFailed: '復(fù)制失?。耗蓢L試單擊右鍵進(jìn)行復(fù)制',
require: '必填',
to: '-',
today: '今天',
yesterday: '昨天',
last7Days: '過去7天',
last30Days: '過去30天',
placeholderStartDate: '開始日期',
placeholderEndDate: '結(jié)束日期',
applyRefundDes_1: '系統(tǒng)正在處理,請稍后查詢。受理成功后,款項(xiàng)預(yù)計(jì)',
applyRefundDes_2: '返回至原支付賬戶中。',
approvalArrivalTimeMap: { 0: '將立刻', 1: '將在1天', 2: '將在10天內(nèi)', 3: '' },
reupload: '重新上傳',
download: '導(dǎo)出',
export: '導(dǎo)出',
create: '創(chuàng)建',
showDetail: '詳情',
pixiuDetail: '詳情',
success: '成功',
unit: '筆',
units: '筆',
all: '全部',
timeZoneSetting: '時(shí)區(qū)設(shè)置:',
timeZoneDefault: '默認(rèn)',
timeZoneSelectHint: '時(shí)區(qū)篩選',
platformTimeZoneList: [
{ value: 'UTC', label: 'UTC +0:00', offset: 0, city: ' 世界標(biāo)準(zhǔn)時(shí)間', countryCode: 'UTC', zoneName: 'UTC' },
{ value: 'UTC +4:00 GST', label: 'UTC +4:00', offset: 240, city: ' 迪拜(阿聯(lián)酋)', countryCode: 'AE', zoneName: 'Asia/Dubai' },
{ value: 'UTC +3:00 MSK', label: 'UTC +3:00', offset: 180, city: ' 莫斯科(俄羅斯)', countryCode: 'RU', zoneName: 'Europe/Moscow' },
{ value: 'UTC +2:00 CAT', label: 'UTC +2:00', offset: 120, city: ' 開羅(埃及)', countryCode: 'EG', zoneName: 'Africa/Cairo' },
{ value: 'UTC +8:00 PHT', label: 'UTC +8:00', offset: 480, city: ' 馬尼拉(菲律賓)', countryCode: 'PH', zoneName: 'Asia/Manila' },
{ value: 'UTC +8:00 MYT', label: 'UTC +8:00', offset: 480, city: ' 古晉(馬來西亞)', countryCode: 'MY', zoneName: 'Asia/Kuala_Lumpur' },
{ value: 'UTC +2:00 SAST', label: 'UTC +2:00', offset: 120, city: ' 約翰內(nèi)斯堡(南非)', countryCode: 'ZA', zoneName: 'Africa/Johannesburg' },
{ value: 'UTC +3:00 AST', label: 'UTC +3:00', offset: 180, city: ' 利雅得(沙特)', countryCode: 'SA', zoneName: 'Asia/Riyadh' },
{ value: 'UTC +8:00 SGT', label: 'UTC +8:00', offset: 480, city: ' 新加坡(新加坡)', countryCode: 'SG', zoneName: 'Asia/Singapore' },
{ value: 'UTC +5:30 IST', label: 'UTC +5:30', offset: 330, city: ' 加爾各答(印度)', countryCode: 'IN', zoneName: 'Asia/Calcutta' },
{ value: 'UTC +7:00 WIB', label: 'UTC +7:00', offset: 420, city: ' 雅加達(dá)(印度尼西亞)', countryCode: 'ID', zoneName: 'Asia/Jakarta' },
{ value: 'UTC +8:00 CST', label: 'UTC +8:00', offset: 480, city: ' 北京(中國)', countryCode: 'CN', zoneName: 'Asia/Shanghai' },
{ value: 'UTC -3:00 BRT', label: 'UTC -3:00', offset: -180, city: ' 圣保羅(巴西)', countryCode: 'BR', zoneName: 'America/Sao_Paulo' },
{ value: 'UTC +3:00 TRT', label: 'UTC +3:00', offset: 180, city: ' 伊斯坦布爾(土耳其)', countryCode: 'TR', zoneName: 'Europe/Istanbul' }
],
faq: {
label: '常見問題',
testUrl: 'https://docs-dev.shareitpay.in/#/2?page_id=178&si=1&lang=zh-cn',
prodUrl: 'https://docs.payermax.com/#/12?page_id=180&si=1&lang=zh-cn',
},
helpList: [{
label: '文檔中心',
testUrl: 'https://docs-dev.shareitpay.in/#/2?page_id=4&si=1&lang=zh-cn',
prodUrl: 'https://docs.payermax.com/#/30?page_id=580&si=1&lang=zh-cn',
},
{
label: '幫助中心',
url: '',
}],
documentUrlInfo: {
testUrl: 'https://docs.payermax.com/#/12?page_id=81&si=1&lang=cn',
prodUrl: 'https://docs.payermax.com/#/30?page_id=580&si=1&lang=zh-cn',
},
datePick: {
tip: '時(shí)間跨度最大支持31天'
},
downloadEmail: {
title: '數(shù)據(jù)處理中',
submit: '好的',
message: '數(shù)據(jù)處理完成后,我們會(huì)將導(dǎo)出文件發(fā)送至您的郵箱 <span class="waring">%{email}</span>,請注意查收。'
},
accountSubject: '賬戶主體',
securityVerification: '用戶安全登錄驗(yàn)證',
securityOpen: '已開啟',
securityClosed: '已關(guān)閉',
deleteMerchantDes: '設(shè)為默認(rèn),賬號登錄后默認(rèn)打開此商戶號',
defaultMerchantGroupsDes: '設(shè)為默認(rèn),賬號登錄后默認(rèn)打開此商戶群組',
createGroup: '創(chuàng)建商戶群組',
switchTommc: '切換至商戶平臺(tái)運(yùn)營',
notification: '公告通知',
documentCenter: '文檔中心',
paymentMethodType: '支付方式類型',
},
route: {
unknown: '未命名菜單',
dashboard: '儀表盤',
overview: '概覽',
group: '群組管理',
banlnce: '賬戶余額',
balanceTotal: '余額匯總',
incomeDetail: '收支明細(xì)',
merchant: 'merchant',
report: '報(bào)告',
disbursement: '出款查詢',
reportHistory: '導(dǎo)出記錄',
transaction: '收單管理',
orderSearch: '訂單查詢',
orderDetail: '訂單詳情',
},
responseError: {
error602: {
title: '確定登出',
content: '您已被登出,請重新登錄',
okStr: '重新登錄',
},
error603: {
title: '提示',
okStr: '重新登錄',
},
errorCodeList: [
{ value: '600', label: '用戶賬號不存在' },
{ value: '601', label: '賬號名或密碼錯(cuò)誤' },
{ value: '603', label: '獲取權(quán)限異常,建議重新登錄' },
{ value: '604', label: '驗(yàn)證失敗過多,賬號已鎖定,請重設(shè)密碼' },
],
unknownError: '未知錯(cuò)誤'
}
};
en/index.js
export default {
common: {
merchantPlatform: 'Merchant Platform',
search: 'Search',
clear: 'Clear',
prev: 'Back',
done: 'Done',
batchCopy: 'Copy All',
currency: 'Currency',
next: 'Next',
back: 'Back',
submit: 'Submit',
confirm: 'Confirm',
add: 'Add',
delete: 'Delete',
edit: 'Edit',
notify: 'Notify',
noLoginName: 'No Login',
logout: 'Sign Out',
changePwd: 'Change Password',
total: 'Total',
language: 'Language Settings',
languageList: [
{
value: 'en',
label: 'English'
},
{
value: 'cn',
label: '中文'
}
],
gotIt: 'Got it',
tableNoData: 'No data',
tableNoDataSubtext: 'Tip: Suggest to recheck your filter.',
talbeLoadingData: 'Searching...',
homeLoadingTitle: 'Loading...',
homeLoadingSubTitle: 'It may take more time to load the resource for the first time. Please wait patiently.',
action: 'Action',
save: 'Save',
cancel: 'Cancel',
saveSuccessTip: 'Save successfully!',
deleteSuccessTip: 'Delete successfully!',
yes: 'Confirm',
no: 'Cancel',
nonactivated: 'Nonactivated',
required: 'Required',
view: 'View',
agree: 'Agree',
disagree: 'Disagree',
notice: 'Notification',
timeZone: 'Time Zone',
mailLanguage: 'Email Language: ',
mailLanguageTitle: 'Select Email Language',
mailLanguageContent: 'All merchants that are bound to you will send you an email in this language.',
noContractSigned: 'There is no contract under the current account, please contact the PayerMax business development for further assistance.',
copySuccessfully: 'Copy successfully',
copyFailed: 'Copy failed: Please try right-click and select Copy',
require: 'Required',
to: '-',
today: 'Today',
yesterday: 'Yesterday',
last7Days: 'Last 7 days',
last30Days: 'Last 30 days',
placeholderStartDate: 'Start Date',
placeholderEndDate: 'End Date',
applyRefundDes_1: 'Wait for some time, system is processing. Once the refund is processed, the money will be sent to the original payment source',
applyRefundDes_2: '.',
approvalArrivalTimeMap: { 0: ' immediately', 1: ' within 1 working day', 2: ' within 10 working days', 3: '' },
reupload: 'Re-upload',
download: 'Download',
export: 'Export',
create: 'Create',
showDetail: 'Detail',
pixiuDetail: 'Details',
success: 'Success',
unit: 'order',
units: 'orders',
all: 'All',
timeZoneSetting: 'Timezone Setting: ',
timeZoneDefault: 'Default',
timeZoneSelectHint: 'Time Zone Filter',
platformTimeZoneList: [
{ value: 'UTC', label: 'UTC +0:00', offset: 0, city: ' Universal Time Coordinated', countryCode: 'UTC', zoneName: 'UTC' },
{ value: 'UTC +4:00 GST', label: 'UTC +4:00', offset: 240, city: ' Dubai(United Arab Emirates)', countryCode: 'AE', zoneName: 'Asia/Dubai' },
{ value: 'UTC +3:00 MSK', label: 'UTC +3:00', offset: 180, city: ' Moscow(Russia)', countryCode: 'RU', zoneName: 'Europe/Moscow' },
{ value: 'UTC +2:00 CAT', label: 'UTC +2:00', offset: 120, city: ' Cairo(Egypt)', countryCode: 'EG', zoneName: 'Africa/Cairo' },
{ value: 'UTC +8:00 PHT', label: 'UTC +8:00', offset: 480, city: ' Manila(Philippines)', countryCode: 'PH', zoneName: 'Asia/Manila' },
{ value: 'UTC +8:00 MYT', label: 'UTC +8:00', offset: 480, city: ' Kuching(Malaysia)', countryCode: 'MY', zoneName: 'Asia/Kuala_Lumpur' },
{ value: 'UTC +2:00 SAST', label: 'UTC +2:00', offset: 120, city: ' Johannesburg(South Africa)', countryCode: 'ZA', zoneName: 'Africa/Johannesburg' },
{ value: 'UTC +3:00 AST', label: 'UTC +3:00', offset: 180, city: ' Riyadh(Saudi Arabia)', countryCode: 'SA', zoneName: 'Asia/Riyadh' },
{ value: 'UTC +8:00 SGT', label: 'UTC +8:00', offset: 480, city: ' Singapore(Singapore)', countryCode: 'SG', zoneName: 'Asia/Singapore' },
{ value: 'UTC +5:30 IST', label: 'UTC +5:30', offset: 330, city: ' Kolkata(India)', countryCode: 'IN', zoneName: 'Asia/Calcutta' },
{ value: 'UTC +7:00 WIB', label: 'UTC +7:00', offset: 420, city: ' Jakarta(Indonesia)', countryCode: 'ID', zoneName: 'Asia/Jakarta' },
{ value: 'UTC +8:00 CST', label: 'UTC +8:00', offset: 480, city: ' Beijing(China)', countryCode: 'CN', zoneName: 'Asia/Shanghai' },
{ value: 'UTC -3:00 BRT', label: 'UTC -3:00', offset: -180, city: ' Sao Paulo(Brazil)', countryCode: 'BR', zoneName: 'America/Sao_Paulo' },
{ value: 'UTC +3:00 TRT', label: 'UTC +3:00', offset: 180, city: ' Istanbul(Turkey)', countryCode: 'TR', zoneName: 'Europe/Istanbul' }
],
faq: {
label: 'FAQ',
testUrl: 'https://docs-dev.payermax.com/#/2?page_id=178&si=1&lang=en',
prodUrl: 'https://docs.payermax.com/#/12?page_id=180&si=1&lang=en',
},
helpList: [{
label: 'Documents',
testUrl: 'https://docs-dev.payermax.com/#/2?page_id=4&si=1&lang=en',
prodUrl: 'https://docs.payermax.com/#/30?page_id=580&si=1&lang=zh-en',
},
{
label: 'Support',
url: '',
hidden: true
}],
documentUrlInfo: {
testUrl: 'https://docs.payermax.com/#/30?page_id=580&si=1&lang=zh-en',
prodUrl: 'https://docs.payermax.com/#/30?page_id=580&si=1&lang=zh-en',
},
datePick: {
tip: 'Date range up to 31 days'
},
downloadEmail: {
title: 'Data processing',
submit: 'OK',
message: 'We will send the export to <span class="waring">%{email}</span> when it\'s completed, please check it later.'
},
accountSubject: 'Account Subject',
securityVerification: 'User security login verification',
securityOpen: 'Enabled',
securityClosed: 'Closed',
deleteMerchantDes: 'Set as default, this merchant account will be displayed after account login',
defaultMerchantGroupsDes: 'Set as default, this merchant group account will be displayed after account login',
createGroup: 'Create Group',
switchTommc: 'Switch to Merchant Platform',
notification: 'Notification',
documentCenter: 'Document Center',
paymentMethodType: 'Payment Method Type',
},
route: {
unknown: 'unknown menu',
dashboard: 'Dashboard',
overview: 'Dashboard',
banlnce: 'Banlnce',
balanceTotal: 'Balance Summary',
incomeDetail: 'Account Turnover',
group: 'Group',
report: 'Report',
disbursement: 'Disbursement',
reportHistory: 'Export Records',
merchant: 'merchant',
transaction: 'Payment',
orderSearch: 'Order Search',
orderDetail: 'Order Detail',
},
responseError: {
error602: {
title: 'Logout',
content: 'Your session has expired, please login again.',
okStr: 'Click to Sign in',
},
error603: {
title: 'Hint',
okStr: 'Click to Sign in',
},
errorCodeList: [
{ value: '600', label: 'The user account is not exits.' },
{ value: '601', label: 'User ID or Password is incorrect.' },
{ value: '603', label: 'Something wrong with accessing permission. Suggest to sign in again.' },
],
unknownError: 'Unknown error.'
}
};
三、在VUE中引入 main.js
import i18n from './i18n';
const vue = new Vue({
router,
store,
i18n,
created() {
injectBeyla();
},
mounted() {
util.init();
},
render: h => h(App),
}).$mount('#app');四、在頁面中使用

<ProblemDescription :title="$t(`workOrderInfo.yourLocalReceivingAccountNumber`)" />
<el-button @click="goBack">{{ $t('workOrderInfo.return') }}</el-button>
{
prop: 'status',
labelKey: 'workOrderInfo.workOrderStatus',
minWidth: 130,
render(h, row) {
const type = setStatus(row.status, this.language) || '';
return <div>
{row.status == 'PROCESS' && <div style='color: rgba(251, 151, 1, 1);padding: 4px 12px;border-radius: 14px;background: rgba(255, 241, 215, 1);'>{type || '-'}</div>}
{row.status == 'FINISHED' && <div style='color: rgba(0, 195, 82, 1);padding: 4px 12px;border-radius: 14px;background: rgba(230, 249, 239, 1);'>{type || '-'}</div>}
</div>;
}
},
import local from './local';
const SCOPE_NAME = 'workOrderInfo';
created() {
if (!this.$i18n.getLocaleMessage('en')[SCOPE_NAME]) {
this.$i18n.mergeLocaleMessage('en', local.en);
this.$i18n.mergeLocaleMessage('cn', local.cn);
}
},
this.tipMessage(this.$t('workOrderInfo.orderExisting'));local.js
export default {
cn: {
workOrderInfo: {
orderExisting: '該訂單已經(jīng)創(chuàng)建咨詢,請刷新頁面',
mustSelectAContent: '必須選擇一項(xiàng)內(nèi)容',
fileCount: '當(dāng)前限制最多上傳 5 個(gè)文件!',
}
},
en: {
workOrderInfo: {
orderExisting: 'The order has been created, please refresh the page',
mustSelectAContent: 'One item must be selected',
fileCount: 'The current limit allows for a maximum of 5 files to be uploaded!',
}
}
};總結(jié)
到此這篇關(guān)于前端VUE雙語實(shí)現(xiàn)方案的文章就介紹到這了,更多相關(guān)前端VUE雙語實(shí)現(xiàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
調(diào)用createApp?時(shí)Vue工作過程原理
這篇文章主要為大家介紹了調(diào)用createApp?時(shí)Vue工作過程原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
Vux+Axios攔截器增加loading的問題及實(shí)現(xiàn)方法
這篇文章主要介紹了Vux+Axios攔截器增加loading的問題及實(shí)現(xiàn)方法,文中通過實(shí)例代碼介紹了vue中使用axios的相關(guān)知識(shí),需要的朋友可以參考下2018-11-11
vue中動(dòng)態(tài)參數(shù)與計(jì)算屬性的使用方法
在平時(shí)vue開發(fā)中,我們經(jīng)常會(huì)用到計(jì)算屬性(計(jì)算屬性只有在它的相關(guān)依賴發(fā)生改變時(shí)才會(huì)重新求值)來計(jì)算我們需要的數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于vue中動(dòng)態(tài)參數(shù)與計(jì)算屬性使用的相關(guān)資料,需要的朋友可以參考下2021-08-08
Vue實(shí)現(xiàn)半自動(dòng)打字機(jī)特效
本文主要介紹了Vue實(shí)現(xiàn)半自動(dòng)打字機(jī)特效,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12
使用Vue動(dòng)態(tài)生成form表單的實(shí)例代碼
這篇文章主要介紹了使用Vue動(dòng)態(tài)生成form表單的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-04-04
vue 做移動(dòng)端微信公眾號采坑經(jīng)驗(yàn)記錄
這篇文章主要介紹了vue 做移動(dòng)端微信公眾號采坑經(jīng)驗(yàn)記錄,文中是小編記錄的三個(gè)坑及解決方案,需要的朋友可以參考下2018-04-04

