Commit d33b51432d8c13900f1062d84860fb0082780804

Authored by 梁灏
1 parent 86b4da54

support i18n

support i18n
@@ -40,6 +40,7 @@ @@ -40,6 +40,7 @@
40 "dependencies": { 40 "dependencies": {
41 "async-validator": "^1.6.7", 41 "async-validator": "^1.6.7",
42 "core-js": "^2.4.1", 42 "core-js": "^2.4.1",
  43 + "deepmerge": "^1.3.1",
43 "popper.js": "^0.6.4" 44 "popper.js": "^0.6.4"
44 }, 45 },
45 "peerDependencies": { 46 "peerDependencies": {
src/components/select/select.vue
@@ -35,6 +35,7 @@ @@ -35,6 +35,7 @@
35 import Dropdown from './dropdown.vue'; 35 import Dropdown from './dropdown.vue';
36 import clickoutside from '../../directives/clickoutside'; 36 import clickoutside from '../../directives/clickoutside';
37 import { oneOf, MutationObserver } from '../../utils/assist'; 37 import { oneOf, MutationObserver } from '../../utils/assist';
  38 + import { t } from '../../locale';
38 39
39 const prefixCls = 'ivu-select'; 40 const prefixCls = 'ivu-select';
40 41
@@ -60,7 +61,9 @@ @@ -60,7 +61,9 @@
60 }, 61 },
61 placeholder: { 62 placeholder: {
62 type: String, 63 type: String,
63 - default: '请选择' 64 + default () {
  65 + return t('i.select.placeholder');
  66 + }
64 }, 67 },
65 filterable: { 68 filterable: {
66 type: Boolean, 69 type: Boolean,
@@ -80,7 +83,9 @@ @@ -80,7 +83,9 @@
80 }, 83 },
81 notFoundText: { 84 notFoundText: {
82 type: String, 85 type: String,
83 - default: '无匹配数据' 86 + default () {
  87 + return t('i.select.noMatch');
  88 + }
84 } 89 }
85 }, 90 },
86 data () { 91 data () {
@@ -40,6 +40,7 @@ import Tooltip from './components/tooltip'; @@ -40,6 +40,7 @@ import Tooltip from './components/tooltip';
40 import Transfer from './components/transfer'; 40 import Transfer from './components/transfer';
41 import { Row, Col } from './components/layout'; 41 import { Row, Col } from './components/layout';
42 import { Select, Option, OptionGroup } from './components/select'; 42 import { Select, Option, OptionGroup } from './components/select';
  43 +import locale from './locale';
43 44
44 const iview = { 45 const iview = {
45 Affix, 46 Affix,
@@ -100,7 +101,10 @@ const iview = { @@ -100,7 +101,10 @@ const iview = {
100 Transfer 101 Transfer
101 }; 102 };
102 103
103 -const install = function (Vue) { 104 +const install = function (Vue, opts = {}) {
  105 + locale.use(opts.locale);
  106 + locale.i18n(opts.i18n);
  107 +
104 Object.keys(iview).forEach((key) => { 108 Object.keys(iview).forEach((key) => {
105 Vue.component(key, iview[key]); 109 Vue.component(key, iview[key]);
106 }); 110 });
src/locale/format.js 0 → 100644
  1 +/**
  2 + * String format template
  3 + * - Inspired:
  4 + * https://github.com/Matt-Esch/string-template/index.js
  5 + */
  6 +
  7 +const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g;
  8 +
  9 +export default function(Vue) {
  10 + const { hasOwn } = Vue.util;
  11 +
  12 + /**
  13 + * template
  14 + *
  15 + * @param {String} string
  16 + * @param {Array} ...args
  17 + * @return {String}
  18 + */
  19 +
  20 + function template(string, ...args) {
  21 + if (args.length === 1 && typeof args[0] === 'object') {
  22 + args = args[0];
  23 + }
  24 +
  25 + if (!args || !args.hasOwnProperty) {
  26 + args = {};
  27 + }
  28 +
  29 + return string.replace(RE_NARGS, (match, prefix, i, index) => {
  30 + let result;
  31 +
  32 + if (string[index - 1] === '{' &&
  33 + string[index + match.length] === '}') {
  34 + return i;
  35 + } else {
  36 + result = hasOwn(args, i) ? args[i] : null;
  37 + if (result === null || result === undefined) {
  38 + return '';
  39 + }
  40 +
  41 + return result;
  42 + }
  43 + });
  44 + }
  45 +
  46 + return template;
  47 +}
src/locale/index.js 0 → 100644
  1 +// https://github.com/ElemeFE/element/blob/dev/src/locale/index.js
  2 +
  3 +import defaultLang from './lang/zh-CN';
  4 +import Vue from 'vue';
  5 +import deepmerge from 'deepmerge';
  6 +import Format from './format';
  7 +
  8 +const format = Format(Vue);
  9 +let lang = defaultLang;
  10 +let merged = false;
  11 +let i18nHandler = function() {
  12 + const vuei18n = Object.getPrototypeOf(this || Vue).$t;
  13 + if (typeof vuei18n === 'function') {
  14 + if (!merged) {
  15 + merged = true;
  16 + Vue.locale(
  17 + Vue.config.lang,
  18 + deepmerge(lang, Vue.locale(Vue.config.lang) || {}, { clone: true })
  19 + );
  20 + }
  21 + return vuei18n.apply(this, arguments);
  22 + }
  23 +};
  24 +
  25 +export const t = function(path, options) {
  26 + let value = i18nHandler.apply(this, arguments);
  27 + if (value !== null && value !== undefined) return value;
  28 +
  29 + const array = path.split('.');
  30 + let current = lang;
  31 +
  32 + for (let i = 0, j = array.length; i < j; i++) {
  33 + const property = array[i];
  34 + value = current[property];
  35 + if (i === j - 1) return format(value, options);
  36 + if (!value) return '';
  37 + current = value;
  38 + }
  39 + return '';
  40 +};
  41 +
  42 +export const use = function(l) {
  43 + lang = l || lang;
  44 +};
  45 +
  46 +export const i18n = function(fn) {
  47 + i18nHandler = fn || i18nHandler;
  48 +};
  49 +
  50 +export default { use, t, i18n };
0 \ No newline at end of file 51 \ No newline at end of file
src/locale/lang/en-US.js 0 → 100644
  1 +export default {
  2 + i: {
  3 + select: {
  4 + placeholder: 'Select',
  5 + noMatch: 'No matching data'
  6 + }
  7 + }
  8 +};
0 \ No newline at end of file 9 \ No newline at end of file
src/locale/lang/zh-CN.js 0 → 100644
  1 +export default {
  2 + i: {
  3 + select: {
  4 + placeholder: '请选择',
  5 + noMatch: '无匹配数据'
  6 + }
  7 + }
  8 +};
0 \ No newline at end of file 9 \ No newline at end of file
src/locale/lang/zh-TW.js 0 → 100644
  1 +export default {
  2 + i: {
  3 + select: {
  4 + placeholder: '請選擇',
  5 + noMatch: '無匹配數據'
  6 + }
  7 + }
  8 +};
0 \ No newline at end of file 9 \ No newline at end of file
@@ -5,9 +5,10 @@ import Vue from &#39;vue&#39;; @@ -5,9 +5,10 @@ import Vue from &#39;vue&#39;;
5 import VueRouter from 'vue-router'; 5 import VueRouter from 'vue-router';
6 import App from './app.vue'; 6 import App from './app.vue';
7 import iView from '../src/index'; 7 import iView from '../src/index';
  8 +import locale from '../src/locale/lang/en-US';
8 9
9 Vue.use(VueRouter); 10 Vue.use(VueRouter);
10 -Vue.use(iView); 11 +Vue.use(iView, { locale });
11 12
12 // 开启debug模式 13 // 开启debug模式
13 Vue.config.debug = true; 14 Vue.config.debug = true;
test/routers/select.vue
@@ -2,12 +2,12 @@ @@ -2,12 +2,12 @@
2 <Row> 2 <Row>
3 <i-col span="12" style="padding-right:10px"> 3 <i-col span="12" style="padding-right:10px">
4 <i-select :model.sync="model11" filterable> 4 <i-select :model.sync="model11" filterable>
5 - <i-option v-for="item in cityList" :value="item.value" :label="item.label"><span>{{ item.label }}</span><span>{{ item.des }}</span></i-option> 5 + <i-option v-for="item in cityList" :value="item.value">{{ item.label }}</i-option>
6 </i-select> 6 </i-select>
7 </i-col> 7 </i-col>
8 <i-col span="12"> 8 <i-col span="12">
9 <i-select :model.sync="model12" filterable multiple> 9 <i-select :model.sync="model12" filterable multiple>
10 - <i-option v-for="item in cityList" :value="item.value" :label="item.label"><span>{{ item.label }}</span><span>{{ item.des }}</span></i-option> 10 + <i-option v-for="item in cityList" :value="item.value">{{ item.label }}</i-option>
11 </i-select> 11 </i-select>
12 </i-col> 12 </i-col>
13 </Row> 13 </Row>
@@ -19,27 +19,31 @@ @@ -19,27 +19,31 @@
19 cityList: [ 19 cityList: [
20 { 20 {
21 value: 'beijing', 21 value: 'beijing',
22 - label: '北京市',  
23 - des: '帝都' 22 + label: '北京市'
24 }, 23 },
25 { 24 {
26 value: 'shanghai', 25 value: 'shanghai',
27 - label: '上海市',  
28 - des: '魔都' 26 + label: '上海市'
29 }, 27 },
30 { 28 {
31 value: 'shenzhen', 29 value: 'shenzhen',
32 - label: '深圳市',  
33 - des: '渔村' 30 + label: '深圳市'
  31 + },
  32 + {
  33 + value: 'hangzhou',
  34 + label: '杭州市'
  35 + },
  36 + {
  37 + value: 'nanjing',
  38 + label: '南京市'
34 }, 39 },
35 { 40 {
36 value: 'chongqing', 41 value: 'chongqing',
37 - label: '重庆市',  
38 - des: '山城' 42 + label: '重庆市'
39 } 43 }
40 ], 44 ],
41 model11: '', 45 model11: '',
42 - model12: ['beijing', 'shanghai'] 46 + model12: []
43 } 47 }
44 } 48 }
45 } 49 }