当前位置:   article > 正文

使用i18n实现vue2+element UI的国际化_vue2 i18n

vue2 i18n

搭建环境

安装i18n

要注意使用vue2安装i18n不能安装最新版,会不兼容。

npm install vue-i18n@8.27.1 --save
  • 1

新建相关文件

其中en.js和zh.js是存放自定义的语言配置文件,change-language.vue是实现切换语言的组件的文件。index.js 是语言包入口文件。
在这里插入图片描述

编写代码

index.js的内容

import Vue from 'vue'
import VueI18n from 'vue-i18n'
// 引入自定义的各个语言配置文件
import zh from './config/zh';
import en from './config/en';
//element-ui自带多语言配置
import enLocale from 'element-ui/lib/locale/lang/en'
import zhLocale from 'element-ui/lib/locale/lang/zh-CN'
Vue.use(VueI18n)

// 各个国家语言包
const messages = {
    en: {
        ...en,
        ...enLocale
    },
    zh: {
        ...zh,
        ...zhLocale
    },
}

export default new VueI18n({
    locale: localStorage.getItem('change-language') || 'zh-CN',
    messages,
    silentTranslationWarn: true // 忽略翻译警告
})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

change-language.vue

<template>
  <el-dropdown @command="handle">
    <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" :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>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

这里我把选择的是什么语言存储到本地

localStorage.setItem('change-language', value)
  • 1

在这里插入图片描述

实现国际化

在main.js中引入

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import element from "@/element";

import 'element-ui/lib/theme-chalk/index.css';
// 国际化
import i18n from './components/i18n';

Vue.config.productionTip = false
Vue.use(element, {
    i18n: (key, value) => i18n.t(key, value)
})


new Vue({
    router,
    store,
    i18n,
    render: h => h(App)
}).$mount('#app')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

根据项目编写自定义的语言配置文件

en.js
const en = {
    'Language': 'English',
    login:{
        title:"Movie Review Information Management System",
        username: "Username",
        password: "Password",
        rememberMe: "Remember Me",
        forgotPassword: "Forgot Password",
        login: "Login",
        loggingIn: "Logging In...",
        footer: "Copyright © 2023-2024 Movie Review Information Management System All Rights Reserved.",
        enterUsername: "Please enter your username",
        enterPassword: "Please enter your password"
    }
}
export default en;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
zh.js
const zh = {
    'Language': '中文',
    login:{
        title:'电影点评网站信息管理系统',
        username: "账号",
        password: "密码",
        rememberMe: "记住密码",
        forgotPassword: "忘记密码",
        login: "登录",
        loggingIn: "登录中...",
        footer: "Copyright © 2023-2024 电影点评网站信息管理系统 All Rights Reserved.",
        enterUsername: "请输入您的账号",
        enterPassword: "请输入您的密码"
    }
}
export default zh;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在登录页面调用

一旦将 VueI18n 实例挂载到 Vue 实例上,在 Vue 组件中直接使用 $t 方法,可以通过指定键(key)来获取对应语言的翻译文本。

在template中直接使用,如下:

  $t('login.title') 
  • 1

在script中使用,如下:

   this.$t('login.enterUsername')
  • 1

和在template中直接使用的区别就是在前面加上了this

下面是完整代码,仅供参考

<template>
    <div class="login">
        <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
            <h3 class="title">{{ $t('login.title') }}</h3>
            <el-form-item prop="userNo">
                <el-input
                        v-model="loginForm.userNo"
                        type="text"
                        auto-complete="off"
                        :placeholder="$t('login.enterUsername')"
                >
                    <i slot="prefix" class="el-input__icon el-icon-user"></i>
                </el-input>
            </el-form-item>
            <el-form-item prop="password">
                <el-input
                        v-model="loginForm.password"
                        type="password"
                        auto-complete="off"
                        :placeholder="$t('login.enterPassword')"
                        @keyup.enter.native="handleLogin"
                >
                    <i slot="prefix" class="el-input__icon el-icon-lock"></i>
                </el-input>
            </el-form-item>
            <div style="margin:0 0 25px 0;text-align:left">
                <el-checkbox v-model="loginForm.rememberMe">
                  {{ $t('login.rememberMe') }}
                </el-checkbox>
                <el-link type="primary" :href="'http://localhost:8080/user/forgetPassword'" style="margin-left: 10px">
                  {{ $t('login.forgotPassword') }}
                </el-link>
            </div>
            <el-form-item style="width:100%;">
                <el-button
                        :loading="loading"
                        size="medium"
                        type="primary"
                        style="width:100%;"
                        @click.native.prevent="handleLogin"
                        @keyup.enter="handleLogin"
                >
                    <span v-if="!loading">{{ $t('login.login') }}</span>
                    <span v-else>{{ $t('login.loggingIn') }}</span>
                </el-button>
            </el-form-item>
        </el-form>
        <div class="ChangeLanguage-container" >
          <!-- 添加 ChangeLanguage 组件 -->
          <ChangeLanguage/>
        </div>
        <!--  底部  -->
        <div class="el-login-footer">
            <span> {{ $t('login.footer') }}</span>
        </div>
    </div>
