feature:add i18n

This commit is contained in:
Pan 2017-11-03 18:37:49 +08:00
parent bb1d939a94
commit e05da2650b
16 changed files with 381 additions and 55 deletions

View File

@ -33,6 +33,7 @@
"sortablejs": "1.6.1",
"vue": "2.5.2",
"vue-count-to": "1.0.5",
"vue-i18n": "7.3.2",
"vue-multiselect": "2.0.6",
"vue-router": "3.0.1",
"vue-splitpane": "1.0.0",

View File

@ -47,7 +47,7 @@ export default {
.screenfull-svg {
display: inline-block;
cursor: pointer;
fill: #48576a;
fill: #5a5e66;;
width: 20px;
height: 20px;
vertical-align: 10px;

View File

@ -1,5 +1,5 @@
<template>
<svg class="svg-icon" aria-hidden="true">
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>
@ -11,11 +11,21 @@ export default {
iconClass: {
type: String,
required: true
},
className: {
type: String
}
},
computed: {
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
}
}
}

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1509677746926" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1419" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M666.298182 824.087273c-12.567273-30.72-54.225455-83.316364-123.578182-156.392728-18.618182-19.549091-17.454545-34.443636-10.705455-78.894545v-5.12c4.421818-30.487273 12.101818-48.407273 114.501819-64.698182 52.130909-8.145455 65.629091 12.567273 84.712727 41.425455l6.283636 9.541818a101.003636 101.003636 0 0 0 51.432728 41.658182c9.076364 4.189091 20.247273 9.309091 35.374545 17.92C861.090909 649.774545 861.090909 672.814545 861.090909 723.549091v5.818182a215.272727 215.272727 0 0 1-41.425454 139.636363 472.436364 472.436364 0 0 1-152.203637 88.203637c27.927273-52.363636 6.516364-114.501818 0-132.421818zM512 40.96a468.014545 468.014545 0 0 1 203.869091 46.545455 434.501818 434.501818 0 0 0-102.865455 82.618181c-7.447273 10.24-13.730909 19.781818-19.781818 28.625455-19.549091 29.556364-29.090909 42.821818-46.545454 44.916364a200.843636 200.843636 0 0 1-33.745455 0c-34.210909-2.327273-80.756364-5.12-95.650909 35.374545-9.541818 25.832727-11.170909 95.650909 19.549091 131.956364a32.349091 32.349091 0 0 1 2.56 28.625454 56.087273 56.087273 0 0 1-16.523636 25.832727 151.505455 151.505455 0 0 1-23.272728-23.272727 151.272727 151.272727 0 0 0-66.56-52.829091c-10.007273-2.792727-21.178182-5.12-31.883636-7.447272-30.254545-6.283636-64.232727-13.498182-72.145455-30.487273a119.156364 119.156364 0 0 1-5.818181-46.545455 175.476364 175.476364 0 0 0-11.17091-74.007272 70.981818 70.981818 0 0 0-44.450909-39.563637A469.643636 469.643636 0 0 1 512 40.96zM0 512A512 512 0 1 0 512 0 512 512 0 0 0 0 512z" p-id="1420"></path></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1509704884729" class="icon" style="" viewBox="0 0 1088 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6279" xmlns:xlink="http://www.w3.org/1999/xlink" width="34" height="32"><defs><style type="text/css"></style></defs><path d="M729.6 294.4c19.2 57.6 44.8 102.4 89.6 147.2 38.4-38.4 64-89.6 83.2-147.2h-172.8zM307.2 614.4h166.4L390.4 390.4z" p-id="6280"></path><path d="M947.2 0h-768C108.8 0 51.2 57.6 51.2 128v768c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128V128c0-70.4-51.2-128-128-128zM633.6 825.6c-12.8 12.8-25.6 12.8-38.4 12.8-6.4 0-19.2 0-25.6-6.4s-12.8 0-12.8-6.4-6.4-12.8-12.8-25.6-6.4-19.2-12.8-32l-25.6-70.4H281.6L256 768c-12.8 25.6-19.2 44.8-25.6 57.6-6.4 12.8-19.2 12.8-38.4 12.8-12.8 0-25.6-6.4-38.4-12.8-12.8-12.8-19.2-19.2-19.2-32 0-6.4 0-12.8 6.4-25.6s6.4-19.2 12.8-32l140.8-358.4c6.4-12.8 6.4-25.6 12.8-38.4s12.8-25.6 19.2-32 12.8-19.2 25.6-25.6c12.8-6.4 25.6-6.4 38.4-6.4 12.8 0 25.6 0 38.4 6.4 12.8 6.4 19.2 12.8 25.6 25.6 6.4 6.4 12.8 19.2 19.2 32 6.4 12.8 12.8 25.6 19.2 44.8l140.8 352c12.8 25.6 19.2 44.8 19.2 57.6-6.4 6.4-12.8 19.2-19.2 32zM985.6 576c-70.4-25.6-121.6-57.6-166.4-96-44.8 44.8-102.4 76.8-172.8 96l-19.2-32c70.4-19.2 128-44.8 172.8-89.6-44.8-44.8-83.2-102.4-96-166.4h-64v-25.6h172.8c-12.8-19.2-25.6-44.8-38.4-64l19.2-6.4c12.8 19.2 32 44.8 44.8 70.4h160v32h-64c-19.2 64-51.2 121.6-89.6 160 44.8 38.4 96 70.4 166.4 89.6l-25.6 32z" p-id="6281"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

