vue2项目实现国际化(若依框架示例)
本文主要梳理vue2项目实现全项目格式化,在导航栏中切换,页面中所有的组件的默认语言随之切换,搭配vue-i18n插件
文章目录
- 基础准备
- 引入插件vue-i18n
- 实现示例流程
- 1. 创建国际化文件
- 1.1 element文件夹
- 1.2 locales文件夹
- 1.3 index.js
- 1.4 change-language.vue 切换组件
- 2. 全局引入(main.js)
- 3. 在导航栏navbar.vue组件切换逻辑
- 4. 在首页示例展示效果
基础准备
引入插件vue-i18n
安装插件
npm i vue-i18n
【注】安装过程中报错
npm ERR! Cannot read properties of null (reading ‘matches‘)
解决方案:
先清除npm缓存:
npm cache clean --force
再使用pnpm进行安装(未安装的话就npm i pnpm一下即可)
pnpm i vue-i18n
或者在package.json文件中直接添加 “vue-i18n”: “^8.27.1”,版本,在进行重新进行npm install一下也可以
实现示例流程
1. 创建国际化文件
在src文件目录下创建i18n文件夹,文件夹下创建:element、locales、change-language.vue、index.js四个文件
1.1 element文件夹
创建两个文件:en.js,zh-CN.js,
主要用于存放elementUI组件,一些相对固定的文本描述翻译
【en.js】
// 英语
exports.default = {el: {colorpicker: {confirm: 'OK',clear: 'Clear'},datepicker: {now: 'Now',today: 'Today',cancel: 'Cancel',clear: 'Clear',confirm: 'OK',selectDate: 'Select date',selectTime: 'Select time',startDate: 'Start Date',startTime: 'Start Time',endDate: 'End Date',endTime: 'End Time',prevYear: 'Previous Year',nextYear: 'Next Year',prevMonth: 'Previous Month',nextMonth: 'Next Month',year: 'year',month1: 'January',month2: 'February',month3: 'March',month4: 'April',month5: 'May',month6: 'June',month7: 'July',month8: 'August',month9: 'September',month10: 'October',month11: 'November',month12: 'December',week: 'week',weeks: {sun: 'Sun',mon: 'Mon',tue: 'Tue',wed: 'Wed',thu: 'Thu',fri: 'Fri',sat: 'Sat'},months: {jan: 'Jan',feb: 'Feb',mar: 'Mar',apr: 'Apr',may: 'May',jun: 'Jun',jul: 'Jul',aug: 'Aug',sep: 'Sep',oct: 'Oct',nov: 'Nov',dec: 'Dec'}},select: {loading: 'Loading',noMatch: 'No matching data',noData: 'No data',placeholder: 'Select'},cascader: {noMatch: 'No matching data',loading: 'Loading',placeholder: 'Select',noData: 'No data'},pagination: {goto: 'Go to',pagesize: '/page',total: 'Total {total}',pageClassifier: ''},messagebox: {title: 'Message',confirm: 'OK',cancel: 'Cancel',error: 'Illegal input'},upload: {deleteTip: 'press delete to remove',delete: 'Delete',preview: 'Preview',continue: 'Continue'},table: {emptyText: 'No Data',confirmFilter: 'Confirm',resetFilter: 'Reset',clearFilter: 'All',sumText: 'Sum'},tree: {emptyText: 'No Data'},transfer: {noMatch: 'No matching data',noData: 'No data',titles: ['List 1', 'List 2'], // to be translatedfilterPlaceholder: 'Enter keyword', // to be translatednoCheckedFormat: '{total} items', // to be translatedhasCheckedFormat: '{checked}/{total} checked' // to be translated},image: {error: 'FAILED'},pageHeader: {title: 'Back' // to be translated},popconfirm: {confirmButtonText: 'Yes',cancelButtonText: 'No'},empty: {description: 'No Data'}},
};
【zh-CN.js】
// 中文
exports.default = {el: {colorpicker: {confirm: '确定',clear: '清空'},datepicker: {now: '此刻',today: '今天',cancel: '取消',clear: '清空',confirm: '确定',selectDate: '选择日期',selectTime: '选择时间',startDate: '开始日期',startTime: '开始时间',endDate: '结束日期',endTime: '结束时间',prevYear: '前一年',nextYear: '后一年',prevMonth: '上个月',nextMonth: '下个月',year: '年',month1: '1 月',month2: '2 月',month3: '3 月',month4: '4 月',month5: '5 月',month6: '6 月',month7: '7 月',month8: '8 月',month9: '9 月',month10: '10 月',month11: '11 月',month12: '12 月',// week: '周次',weeks: {sun: '日',mon: '一',tue: '二',wed: '三',thu: '四',fri: '五',sat: '六'},months: {jan: '一月',feb: '二月',mar: '三月',apr: '四月',may: '五月',jun: '六月',jul: '七月',aug: '八月',sep: '九月',oct: '十月',nov: '十一月',dec: '十二月'}},select: {loading: '加载中',noMatch: '无匹配数据',noData: '无数据',placeholder: '请选择'},cascader: {noMatch: '无匹配数据',loading: '加载中',placeholder: '请选择',noData: '暂无数据'},pagination: {goto: '前往',pagesize: '条/页',total: '共 {total} 条',pageClassifier: '页'},messagebox: {title: '提示',confirm: '确定',cancel: '取消',error: '输入的数据不合法!'},upload: {deleteTip: '按 delete 键可删除',delete: '删除',preview: '查看图片',continue: '继续上传'},table: {emptyText: '暂无数据',confirmFilter: '筛选',resetFilter: '重置',clearFilter: '全部',sumText: '合计'},tree: {emptyText: '暂无数据'},transfer: {noMatch: '无匹配数据',noData: '无数据',titles: ['列表 1', '列表 2'],filterPlaceholder: '请输入搜索内容',noCheckedFormat: '共 {total} 项',hasCheckedFormat: '已选 {checked}/{total} 项'},image: {error: '加载失败'},pageHeader: {title: '返回'},popconfirm: {confirmButtonText: '确定',cancelButtonText: '取消'},empty: {description: '暂无数据'}},};
1.2 locales文件夹
创建两个文件:en.js,zh-CN.js,
主要用于存放页面中所需要的除了elementUI自带其他的页面文本描述元素
【en.js】
export default {Language: 'English',system: {homePage: {title1: 'title1',title2: 'title2',description1: 'Last 7 days',description2: 'Nearly six months',}}
};
【zh-CN.js】
export default {Language: '中文',system: {homePage: {title1: '标题1',title2: '标题2',description1: '近7日',description2: '近6个月',}}
};
1.3 index.js
文本集成文件,用于导入到入口文件main.js中,基本结构就是将两个element和locales文件集成导入,为了实现全局控制使用了本地储存localStorage来进行全局控制切换值,默认中文
import Vue from 'vue';
import VueI18n from 'vue-i18n';Vue.use(VueI18n);// 各个国家的key
const localeKeys = ['en', 'zh-CN'];// 各个国家语言包
const messages = {};
for (const key of localeKeys) {const langObj = require(`./locales/${key}`).default;const langElement = require(`./element/${key}`);messages[key] = {...langObj,...langElement ? langElement.default : {}};
}export default new VueI18n({locale: localStorage.getItem('change-language') || 'zh-CN',messages,silentTranslationWarn: true // 忽略翻译警告
});
解析:
-
locale属性:用于控制语言的标识,默认中文,此处使用了localStorage本地储存,方便全局且页面刷新都可以保持选中值
-
messages属性:切换文本的主要内容值,当locale的属性切换,所对应的语言的文本展示
-
silentTranslationWarn:是否忽略翻译警告
1.4 change-language.vue 切换组件
封装国际化语言切换组件,方便调用使用
<template><el-dropdown @command="handle"style="cursor: pointer;"><span class="el-dropdown-link">{{$t('Language')}}<i class="el-icon-caret-bottom el-icon--right"></i></span><el-dropdown-menu slot="dropdown"><el-dropdown-item v-for="(item, index) of list":key="index":disabled="$t('Language') == item.name":command="item.key">{{item.name}}</el-dropdown-item></el-dropdown-menu></el-dropdown>
</template><script>
export default {name: 'change-language',data() {return {list: [{ key: 'en', name: 'English' }, // 英语{ key: 'zh-CN', name: '中文' }, // 中文],}},methods: {handle(value) {this.$i18n.locale = valuelocalStorage.setItem('change-language', value)location.reload()},},
}
</script>
<style scoped lang="scss">
</style>
2. 全局引入(main.js)
在入口文件main.js文件中进行引入,方便全局使用,
import i18n from './i18n';Vue.use(Element, {i18n: (key, value) => i18n.t(key, value),
});new Vue({el: '#app',router,store,i18n,render: h => h(App)
});
3. 在导航栏navbar.vue组件切换逻辑
直接在导航栏引入封装组件
引入:
<ChangeLanguage />
import ChangeLanguage from '@/i18n/change-language'export default {components: {ChangeLanguage,},}
效果:
4. 在首页示例展示效果
示例组件:
直接使用$t函数直接双向绑定
<template><div class="newMain-container homePage">示例代码:<br>我是title1===:{{ $t('system.homePage.title1') }}<br>我是title2===:{{ $t('system.homePage.title2') }}<br>我是description1===:<el-button type="primary">{{ $t('system.homePage.description1') }}</el-button><br>我是description2===:<el-button type="primary">{{ $t('system.homePage.description2') }}</el-button></div>
</template>
效果: