vue2项目实现国际化(若依框架示例)

本文主要梳理vue2项目实现全项目格式化,在导航栏中切换,页面中所有的组件的默认语言随之切换,搭配vue-i18n插件

文章目录

  • 基础准备
  • 实现示例流程
      • [1. 创建国际化文件](#1. 创建国际化文件)
          • [1.1 element文件夹](#1.1 element文件夹)
          • [1.2 locales文件夹](#1.2 locales文件夹)
          • [1.3 index.js](#1.3 index.js)
          • [1.4 change-language.vue 切换组件](#1.4 change-language.vue 切换组件)
      • [2. 全局引入(main.js)](#2. 全局引入(main.js))
      • [3. 在导航栏navbar.vue组件切换逻辑](#3. 在导航栏navbar.vue组件切换逻辑)
      • [4. 在首页示例展示效果](#4. 在首页示例展示效果)

基础准备

引入插件vue-i18n

安装插件

bash 复制代码
npm i vue-i18n

【注】安装过程中报错

npm ERR! Cannot read properties of null (reading 'matches')

解决方案:

先清除npm缓存:

bash 复制代码
npm cache clean --force

再使用pnpm进行安装(未安装的话就npm i pnpm一下即可)

bash 复制代码
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】

javascript 复制代码
// 英语
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 translated
      filterPlaceholder: 'Enter keyword', // to be translated
      noCheckedFormat: '{total} items', // to be translated
      hasCheckedFormat: '{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】

javascript 复制代码
// 中文
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】

javascript 复制代码
export default {
  Language: 'English',
  system: {
    homePage: {
      title1: 'title1',
      title2: 'title2',
      description1: 'Last 7 days',
      description2: 'Nearly six months',
    }
  }
};

【zh-CN.js】

javascript 复制代码
export default {
  Language: '中文',
  system: {
    homePage: {
      title1: '标题1',
      title2: '标题2',
      description1: '近7日',
      description2: '近6个月',
    }
  }
};
1.3 index.js

文本集成文件,用于导入到入口文件main.js中,基本结构就是将两个element和locales文件集成导入,为了实现全局控制使用了本地储存localStorage来进行全局控制切换值,默认中文

javascript 复制代码
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 切换组件

封装国际化语言切换组件,方便调用使用

javascript 复制代码
<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 = value
      localStorage.setItem('change-language', value)
      location.reload()
    },
  },
}
</script>
<style scoped lang="scss">
</style>

2. 全局引入(main.js)

在入口文件main.js文件中进行引入,方便全局使用,

javascript 复制代码
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组件切换逻辑

直接在导航栏引入封装组件

引入:

html 复制代码
<ChangeLanguage />
javascript 复制代码
import ChangeLanguage from '@/i18n/change-language'

export default {
  components: {
    ChangeLanguage,
  },
  }

效果:

4. 在首页示例展示效果

示例组件:

直接使用$t函数直接双向绑定

javascript 复制代码
<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>

效果:


相关推荐
持续前行8 小时前
vscode 中找settings.json 配置
前端·javascript·vue.js
JosieBook8 小时前
【Vue】11 Vue技术——Vue 中的事件处理详解
前端·javascript·vue.js
安逸点8 小时前
Vue项目中使用xlsx库解析Excel文件
vue.js
一只小阿乐8 小时前
vue 改变查询参数的值
前端·javascript·vue.js·路由·router·网文·未花中文网
小酒星小杜9 小时前
在AI时代下,技术人应该学会构建自己的反Demo地狱系统
前端·vue.js·ai编程
Code知行合壹9 小时前
Pinia入门
vue.js
今天也要晒太阳4739 小时前
element表单和vxe表单联动校验的实现
vue.js
依赖_赖10 小时前
前端实现token无感刷新
前端·javascript·vue.js
hhcccchh11 小时前
学习vue第十三天 Vue3组件深入指南:组件的艺术与科学
javascript·vue.js·学习
zhengxianyi51511 小时前
ruoyi-vue-pro本地环境搭建(超级详细,带异常处理)
前端·vue.js·前后端分离·ruoyi-vue-pro