49
src/lang/en.js Normal file
View File

@ -0,0 +1,49 @@
export default {
route: {
dashboard: 'dashboard',
introduction: 'introduction',
permission: 'permission',
icons: 'icons',
components: 'components:',
componentIndex: 'introduction',
tinymce: 'tinymce',
markdown: 'Markdown',
jsonEditor: 'JSON Editor',
dndList: 'dnd list',
splitPane: 'Splitpane',
avatarUpload: 'avatar upload',
dropzone: 'Dropzone',
sticky: 'Sticky',
countTo: 'CountTo',
componentMixin: 'Mixin',
backToTop: 'backToTop',
charts: 'charts',
chartsIndex: 'introduction',
keyboardChart: 'keyboard chart',
keyboardChart2: 'keyboard chart2',
lineChart: 'line chart',
mixChart: 'mix chart',
example: 'example',
Table: 'Table',
dynamicTable: '动态table',
dragTable: '拖拽table',
inlineEditTable: 'table内编辑',
complexTabl: '综合table',
tab: 'Tab',
form: 'Form',
createForm: 'create form',
editForm: 'edit form',
errorPages: 'error pages',
page401: '401',
page404: '404',
errorLog: 'error log',
excel: 'excel',
exportExcel: 'export excel',
selectExcel: 'export selected',
uploadExcel: 'upload excel',
exportZip: 'zip',
theme: 'theme',
clipboardDemo: 'clipboard',
i18n: 'i18n'
}
}

27
src/lang/index.js Normal file
View File

@ -0,0 +1,27 @@
import Vue from 'vue'
import elementEnLocale from 'element-ui/lib/locale/lang/en'
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'
import enLocale from './en'
import zhLocale from './zh'
import VueI18n from 'vue-i18n'
import Cookies from 'js-cookie'
Vue.use(VueI18n)
const messages = {
en: {
...enLocale,
...elementEnLocale
},
zh: {
...zhLocale,
...elementZhLocale
}
}
const i18n = new VueI18n({
locale: Cookies.get('language') || 'zh', // set locale
messages // set locale messages
})
export default i18n

49
src/lang/zh.js Normal file
View File

@ -0,0 +1,49 @@
export default {
route: {
dashboard: '首页',
introduction: '简述',
permission: '权限测试页',
icons: '图标',
components: '组件',
componentIndex: '介绍',
tinymce: '富文本编辑器',
markdown: 'Markdown',
jsonEditor: 'JSON编辑器',
dndList: '列表拖拽',
splitPane: 'Splitpane',
avatarUpload: '头像上传',
dropzone: 'Dropzone',
sticky: 'Sticky',
countTo: 'CountTo',
componentMixin: '小组件',
backToTop: '返回顶部',
charts: '图表',
chartsIndex: '介绍',
keyboardChart: '键盘图表',
keyboardChart2: '键盘图表2',
lineChart: '折线图',
mixChart: '混合图表',
example: '综合实例',
Table: 'Table',
dynamicTable: '动态table',
dragTable: '拖拽table',
inlineEditTable: 'table内编辑',
complexTabl: '综合table',
tab: 'Tab',
form: '表单',
createForm: '创建表单',
editForm: '编辑表单',
errorPages: '错误页面',
page401: '401',
page404: '404',
errorLog: '错误日志',
excel: 'excel',
exportExcel: 'export excel',
selectExcel: 'export selected',
uploadExcel: 'upload excel',
exportZip: 'zip',
theme: '换肤',
clipboardDemo: 'clipboard',
i18n: '国际化'
}
}

