vue-cli 使用 VueI18n 实现多语言前端项目
安装 vue-i18n 和 js-cookie。
npm install vue-i18n --save
npm install js-cookie --save
src 文件夹下新建文件夹 lang ,lang下创建 index.js、zh.js、en.js 文件。(我这里只用了中文和英文,需要的可以自己加 ja.js、es.js 等)
提取页面中的静态文字。
zh.js 文件:
export default {
route: {
home: "首页",
product: "产品展示",
news: "新闻资讯",
newsView: "详情",
buynow: "下单购买",
service: "服务支持",
about: "关于我们",
icons: "图标",
backToTop: "返回顶部",
charts: "图表",
keyboardChart: "键盘图表",
lineChart: "折线图",
mixChart: "混合图表",
articleList: "文章列表",
i18n: "语言切换"
},
navbar: {
home: "首页",
product: "产品展示",
news: "新闻资讯",
service: "服务支持",
about: "关于我们",
Buynow: "下单购买"
},
buynow: {
name: {
label: "你的名字",
message: "请输入你的名字",
},
phone: {
label: "联系方式",
message: "请输入电话或手机",
},
num: "数量",
region: {
label: "所在地区",
message: "请选择所在地区",
},
address: {
label: "详细地址",
placeholder: "详细地址:如道路、门牌号、小区、楼栋号、单元室等",
message: "请输入详细地址",
},
comment: "备注",
submit: "提交订单",
reset: "重置",
},
View: {
title: "标题",
importance: "重要性",
type: "类型",
search: "搜索",
reviewer: "审核人",
id: "Id",
date: "时间",
author: "作者",
readings: "阅读数",
status: "状态",
actions: "操作",
appUrl: "路径",
introduce: "介绍",
}
};
en.js 文件:
export default {
route: {
home: "home",
product: "product",
news: "news",
newsView: "Details",
buynow: "buy now",
service: "service",
about: "about",
icons: "icons",
backToTop: "backToTop",
charts: "charts",
keyboardChart: "keyboard Chart",
lineChart: "lineChart",
mixChart: "mix Chart",
articleList: "articleList",
i18n: "language",
},
navbar: {
home: "home",
product: "product",
news: "news",
service: "service",
about: "about",
Buynow: "Buy now"
},
buynow: {
name: {
label: "Your Name",
message: "Please enter your name",
},
phone: {
label: "Phone call",
message: "Please enter the telephone number",
},
num: "Count",
region: {
label: "Region",
message: "Please select your region",
},
address: {
label: "Detailed address",
placeholder: "Detailed address: such as road, door number, residential area, building, unit room, etc",
message: "Please enter the detailed address",
},
comment: "Remarks",
submit: "Submit orders",
reset: "reset",
},
View: {
title: "Title",
importance: "Imp",
type: "Type",
search: "Search",
reviewer: "reviewer",
id: "ID",
date: "Date",
author: "Author",
readings: "Readings",
status: "Status",
actions: "Actions",
appUrl: "appUrl",
introduce: "introduce",
}
};
index.js 文件:
import Vue from "vue";
import VueI18n from "vue-i18n";
import Cookies from "js-cookie";
// 这里是引入的 element ui 组件的各种语言
import elementEnLocale from "element-ui/lib/locale/lang/en"; // element-ui lang
import elementZhLocale from "element-ui/lib/locale/lang/zh-CN"; // element-ui lang
import elementEsLocale from "element-ui/lib/locale/lang/es"; // element-ui lang
import elementJaLocale from "element-ui/lib/locale/lang/ja"; // element-ui lang
// 引入自己写的。
import enLocale from "./en";
import zhLocale from "./zh";
import esLocale from "./es";
import jaLocale from "./ja";
Vue.use(VueI18n);
const messages = {
en: {
...enLocale,
...elementEnLocale
},
zh: {
...zhLocale,
...elementZhLocale
},
es: {
...esLocale,
...elementEsLocale
},
ja: {
...jaLocale,
...elementJaLocale
}
};
export function getLanguage() {
const chooseLanguage = Cookies.get("language");
if (chooseLanguage) return chooseLanguage;
// 如果没有选择语言
const language = (navigator.language || navigator.browserLanguage).toLowerCase(); //获取浏览器的语言
const locales = Object.keys(messages);
// 显示与浏览器一样的语言如果浏览器不是这四种语言就默认显示英语
for (const locale of locales) {
if (language.indexOf(locale) > -1) {
return locale;
}
}
return "en";
}
const i18n = new VueI18n({
// 设置语言环境
// 选项: en | zh | es | ja
locale: getLanguage(),
// 设置语言环境信息
messages
});
export default i18n;
全局配置 main.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import Element from "element-ui";
import "./styles/element-variables.scss";
import "@/styles/index.scss"; // global css
import i18n from "./lang"; // 国际化
Vue.use(Element, {
i18n: (key, value) => i18n.t(key, value)
});
Vue.config.productionTip = false;
new Vue({
router,
store,
i18n,
render: h => h(App)
}).$mount("#app");
创建组件 (components 文件下新建 LangSelect 文件夹,里面创建文件 index.vue)。
index.vue
<template> <el-dropdown trigger="click" class="international" @command="handleSetLanguage" > <div> <i class="iconfont icon-yuyanqiehuan"></i> {{ languages }} </div> <el-dropdown-menu slot="dropdown"> <el-dropdown-item :disabled="language === 'zh'" command="zh" >中文</el-dropdown-item > <el-dropdown-item :disabled="language === 'en'" command="en" >English</el-dropdown-item > <!-- <el-dropdown-item :disabled="language === 'es'" command="es" >Español</el-dropdown-item > <el-dropdown-item :disabled="language === 'ja'" command="ja" >日本語</el-dropdown-item > --> </el-dropdown-menu> </el-dropdown> </template> <script> export default { name: "language", computed: { language() { return this.$store.getters.language; }, }, data() { return { languages: "中文", }; }, mounted() {
// 加载时获得当前语言
switch (this.language) { case "zh": this.languages = "中文"; break; case "en": this.languages = "English"; break; case "es": this.languages = "Español"; break; case "ja": this.languages = "日本語"; break; } }, methods: { handleSetLanguage(lang) { this.$i18n.locale = lang; this.$store.dispatch("app/setLanguage", lang); switch (lang) { case "zh": this.languages = "中文"; this.$message({ message: "语言切换成功", type: "success", }); break; case "en": this.languages = "English"; this.$message({ message: "Switch Language Success", type: "success", }); break; case "es": this.languages = "Español"; this.$message({ message: "Cambio de idioma con éxito", type: "success", }); break; case "ja": this.languages = "日本語"; this.$message({ message: "言語切り替えに成功", type: "success", }); break; } }, }, }; </script> <style lang="scss"> @import "//at.alicdn.com/t/font_1384350_a0jzmkrqfw.css"; //引入的阿里的图标库 .iconfont { font-size: 22px; vertical-align: middle; } </style>
使用:
引入: import LangSelect from "@/components/LangSelect"; components: { LangSelect }, 使用: <lang-select />
<template> <div class="navbar"> <div class="main-container"> <div class="logo"> <a href="/"> <img src="@/assets/logo.png" /> </a> </div> <div class="nav clearfix"> <lang-select class="right-menu-item hover-effect" /> <el-tabs v-model="activeName" @tab-click="handleClick(activeName)"> <el-tab-pane :label="$t('navbar.product')" name="/home"></el-tab-pane> <el-tab-pane :label="$t('navbar.product')" name="/product/index" ></el-tab-pane> <el-tab-pane :label="$t('navbar.service')" name="/service/index" ></el-tab-pane> <el-tab-pane :label="$t('navbar.about')" name="/about/index" ></el-tab-pane> <el-tab-pane :label="$t('navbar.Buynow')" name="/buynow/index"> <el-button class="right-button hover-effect" slot="label" icon="el-icon-shopping-cart-2" >{{ $t("navbar.Buynow") }}</el-button > </el-tab-pane> </el-tabs> </div> </div> </div> </template> <script> import LangSelect from "@/components/LangSelect"; export default { name: "navber", components: { LangSelect }, data() { return { role: true, activeName: "/home", activeIndex: "1", }; }, computed: { routePath() { return this.$route.path; }, }, watch: { routePath(newVal, oldVal) { console.log(newVal, oldVal); this.activeName = newVal; }, }, created() { this.activeName = this.$route.path; }, methods: { handleClick(activeName) { console.log(activeName); //跳转页面 this.$router.push({ path: activeName, }); }, handleSelect() {}, }, }; </script> <style lang="scss"> .navbar { position: relative; z-index: 5; width: 100%; height: 80px; overflow: hidden; background: rgba(255, 255, 255, 0.3); box-shadow: 0 1px 6px rgba(0, 21, 41, 0.2); &:hover { background: rgba(255, 255, 255, 0.5); } .logo { height: 80px; float: left; img { height: 85%; } } .nav { float: right; .el-tabs { float: right; .el-tabs__header { margin: 0px !important; .el-tabs__nav-wrap::after { height: 0px; } .el-tabs__item { // color: #111111; height: 80px; line-height: 80px; font-weight: 600; } } } .el-menu--horizontal { border: 0px; .el-menu-item { height: 80px; line-height: 80px; } .el-submenu .el-submenu__title { height: 80px; line-height: 80px; } } .right-menu-item { float: right; padding: 0px 20px; height: 80px; line-height: 80px; font-size: 14px; color: #000; vertical-align: text-bottom; margin: 0px 0px 0px 60px; &:before { content: ""; position: absolute; left: -20px; top: 33px; height: 14px; width: 1px; background: #cccccc; } &.hover-effect { cursor: pointer; transition: background 0.3s; &:hover { background: rgba(0, 0, 0, 0.025); } } } .right-button { border: 1px solid #ff0036; color: #ff0036; background: #ffeded; // margin: 20px 0px 20px 40px; &.hover-effect { cursor: pointer; transition: background 0.3s; } } } } </style>
效果:
完成。