Procházet zdrojové kódy

+ 新增国际化组件和配置文件

chen.cheng před 5 měsíci
rodič
revize
42eff9a98e

+ 1 - 0
package.json

@@ -60,6 +60,7 @@
     "vue-count-to": "1.0.13",
     "vue-cron": "^1.0.9",
     "vue-cropper": "0.5.5",
+    "vue-i18n": "7.3.2",
     "vue-json-editor": "^1.4.3",
     "vue-meta": "2.4.0",
     "vue-router": "3.4.9",

+ 75 - 0
src/components/LanguageSwitcher/index.vue

@@ -0,0 +1,75 @@
+<template>
+  <div class="language-wrapper">
+    <el-select @change="changeLanguage" v-model="lang">
+      <el-option v-for="lan in langList"
+                 :key="lan.value"
+                 :label="lan.label"
+                 :value="lan.value">
+      </el-option>
+    </el-select>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "language-switcher",
+  props: {
+    ws: {
+      type: String,
+      default: '',
+    },
+  },
+  watch: {
+    ws(val) {
+      this.init();
+    },
+  },
+  data() {
+    return {
+      lang: "en",
+      langList: [
+        {
+          label: "中文",
+          value: "zh"
+        },
+        {
+          label: "English",
+          value: "en"
+        }
+      ],
+    };
+  },
+  // 组件卸载前清空图层信息
+  beforeDestroy() {
+  },
+  created() {
+
+  },
+  mounted() {
+    this.init();
+  },
+  methods: {
+    init() {
+
+    },
+    changeLanguage(event) {
+      this.$i18n.locale = event // 改变为中文
+      localStorage.setItem('language', event)//在localStorage中存入设置
+    },
+  },
+};
+</script>
+<style lang="scss">
+.language-wrapper {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 80px;
+  height: 100%;
+
+  .el-input--suffix .el-input__inner {
+    padding: 0;
+    border: none;
+  }
+}
+</style>

+ 17 - 0
src/i18n/en.js

@@ -0,0 +1,17 @@
+export default {
+  common: {
+    username: '用户名',
+    password: '密码',
+    save: '保存',
+    edit: '编辑',
+    update: '更新',
+    delete: '删除',
+    forever: '永久',
+    expired: '过期'
+  },
+  menus: {
+    首页: "home page",
+    用户管理: "user manage"
+  },
+  search: "search"
+}

+ 58 - 0
src/i18n/index.js

@@ -0,0 +1,58 @@
+import Vue from 'vue'
+import VueI18n from 'vue-i18n'
+import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang导入Element的语言包 英文
+import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang g导入Element的语言包 中文
+import enLocale from './en' // 导入项目中用到的英文语言包
+import zhLocale from './zh'// 导入项目中用到的中文语言包
+Vue.use(VueI18n)
+const messages = {
+  en: {
+    ...enLocale,
+    ...elementEnLocale
+  },
+  zh: {
+    ...zhLocale,
+    ...elementZhLocale,
+  },
+
+}
+
+const i18n = new VueI18n({
+  locale: localStorage.getItem('language') || 'zh', // 设置当前语种,之所以放到storage中是为了避免用户手动点击刷新页面时语言被自动切换回去,所以需要把语言存起来
+  messages, // 设置全局当地语言包,
+  fallbackLocale: 'zh', //如果当前语种不存在时,默认设置当前语种
+  numberFormats:{ //设置 数字本地化
+    'en': {
+      currency: { //添加 $
+        style: 'currency', currency: 'USD'
+      }
+    },
+    'zh': {
+      currency: { //添加 ¥
+        style: 'currency', currency: 'JPY', currencyDisplay: 'symbol'
+      }
+    }
+  },
+  dateTimeFormats:{//设置 日期时间本地化
+    'en': {
+      short: {
+        year: 'numeric', month: 'short', day: 'numeric'
+      },
+      long: {
+        year: 'numeric', month: 'short', day: 'numeric',
+        weekday: 'short', hour: 'numeric', minute: 'numeric'
+      }
+    },
+    'zh': {
+      short: {
+        year: 'numeric', month: 'short', day: 'numeric'
+      },
+      long: {
+        year: 'numeric', month: 'short', day: 'numeric',
+        weekday: 'short', hour: 'numeric', minute: 'numeric'
+      }
+    }
+  }
+})
+
+export default i18n

+ 17 - 0
src/i18n/zh.js

@@ -0,0 +1,17 @@
+export default {
+  common: {
+    username: '用户名',
+    password: '密码',
+    save: '保存',
+    edit: '编辑',
+    update: '更新',
+    delete: '删除',
+    forever: '永久',
+    expired: '过期'
+  },
+  menus: {
+    首页: "home page",
+    用户管理: "user manage"
+  },
+  search: "搜索"
+}

+ 15 - 20
src/layout/components/Navbar.vue

@@ -1,34 +1,25 @@
 <template>
   <div class="navbar">
-    <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
+    <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container"
+               @toggleClick="toggleSideBar"/>
 
     <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/>
     <top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/>
 
     <div class="right-menu">
       <template v-if="device!=='mobile'">