View File

@ -1,6 +1,7 @@
import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import i18n from './lang' // 国际化
import App from './App'
import router from './router'
import store from './store'
@ -10,7 +11,9 @@ import './errorLog'// error log
import './permission' // 权限
import './mock' // 该项目所有请求使用mockjs模拟
Vue.use(Element)
Vue.use(Element, {
i18n: (key, value) => i18n.t(key, value)
})
// register global utility filters.
Object.keys(filters).forEach(key => {
@ -23,6 +26,7 @@ new Vue({
el: '#app',
router,
store,
i18n,
template: '<App/>',
components: { App }
})

View File

@ -33,7 +33,7 @@ export const constantRouterMap = [
path: 'dashboard',
component: _import('dashboard/index'),
name: 'dashboard',
meta: { title: '首页', icon: 'dashboard' }
meta: { title: 'dashboard', icon: 'dashboard' }
}]
},
@ -45,7 +45,7 @@ export const constantRouterMap = [
path: 'index',
component: _import('introduction/index'),
name: 'introduction',
meta: { title: '简述', icon: 'people' }
meta: { title: 'introduction', icon: 'people' }
}]
}
]
@ -67,7 +67,7 @@ export const asyncRouterMap = [
component: _import('permission/index'),
name: 'permission',
meta: {
title: '权限测试页',
title: 'permission',
icon: 'lock',
role: ['admin']
}
@ -81,7 +81,7 @@ export const asyncRouterMap = [
path: 'index',
component: _import('svg-icons/index'),
name: 'icons',
meta: { title: '图标', icon: 'icon' }
meta: { title: 'icons', icon: 'icon' }
}]
},
@ -91,22 +91,22 @@ export const asyncRouterMap = [
redirect: '/components/index',
name: 'components',
meta: {
title: '组件',
title: 'components',
icon: 'component'
},
children: [
{ path: 'index', component: _import('components/index'), name: 'componentIndex', meta: { title: '介绍' }},
{ path: 'tinymce', component: _import('components/tinymce'), name: 'tinymce', meta: { title: '富文本编辑器' }},
{ path: 'markdown', component: _import('components/markdown'), name: 'markdown', meta: { title: 'Markdown' }},
{ path: 'json-editor', component: _import('components/jsonEditor'), name: 'jsonEditor', meta: { title: 'JSON编辑器' }},
{ path: 'dnd-list', component: _import('components/dndList'), name: 'dndList', meta: { title: '列表拖拽' }},
{ path: 'splitpane', component: _import('components/splitpane'), name: 'splitpane', meta: { title: 'SplitPane' }},
{ path: 'avatar-upload', component: _import('components/avatarUpload'), name: 'avatar-upload', meta: { title: '头像上传' }},
{ path: 'dropzone', component: _import('components/dropzone'), name: 'dropzone', meta: { title: 'Dropzone' }},
{ path: 'sticky', component: _import('components/sticky'), name: 'sticky', meta: { title: 'Sticky' }},
{ path: 'count-to', component: _import('components/countTo'), name: 'count-to', meta: { title: 'CountTo' }},
{ path: 'mixin', component: _import('components/mixin'), name: 'componentMixin', meta: { title: '小组件' }},
{ path: 'back-to-top', component: _import('components/backToTop'), name: 'backToTop', meta: { title: '返回顶部' }}
{ path: 'index', component: _import('components/index'), name: 'componentIndex', meta: { title: 'componentIndex' }},
{ path: 'tinymce', component: _import('components/tinymce'), name: 'tinymce', meta: { title: 'tinymce' }},
{ path: 'markdown', component: _import('components/markdown'), name: 'markdown', meta: { title: 'markdown' }},
{ path: 'json-editor', component: _import('components/jsonEditor'), name: 'jsonEditor', meta: { title: 'jsonEditor' }},
{ path: 'dnd-list', component: _import('components/dndList'), name: 'dndList', meta: { title: 'dndList' }},
{ path: 'splitpane', component: _import('components/splitpane'), name: 'splitpane', meta: { title: 'splitPane' }},
{ path: 'avatar-upload', component: _import('components/avatarUpload'), name: 'avatarUpload', meta: { title: 'avatarUpload' }},
{ path: 'dropzone', component: _import('components/dropzone'), name: 'dropzone', meta: { title: 'dropzone' }},
{ path: 'sticky', component: _import('components/sticky'), name: 'sticky', meta: { title: 'sticky' }},
{ path: 'count-to', component: _import('components/countTo'), name: 'countTo', meta: { title: 'countTo' }},
{ path: 'mixin', component: _import('components/mixin'), name: 'componentMixin', meta: { title: 'componentMixin' }},
{ path: 'back-to-top', component: _import('components/backToTop'), name: 'backToTop', meta: { title: 'backToTop' }}
]
},
@ -116,15 +116,15 @@ export const asyncRouterMap = [
redirect: '/charts/index',
name: 'charts',
meta: {
title: '图表',
title: 'charts',
icon: 'chart'
},
children: [
{ path: 'index', component: _import('charts/index'), name: 'chartsIndex', meta: { title: '介绍' }},
{ path: 'keyboard', component: _import('charts/keyboard'), name: 'keyboardChart', meta: { title: '键盘图表' }},
{ path: 'keyboard2', component: _import('charts/keyboard2'), name: 'keyboardChart2', meta: { title: '键盘图表2' }},
{ path: 'line', component: _import('charts/line'), name: 'lineChart', meta: { title: '折线图' }},
{ path: 'mixchart', component: _import('charts/mixChart'), name: 'mixChart', meta: { title: '混合图表' }}
{ path: 'index', component: _import('charts/index'), name: 'chartsIndex', meta: { title: 'chartsIndex' }},
{ path: 'keyboard', component: _import('charts/keyboard'), name: 'keyboardChart', meta: { title: 'keyboardChart' }},
{ path: 'keyboard2', component: _import('charts/keyboard2'), name: 'keyboardChart2', meta: { title: 'keyboardChart2' }},
{ path: 'line', component: _import('charts/line'), name: 'lineChart', meta: { title: 'lineChart' }},
{ path: 'mixchart', component: _import('charts/mixChart'), name: 'mixChart', meta: { title: 'mixChart' }}
]
},
@ -134,7 +134,7 @@ export const asyncRouterMap = [
redirect: 'noredirect',
name: 'example',
meta: {
title: '综合实例',
title: 'example',
icon: 'example'
},
children: [
@ -148,13 +148,13 @@ export const asyncRouterMap = [
icon: 'table'
},
children: [
{ path: 'dynamic-table', component: _import('example/table/dynamicTable/index'), name: 'dynamicTable', meta: { title: '动态table' }},
{ path: 'drag-table', component: _import('example/table/dragTable'), name: 'dragTable', meta: { title: '拖拽table' }},
{ path: 'inline-edit-table', component: _import('example/table/inlineEditTable'), name: 'inlineEditTable', meta: { title: 'table内编辑' }},
{ path: 'complex-table', component: _import('example/table/complexTable'), name: 'complexTable', meta: { title: '综合table' }}
{ path: 'dynamic-table', component: _import('example/table/dynamicTable/index'), name: 'dynamicTable', meta: { title: 'dynamicTable' }},
{ path: 'drag-table', component: _import('example/table/dragTable'), name: 'dragTable', meta: { title: 'dragTable' }},
{ path: 'inline-edit-table', component: _import('example/table/inlineEditTable'), name: 'inlineEditTable', meta: { title: 'inlineEditTable' }},
{ path: 'complex-table', component: _import('example/table/complexTable'), name: 'complexTable', meta: { title: 'complexTabl' }}
]
},
{ path: 'tab/index', icon: 'tab', component: _import('example/tab/index'), name: 'tab', meta: { title: 'Tab' }}
{ path: 'tab/index', icon: 'tab', component: _import('example/tab/index'), name: 'tab', meta: { title: 'tab' }}
]
},
@ -164,12 +164,12 @@ export const asyncRouterMap = [
redirect: 'noredirect',
name: 'form',
meta: {
title: '表单',
title: 'form',
icon: 'form'
},
children: [
{ path: 'create-form', component: _import('form/create'), name: 'createForm', meta: { title: '创建表单', icon: 'table' }},
{ path: 'edit-form', component: _import('form/edit'), name: 'editForm', meta: { title: '编辑表单', icon: 'table' }}
{ path: 'create-form', component: _import('form/create'), name: 'createForm', meta: { title: 'createForm', icon: 'table' }},
{ path: 'edit-form', component: _import('form/edit'), name: 'editForm', meta: { title: 'editForm', icon: 'table' }}
]
},
@ -179,12 +179,12 @@ export const asyncRouterMap = [
redirect: 'noredirect',
name: 'errorPages',
meta: {
title: '错误页面',
title: 'errorPages',
icon: '404'
},
children: [
{ path: '401', component: _import('errorPage/401'), name: 'page401', meta: { title: '401', noCache: true }},
{ path: '404', component: _import('errorPage/404'), name: 'page404', meta: { title: '404', noCache: true }}
{ path: '401', component: _import('errorPage/401'), name: 'page401', meta: { title: 'page401', noCache: true }},
{ path: '404', component: _import('errorPage/404'), name: 'page404', meta: { title: 'page404', noCache: true }}
]
},
@ -192,7 +192,7 @@ export const asyncRouterMap = [
path: '/error-log',
component: Layout,
redirect: 'noredirect',
children: [{ path: 'log', component: _import('errorLog/index'), name: 'errorLog', meta: { title: '错误日志', icon: 'bug' }}]
children: [{ path: 'log', component: _import('errorLog/index'), name: 'errorLog', meta: { title: 'errorLog', icon: 'bug' }}]
},
{
@ -205,9 +205,9 @@ export const asyncRouterMap = [
icon: 'excel'
},
children: [
{ path: 'export-excel', component: _import('excel/exportExcel'), name: 'exportExcel', meta: { title: 'export excel', noCache: true }},
{ path: 'export-selected-excel', component: _import('excel/selectExcel'), name: 'selectExcel', meta: { title: 'export selected', noCache: true }},
{ path: 'upload-excel', component: _import('excel/uploadExcel'), name: 'uploadExcel', meta: { title: 'upload excel', noCache: true }}
{ path: 'export-excel', component: _import('excel/exportExcel'), name: 'exportExcel', meta: { title: 'exportExcel', noCache: true }},
{ path: 'export-selected-excel', component: _import('excel/selectExcel'), name: 'selectExcel', meta: { title: 'selectExcel', noCache: true }},
{ path: 'upload-excel', component: _import('excel/uploadExcel'), name: 'uploadExcel', meta: { title: 'uploadExcel', noCache: true }}
]
},
@ -215,21 +215,27 @@ export const asyncRouterMap = [
path: '/zip',
component: Layout,
redirect: '/zip/download',
children: [{ path: 'download', component: _import('zip/index'), name: 'exportZip', meta: { title: 'zip', icon: 'zip' }}]
children: [{ path: 'download', component: _import('zip/index'), name: 'exportZip', meta: { title: 'exportZip', icon: 'zip' }}]
},
{
path: '/theme',
component: Layout,
redirect: 'noredirect',
children: [{ path: 'index', component: _import('theme/index'), name: 'theme', meta: { title: '换肤', icon: 'theme' }}]
children: [{ path: 'index', component: _import('theme/index'), name: 'theme', meta: { title: 'theme', icon: 'theme' }}]
},
{
path: '/clipboard',
component: Layout,
redirect: 'noredirect',
children: [{ path: 'index', component: _import('clipboard/index'), name: 'clipboardDemo', meta: { title: 'clipboard', icon: 'clipboard' }}]
children: [{ path: 'index', component: _import('clipboard/index'), name: 'clipboardDemo', meta: { title: 'clipboardDemo', icon: 'clipboard' }}]
},
{
path: '/i18n',
component: Layout,
children: [{ path: 'index', component: _import('i18n/index'), name: 'i18n', meta: { title: 'i18n', icon: 'international' }}]
},
{ path: '*', redirect: '/404', hidden: true }