</template>

<script>
    import Cookies from 'js-cookie';
    import {Login} from "@/api/api";
    import {
        addToken,
        addUserCache,
        removeToken,
        removeUserCache,
    } from "@/api/userCache";
    import userMenusMap from "@/utils/menu";
    import ChangeLanguage from '@/components/i18n/change-language'


    export default {
        name: "Login",
        components: {
          ChangeLanguage // 注册 ChangeLanguage 组件
        },
        data() {
            return {
                codeUrl: "",
                loginForm: {
                    userNo: "",
                    password: "",
                    rememberMe: false,
                },
                loginRules: {
                    userNo: [
                        {required: true, trigger: "blur", message: this.$t('login.enterUsername')}
                    ],
                    password: [
                        {required: true, trigger: "blur", message: this.$t('login.enterPassword')}
                    ]
                },
                loading: false,
            };
        },
        mounted() {
            removeUserCache();
            removeToken();
            localStorage.removeItem('home')
        },
        created() {
            removeUserCache();
            removeToken();
            localStorage.removeItem('home')
            this.getCookie();
        },
        methods: {
            getCookie() {
                const username = Cookies.get("username");
                const password = Cookies.get("password");
                const rememberMe = Cookies.get('rememberMe')
                const type = Cookies.get('type')
                this.loginForm = {
                    userNo: username === undefined ? this.loginForm.userNo : username,
                    password: password === undefined ? this.loginForm.password : password,
                    rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
                };
            },
            handleLogin() {
                this.$refs.loginForm.validate(async valid => {
                    if (valid) {
                        localStorage.removeItem('home');
                        this.loading = true;
                        if (this.loginForm.rememberMe) {
                            Cookies.set("username", this.loginForm.userNo, { expires: 30 });// 30天
                            Cookies.set("password", this.loginForm.password, { expires: 30 });
                            Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
                        } else {
                            Cookies.remove("username");
                            Cookies.remove("password");
                            Cookies.remove('rememberMe');
                            Cookies.remove('type');
                        }
                        const params = {
                            password: this.loginForm.password,
                            id: this.loginForm.userNo,
                        }
                        const result = await Login(params);
                        if (result.code === 20000) {
                            let user = result.data.user;
                            let token = result.data.token;
                            addUserCache(user);
                            addToken(token);
                            this.$message({
                                type: "success",
                                message: result.message,
                                duration: 1000
                            });
                            const type = user.type
                            localStorage.setItem('home', userMenusMap[type][1])
                            await this.$router.push({
                                path: '/'
                            })
                        } else {
                            removeUserCache();
                            removeToken();
                            this.$message({
                                type: "error",
                                message: result.message,
                                duration: 1000
                            });
                        }
                        this.loading = false
                    }
                });
            }
        }
    };
</script>

<style rel="stylesheet/scss" lang="scss">
    .login {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        background-image: url("/public/image/login.png");
        background-size: cover;
    }

    .title {
        margin: 0 auto 30px auto;
        text-align: center;
        color: #707070;
    }

    .login-form {
        border-radius: 6px;
        background: #ffffff;
        width: 400px;
        padding: 25px 25px 5px 25px;
    }
    .ChangeLanguage-container {
      position: fixed;
      width: 60px;
      text-align: center;
      margin-top: 332px;
      color: #000000;
      font-family: Arial, serif;
      font-size: 12px;
      letter-spacing: 1px;
      background-color: #FFFFFF;
    }

    .el-login-footer {
        height: 40px;
        line-height: 40px;
        position: fixed;
        bottom: 0;
        width: 100%;
        text-align: center;
        color: #000000;
        font-family: Arial, serif;
        font-size: 12px;
        letter-spacing: 1px;
    }

</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218

效果图

中文:
在这里插入图片描述
英文:
在这里插入图片描述

参考文章

https://blog.csdn.net/xiakekeali/article/details/131720748
https://www.jianshu.com/p/623c7e9dfaec

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号