-        <search id="header-search" class="right-menu-item" />
-
-        <el-tooltip content="源码地址" effect="dark" placement="bottom">
-          <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
-        </el-tooltip>
-
-        <el-tooltip content="文档地址" effect="dark" placement="bottom">
-          <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
-        </el-tooltip>
-
-        <screenfull id="screenfull" class="right-menu-item hover-effect" />
-
+        <search id="header-search" class="right-menu-item"/>
+        <screenfull id="screenfull" class="right-menu-item hover-effect"/>
         <el-tooltip content="布局大小" effect="dark" placement="bottom">
-          <size-select id="size-select" class="right-menu-item hover-effect" />
+          <size-select id="size-select" class="right-menu-item hover-effect"/>
         </el-tooltip>
-
+        <language-switcher></language-switcher>
       </template>
 
       <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
         <div class="avatar-wrapper">
           <img :src="avatar" class="user-avatar">
-          <i class="el-icon-caret-bottom" />
+          <i class="el-icon-caret-bottom"/>
         </div>
         <el-dropdown-menu slot="dropdown">
           <router-link to="/user/profile">
@@ -47,7 +38,7 @@
 </template>
 
 <script>
-import { mapGetters } from 'vuex'
+import {mapGetters} from 'vuex'
 import Breadcrumb from '@/components/Breadcrumb'
 import TopNav from '@/components/TopNav'
 import Hamburger from '@/components/Hamburger'
@@ -56,9 +47,11 @@ import SizeSelect from '@/components/SizeSelect'
 import Search from '@/components/HeaderSearch'
 import RuoYiGit from '@/components/RuoYi/Git'
 import RuoYiDoc from '@/components/RuoYi/Doc'
+import LanguageSwitcher from "@/components/LanguageSwitcher/index.vue";
 
 export default {
   components: {
+    LanguageSwitcher,
     Breadcrumb,
     TopNav,
     Hamburger,
@@ -104,7 +97,8 @@ export default {
         this.$store.dispatch('LogOut').then(() => {
           location.href = '/index';
         })
-      }).catch(() => {});
+      }).catch(() => {
+      });
     }
   }
 }
@@ -116,7 +110,7 @@ export default {
   overflow: hidden;
   position: relative;
   background: #fff;
-  box-shadow: 0 1px 4px rgba(0,21,41,.08);
+  box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
 
   .hamburger-container {
     line-height: 46px;
@@ -124,7 +118,7 @@ export default {
     float: left;
     cursor: pointer;
     transition: background .3s;
-    -webkit-tap-highlight-color:transparent;
+    -webkit-tap-highlight-color: transparent;
 
     &:hover {
       background: rgba(0, 0, 0, .025)
@@ -149,6 +143,7 @@ export default {
     float: right;
     height: 100%;
     line-height: 50px;
+    display: flex;
 
     &:focus {
       outline: none;

+ 10 - 5
src/main.js

@@ -12,13 +12,13 @@ import store from './store'
 import router from './router'
 import directive from './directive' // directive
 import plugins from './plugins' // plugins
-import { download } from '@/utils/request'
+import {download} from '@/utils/request'
 
 import './assets/icons' // icon
 import './permission' // permission control
-import { getDicts } from "@/api/system/dict/data";
-import { getConfigKey } from "@/api/system/config";
-import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
+import {getDicts} from "@/api/system/dict/data";
+import {getConfigKey} from "@/api/system/config";
+import {addDateRange, handleTree, parseTime, resetForm, selectDictLabel, selectDictLabels} from "@/utils/ruoyi";
 // 分页组件
 import Pagination from "@/components/Pagination";
 // 自定义表格工具组件
@@ -38,6 +38,8 @@ import VueMeta from 'vue-meta'
 // 字典数据组件
 import DictData from '@/components/DictData'
 
+import i18n from './i18n';
+
 import VideoPlayer from 'vue-video-player'
 
 import 'video.js/dist/video-js.css'
@@ -65,6 +67,8 @@ Vue.component('Editor', Editor)
 Vue.component('FileUpload', FileUpload)
 Vue.component('ImageUpload', ImageUpload)
 Vue.component('ImagePreview', ImagePreview)
+
+
 Vue.directive('drag', (el) => {
   const oDiv = el // 当前元素
   const minTop = oDiv.getAttribute('drag-min-top')
@@ -94,7 +98,7 @@ Vue.directive('drag', (el) => {
       // 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
       const l = e.clientX - disX
       const t = e.clientY - disY
-      const { marginTop: mt, marginLeft: ml } = window.getComputedStyle(target)
+      const {marginTop: mt, marginLeft: ml} = window.getComputedStyle(target)
       // 计算移动当前元素的位置,并且给该元素样式中的left和top值赋值
       target.style.left = l - parseInt(ml) + 'px'
       target.style.top = (t < minTop ? minTop : t) - parseInt(mt) + 'px'
@@ -156,5 +160,6 @@ new Vue({
   el: '#app',
   router,
   store,
+  i18n,
   render: h => h(App)
 })

+ 1 - 0
src/views/index.vue

@@ -1,6 +1,7 @@
 <template>
   <div class="app-container home">
     综合管理后台
+    {{$t("search")}}
   </div>
 </template>