View File

@ -1,5 +1,6 @@
const getters = {
sidebar: state => state.app.sidebar,
language: state => state.app.language,
visitedViews: state => state.app.visitedViews,
cachedViews: state => state.app.cachedViews,
token: state => state.user.token,

View File

@ -5,6 +5,7 @@ const app = {
sidebar: {
opened: !+Cookies.get('sidebarStatus')
},
language: Cookies.get('language') || 'zh',
visitedViews: [],
cachedViews: []
},
@ -17,6 +18,10 @@ const app = {
}
state.sidebar.opened = !state.sidebar.opened
},
SET_LANGUAGE: (state, language) => {
state.language = language
Cookies.set('language', language)
},
ADD_VISITED_VIEWS: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push({
@ -48,6 +53,9 @@ const app = {
ToggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
setLanguage({ commit }, language) {
commit('SET_LANGUAGE', language)
},
addVisitedViews({ commit }, view) {
commit('ADD_VISITED_VIEWS', view)
},

107
src/views/i18n/index.vue Normal file
View File

@ -0,0 +1,107 @@
<template>
<div class="app-container">
<el-card class="box-card">
<div slot="header" class="clearfix">
<svg-icon icon-class="international" />
<span style='margin-left:10px;'>{{$t('i18nView.title')}}</span>
</div>
<div>
<el-radio-group v-model="lang" size="small">
<el-radio label="zh" border>简体中文</el-radio>
<el-radio label="en" border>English</el-radio>
</el-radio-group>
<el-tag style='margin-top:15px;display:block;' type="info">{{$t('i18nView.note')}}</el-tag>
</div>
</el-card>
<el-row :gutter="20" style="margin:100px 50px 50px;">
<el-col :span="12">
<div class="block">
<el-date-picker v-model="date" type="date" :placeholder="$t('i18nView.datePlaceholder')"></el-date-picker>
</div>
<div class="block">
<el-pagination :current-page="currentPage" :page-sizes="[100, 200, 300, 400]" :page-size="100" layout="total, sizes, prev, pager, next, jumper"
:total="400">
</el-pagination>
</div>
<div class="block">
<el-button size="small">{{$t('i18nView.default')}}</el-button>
<el-button size="small" type="primary">{{$t('i18nView.primary')}}</el-button>
<el-button size="small" type="success">{{$t('i18nView.success')}}</el-button>
<el-button size="small" type="info">{{$t('i18nView.info')}}</el-button>
<el-button size="small" type="warning">{{$t('i18nView.warning')}}</el-button>
<el-button size="small" type="danger">{{$t('i18nView.danger')}}</el-button>
</div>
</el-col>
<el-col :span="12">
<el-table :data="tableData" fit highlight-current-row border style="width: 100%">
<el-table-column prop="date" :label="$t('i18nView.tableDate')" width="180"></el-table-column>
<el-table-column prop="name" :label="$t('i18nView.tableName')" width="180"></el-table-column>
<el-table-column prop="address" :label="$t('i18nView.tableAddress')"></el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
import local from './local'
const viewName = 'i18nView'
export default {
name: 'i18n',
data() {
return {
date: '',
currentPage: 5,
tableData: [{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}]
}
},
created() {
if (!this.$i18n.getLocaleMessage('en')[viewName]) {
this.$i18n.mergeLocaleMessage('en', local.en)
this.$i18n.mergeLocaleMessage('zh', local.zh)
}
},
computed: {
lang: {
get() {
return this.$store.state.app.language
},
set(lang) {
this.$i18n.locale = lang
this.$store.dispatch('setLanguage', lang)
}
}
}
}
</script>
<style scoped>
.box-card {
width: 600px;
margin: 20px auto;
}
.block {
padding: 25px;
}
</style>

36
src/views/i18n/local.js Normal file
View File

@ -0,0 +1,36 @@
export default {
zh: {
i18nView: {
title: '切换语言',
note: '目前只翻译了当前页面和侧边栏和导航,未完待续,敬请期待...',
datePlaceholder: '请选择日期',
tableDate: '日期',
tableName: '姓名',
tableAddress: '地址',
default: '默认按钮',
primary: '主要按钮',
success: '成功按钮',
info: '信息按钮',
warning: '警告按钮',
danger: '危险按钮'
}
},
en: {
i18nView: {
title: 'Switch Language',
note: 'Currently only translated the i18n page and the sidebar and levelbar, please look forword to...',
datePlaceholder: 'Pick a day',
tableDate: 'tableDate',
tableName: 'tableName',
tableAddress: 'tableAddress',
default: 'default:',
primary: 'primary',
success: 'success',
info: 'info',
warning: 'warning',
danger: 'danger'
}
}
}

View File

@ -12,6 +12,14 @@
<screenfull class="screenfull right-menu-item"></screenfull>
</el-tooltip>
<el-dropdown trigger="click" class='international' @command="handleSetLanguage">
<svg-icon class-name='right-menu-item international-icon' icon-class="language" />
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="zh" :disabled="language==='zh'">中文</el-dropdown-item>
<el-dropdown-item command="en" :disabled="language==='en'">English</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-tooltip effect="dark" content="换肤" placement="bottom">
<theme-picker class="theme-switch right-menu-item"></theme-picker>
</el-tooltip>
@ -21,8 +29,8 @@
<img class="user-avatar" :src="avatar+'?imageView2/1/w/80/h/80'">
<i class="el-icon-caret-bottom"></i>
</div>
<el-dropdown-menu class="user-dropdown" slot="dropdown">
<router-link class="inlineBlock" to="/">
<el-dropdown-menu slot="dropdown">
<router-link to="/">
<el-dropdown-item>
首页
</el-dropdown-item>
@ -41,10 +49,6 @@
</el-menu>
</template>
<script>
import { mapGetters } from 'vuex'
import Levelbar from './Levelbar'
@ -71,13 +75,22 @@ export default {
...mapGetters([
'sidebar',
'name',
'avatar'
'avatar',
'language'
])
},
methods: {
toggleSideBar() {
this.$store.dispatch('ToggleSideBar')
},
handleSetLanguage(lang) {
this.$i18n.locale = lang
this.$store.dispatch('setLanguage', lang)
this.$message({
message: 'switch language success',
type: 'success'
})
},
logout() {
this.$store.dispatch('LogOut').then(() => {
location.reload()// vue-router bug
@ -115,6 +128,14 @@ export default {
.screenfull {
height: 20px;
}
.international{
vertical-align: top;
.international-icon{
font-size: 20px;
cursor: pointer;
vertical-align: -5px;
}
}
.theme-switch {
vertical-align: 15px;
}

View File

@ -5,14 +5,14 @@
<router-link v-if="!item.hidden&&item.children&&item.children.length===1" :to="item.path+'/'+item.children[0].path" :key='item.children[0].name'>
<el-menu-item :index="item.path+'/'+item.children[0].path" class='submenu-title-noDropdown'>
<svg-icon v-if='item.children[0].meta&&item.children[0].meta.icon' :icon-class="item.children[0].meta.icon"></svg-icon>
<span>{{item.children[0].meta?item.children[0].meta.title:'no title'}}</span>
<span>{{item.children[0].meta?generateTitle(item.children[0].meta.title):'no title'}}</span>
</el-menu-item>
</router-link>
<el-submenu :index="item.name" v-if="item.children&&item.children.length>1&&!item.hidden" :key='item.name'>
<template slot="title">
<svg-icon v-if='item.meta&&item.meta.icon' :icon-class="item.meta.icon"></svg-icon>
<span>{{item.meta?item.meta.title:'no title'}}</span>
<span>{{item.meta?generateTitle(item.meta.title):'no title'}}</span>
</template>
<template v-for="child in item.children" v-if='!child.hidden'>
@ -21,7 +21,7 @@
<router-link v-else :to="item.path+'/'+child.path" :key='child.name'>
<el-menu-item :index="item.path+'/'+child.path">
<svg-icon v-if='child.meta&&child.meta.icon' :icon-class="child.meta.icon"></svg-icon>
<span v-if='child.meta' >{{child.meta.title}}</span>
<span v-if='child.meta' >{{generateTitle(child.meta.title)}}</span>
</el-menu-item>
</router-link>
@ -39,6 +39,11 @@ export default {
routes: {
type: Array
}
},
methods: {
generateTitle(title) {
return this.$t('route.' + title)
}
}
}
</script>