Commit e5337c810c3a25c0b448d7a6dcbff97d2a1faeae

Authored by 梁灏
1 parent ed91d9b0

fixed some components bug that can not translate when using vue-i18n

examples/routers/modal.vue
1 <template> 1 <template>
2 <div> 2 <div>
3 - <i-button @click.native="modal2 = true">自定义页头和页脚</i-button>  
4 - <Modal v-model="modal2" width="360">  
5 - <p slot="header" style="color:#f60;text-align:center">  
6 - <Icon type="information-circled"></Icon>  
7 - <span>删除确认</span>  
8 - </p>  
9 - <div style="text-align:center">  
10 - <p>此任务删除后,下游 10 个任务将无法执行。</p>  
11 - <p>是否继续删除?</p>  
12 - </div>  
13 - <div slot="footer">  
14 - <i-button type="error" size="large" long :loading="modal_loading" @click.native="del">删除</i-button>  
15 - </div>  
16 - </Modal> 3 + <Button @click="confirm">标准</Button>
  4 + <Button @click="custom">自定义按钮文字</Button>
  5 + <Button @click="async">异步关闭</Button>
17 </div> 6 </div>
18 </template> 7 </template>
19 <script> 8 <script>
20 export default { 9 export default {
21 - data () {  
22 - return {  
23 - modal2: false,  
24 - modal_loading: false,  
25 - modal3: false,  
26 - modal4: false,  
27 - modal5: false  
28 - }  
29 - },  
30 methods: { 10 methods: {
31 - del () {  
32 - this.modal_loading = true;  
33 - setTimeout(() => {  
34 - this.modal_loading = false;  
35 - this.modal2 = false;  
36 - this.$Message.success('删除成功');  
37 - }, 2000); 11 + confirm () {
  12 + this.$Modal.confirm({
  13 + title: '确认对话框标题',
  14 + content: '<p>一些对话框内容</p><p>一些对话框内容</p>',
  15 + onOk: () => {
  16 + this.$Message.info('点击了确定');
  17 + },
  18 + onCancel: () => {
  19 + this.$Message.info('点击了取消');
  20 + }
  21 + });
  22 + },
  23 + custom () {
  24 + this.$Modal.confirm({
  25 + title: '确认对话框标题',
  26 + content: '<p>一些对话框内容</p><p>一些对话框内容</p>',
  27 + okText: 'OK',
  28 + cancelText: 'Cancel'
  29 + });
  30 + },
  31 + async () {
  32 + this.$Modal.confirm({
  33 + title: '确认对话框标题',
  34 + content: '<p>对话框将在 2秒 后关闭</p>',
  35 + loading: true,
  36 + onOk: () => {
  37 + setTimeout(() => {
  38 + this.$Modal.remove();
  39 + this.$Message.info('异步关闭了对话框');
  40 + }, 2000);
  41 + }
  42 + });
38 } 43 }
39 } 44 }
40 } 45 }
src/components/modal/confirm.js
@@ -3,7 +3,7 @@ import Modal from &#39;./modal.vue&#39;; @@ -3,7 +3,7 @@ import Modal from &#39;./modal.vue&#39;;
3 import Icon from '../icon/icon.vue'; 3 import Icon from '../icon/icon.vue';
4 import iButton from '../button/button.vue'; 4 import iButton from '../button/button.vue';
5 import { camelcaseToHyphen } from '../../utils/assist'; 5 import { camelcaseToHyphen } from '../../utils/assist';
6 -import { t } from '../../locale'; 6 +import Locale from '../../mixins/locale';
7 7
8 const prefixCls = 'ivu-modal-confirm'; 8 const prefixCls = 'ivu-modal-confirm';
9 9
@@ -27,8 +27,8 @@ Modal.newInstance = properties =&gt; { @@ -27,8 +27,8 @@ Modal.newInstance = properties =&gt; {
27 <div v-html="body"></div> 27 <div v-html="body"></div>
28 </div> 28 </div>
29 <div class="${prefixCls}-footer"> 29 <div class="${prefixCls}-footer">
30 - <i-button type="text" size="large" v-if="showCancel" @click.native="cancel">{{ cancelText }}</i-button>  
31 - <i-button type="primary" size="large" :loading="buttonLoading" @click.native="ok">{{ okText }}</i-button> 30 + <i-button type="text" size="large" v-if="showCancel" @click.native="cancel">{{ localeCancelText }}</i-button>
  31 + <i-button type="primary" size="large" :loading="buttonLoading" @click.native="ok">{{ localeOkText }}</i-button>
32 </div> 32 </div>
33 </div> 33 </div>
34 </Modal> 34 </Modal>
@@ -37,6 +37,7 @@ Modal.newInstance = properties =&gt; { @@ -37,6 +37,7 @@ Modal.newInstance = properties =&gt; {
37 37
38 const modal = new Vue({ 38 const modal = new Vue({
39 el: div, 39 el: div,
  40 + mixins: [ Locale ],
40 components: { Modal, iButton, Icon }, 41 components: { Modal, iButton, Icon },
41 data: Object.assign(_props, { 42 data: Object.assign(_props, {
42 visible: false, 43 visible: false,
@@ -45,8 +46,8 @@ Modal.newInstance = properties =&gt; { @@ -45,8 +46,8 @@ Modal.newInstance = properties =&gt; {
45 body: '', 46 body: '',
46 iconType: '', 47 iconType: '',
47 iconName: '', 48 iconName: '',
48 - okText: t('i.modal.okText'),  
49 - cancelText: t('i.modal.cancelText'), 49 + okText: undefined,
  50 + cancelText: undefined,
50 showCancel: false, 51 showCancel: false,
51 loading: false, 52 loading: false,
52 buttonLoading: false, 53 buttonLoading: false,
@@ -64,6 +65,20 @@ Modal.newInstance = properties =&gt; { @@ -64,6 +65,20 @@ Modal.newInstance = properties =&gt; {
64 'ivu-icon', 65 'ivu-icon',
65 `ivu-icon-${this.iconName}` 66 `ivu-icon-${this.iconName}`
66 ]; 67 ];
  68 + },
  69 + localeOkText () {
  70 + if (this.okText) {
  71 + return this.okText;
  72 + } else {
  73 + return this.t('i.modal.okText');
  74 + }
  75 + },
  76 + localeCancelText () {
  77 + if (this.cancelText) {
  78 + return this.cancelText;
  79 + } else {
  80 + return this.t('i.modal.cancelText');
  81 + }
67 } 82 }
68 }, 83 },
69 methods: { 84 methods: {
src/components/modal/modal.vue
@@ -16,8 +16,8 @@ @@ -16,8 +16,8 @@
16 <div :class="[prefixCls + '-body']"><slot></slot></div> 16 <div :class="[prefixCls + '-body']"><slot></slot></div>
17 <div :class="[prefixCls + '-footer']" v-if="!footerHide"> 17 <div :class="[prefixCls + '-footer']" v-if="!footerHide">
18 <slot name="footer"> 18 <slot name="footer">
19 - <i-button type="text" size="large" @click.native="cancel">{{ cancelText }}</i-button>  
20 - <i-button type="primary" size="large" :loading="buttonLoading" @click.native="ok">{{ okText }}</i-button> 19 + <i-button type="text" size="large" @click.native="cancel">{{ localeCancelText }}</i-button>
  20 + <i-button type="primary" size="large" :loading="buttonLoading" @click.native="ok">{{ localeOkText }}</i-button>
21 </slot> 21 </slot>
22 </div> 22 </div>
23 </div> 23 </div>
@@ -30,11 +30,13 @@ @@ -30,11 +30,13 @@
30 import Icon from '../icon'; 30 import Icon from '../icon';
31 import iButton from '../button/button.vue'; 31 import iButton from '../button/button.vue';
32 import { getScrollBarSize } from '../../utils/assist'; 32 import { getScrollBarSize } from '../../utils/assist';
33 - import { t } from '../../locale'; 33 + import Locale from '../../mixins/locale';
34 34
35 const prefixCls = 'ivu-modal'; 35 const prefixCls = 'ivu-modal';
36 36
37 export default { 37 export default {
  38 + name: 'Modal',
  39 + mixins: [ Locale ],
38 components: { Icon, iButton }, 40 components: { Icon, iButton },
39 props: { 41 props: {
40 value: { 42 value: {
@@ -57,16 +59,10 @@ @@ -57,16 +59,10 @@
57 default: 520 59 default: 520
58 }, 60 },
59 okText: { 61 okText: {
60 - type: String,  
61 - default () {  
62 - return t('i.modal.okText');  
63 - } 62 + type: String
64 }, 63 },
65 cancelText: { 64 cancelText: {
66 - type: String,  
67 - default () {  
68 - return t('i.modal.cancelText');  
69 - } 65 + type: String
70 }, 66 },
71 loading: { 67 loading: {
72 type: Boolean, 68 type: Boolean,
@@ -125,6 +121,20 @@ @@ -125,6 +121,20 @@
125 Object.assign(style, styleWidth, customStyle); 121 Object.assign(style, styleWidth, customStyle);
126 122
127 return style; 123 return style;
  124 + },
  125 + localeOkText () {
  126 + if (this.okText === undefined) {
  127 + return this.t('i.modal.okText');
  128 + } else {
  129 + return this.okText;
  130 + }
  131 + },
  132 + localeCancelText () {
  133 + if (this.cancelText === undefined) {
  134 + return this.t('i.modal.cancelText');
  135 + } else {
  136 + return this.cancelText;
  137 + }
128 } 138 }
129 }, 139 },
130 methods: { 140 methods: {
src/components/poptip/poptip.vue
@@ -22,8 +22,8 @@ @@ -22,8 +22,8 @@
22 <div :class="[prefixCls + '-body-message']"><slot name="title">{{ title }}</slot></div> 22 <div :class="[prefixCls + '-body-message']"><slot name="title">{{ title }}</slot></div>
23 </div> 23 </div>
24 <div :class="[prefixCls + '-footer']"> 24 <div :class="[prefixCls + '-footer']">
25 - <i-button type="text" size="small" @click.native="cancel">{{ cancelText }}</i-button>  
26 - <i-button type="primary" size="small" @click.native="ok">{{ okText }}</i-button> 25 + <i-button type="text" size="small" @click.native="cancel">{{ localeCancelText }}</i-button>
  26 + <i-button type="primary" size="small" @click.native="ok">{{ localeOkText }}</i-button>
27 </div> 27 </div>
28 </div> 28 </div>
29 <div :class="[prefixCls + '-inner']" v-if="!confirm"> 29 <div :class="[prefixCls + '-inner']" v-if="!confirm">
@@ -42,13 +42,13 @@ @@ -42,13 +42,13 @@
42 import iButton from '../button/button.vue'; 42 import iButton from '../button/button.vue';
43 import clickoutside from '../../directives/clickoutside'; 43 import clickoutside from '../../directives/clickoutside';
44 import { oneOf } from '../../utils/assist'; 44 import { oneOf } from '../../utils/assist';
45 - import { t } from '../../locale'; 45 + import Locale from '../../mixins/locale';
46 46
47 const prefixCls = 'ivu-poptip'; 47 const prefixCls = 'ivu-poptip';
48 48
49 export default { 49 export default {
50 name: 'Poptip', 50 name: 'Poptip',
51 - mixins: [Popper], 51 + mixins: [ Popper, Locale ],
52 directives: { clickoutside }, 52 directives: { clickoutside },
53 components: { iButton }, 53 components: { iButton },
54 props: { 54 props: {
@@ -79,16 +79,10 @@ @@ -79,16 +79,10 @@
79 default: false 79 default: false
80 }, 80 },
81 okText: { 81 okText: {
82 - type: String,  
83 - default () {  
84 - return t('i.poptip.okText');  
85 - } 82 + type: String
86 }, 83 },
87 cancelText: { 84 cancelText: {
88 - type: String,  
89 - default () {  
90 - return t('i.poptip.cancelText');  
91 - } 85 + type: String
92 } 86 }
93 }, 87 },
94 data () { 88 data () {
@@ -114,6 +108,20 @@ @@ -114,6 +108,20 @@
114 style.width = `${this.width}px`; 108 style.width = `${this.width}px`;
115 } 109 }
116 return style; 110 return style;
  111 + },
  112 + localeOkText () {
  113 + if (this.okText === undefined) {
  114 + return this.t('i.poptip.okText');
  115 + } else {
  116 + return this.okText;
  117 + }
  118 + },
  119 + localeCancelText () {
  120 + if (this.cancelText === undefined) {
  121 + return this.t('i.poptip.cancelText');
  122 + } else {
  123 + return this.cancelText;
  124 + }
117 } 125 }
118 }, 126 },
119 methods: { 127 methods: {
src/components/select/select.vue
@@ -8,14 +8,14 @@ @@ -8,14 +8,14 @@
8 <span class="ivu-tag-text">{{ item.label }}</span> 8 <span class="ivu-tag-text">{{ item.label }}</span>
9 <Icon type="ios-close-empty" @click.native.stop="removeTag(index)"></Icon> 9 <Icon type="ios-close-empty" @click.native.stop="removeTag(index)"></Icon>
10 </div> 10 </div>
11 - <span :class="[prefixCls + '-placeholder']" v-show="showPlaceholder && !filterable">{{ placeholder }}</span> 11 + <span :class="[prefixCls + '-placeholder']" v-show="showPlaceholder && !filterable">{{ localePlaceholder }}</span>
12 <span :class="[prefixCls + '-selected-value']" v-show="!showPlaceholder && !multiple && !filterable">{{ selectedSingle }}</span> 12 <span :class="[prefixCls + '-selected-value']" v-show="!showPlaceholder && !multiple && !filterable">{{ selectedSingle }}</span>
13 <input 13 <input
14 type="text" 14 type="text"
15 v-if="filterable" 15 v-if="filterable"
16 v-model="query" 16 v-model="query"
17 :class="[prefixCls + '-input']" 17 :class="[prefixCls + '-input']"
18 - :placeholder="showPlaceholder ? placeholder : ''" 18 + :placeholder="showPlaceholder ? localePlaceholder : ''"
19 :style="inputStyle" 19 :style="inputStyle"
20 @blur="handleBlur" 20 @blur="handleBlur"
21 @keydown="resetInputState" 21 @keydown="resetInputState"
@@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
26 </div> 26 </div>
27 <transition name="slide-up"> 27 <transition name="slide-up">
28 <Drop v-show="visible" ref="dropdown"> 28 <Drop v-show="visible" ref="dropdown">
29 - <ul v-show="notFound" :class="[prefixCls + '-not-found']"><li>{{ notFoundText }}</li></ul> 29 + <ul v-show="notFound" :class="[prefixCls + '-not-found']"><li>{{ localeNotFoundText }}</li></ul>
30 <ul v-show="!notFound" :class="[prefixCls + '-dropdown-list']" ref="options"><slot></slot></ul> 30 <ul v-show="!notFound" :class="[prefixCls + '-dropdown-list']" ref="options"><slot></slot></ul>
31 </Drop> 31 </Drop>
32 </transition> 32 </transition>
@@ -37,14 +37,14 @@ @@ -37,14 +37,14 @@
37 import Drop from './dropdown.vue'; 37 import Drop from './dropdown.vue';
38 import clickoutside from '../../directives/clickoutside'; 38 import clickoutside from '../../directives/clickoutside';
39 import { oneOf, findComponentDownward } from '../../utils/assist'; 39 import { oneOf, findComponentDownward } from '../../utils/assist';
40 - import { t } from '../../locale';  
41 import Emitter from '../../mixins/emitter'; 40 import Emitter from '../../mixins/emitter';
  41 + import Locale from '../../mixins/locale';
42 42
43 const prefixCls = 'ivu-select'; 43 const prefixCls = 'ivu-select';
44 44
45 export default { 45 export default {
46 name: 'iSelect', 46 name: 'iSelect',
47 - mixins: [ Emitter ], 47 + mixins: [ Emitter, Locale ],
48 components: { Icon, Drop }, 48 components: { Icon, Drop },
49 directives: { clickoutside }, 49 directives: { clickoutside },
50 props: { 50 props: {
@@ -65,10 +65,7 @@ @@ -65,10 +65,7 @@
65 default: false 65 default: false
66 }, 66 },
67 placeholder: { 67 placeholder: {
68 - type: String,  
69 - default () {  
70 - return t('i.select.placeholder');  
71 - } 68 + type: String
72 }, 69 },
73 filterable: { 70 filterable: {
74 type: Boolean, 71 type: Boolean,
@@ -87,10 +84,7 @@ @@ -87,10 +84,7 @@
87 default: false 84 default: false
88 }, 85 },
89 notFoundText: { 86 notFoundText: {
90 - type: String,  
91 - default () {  
92 - return t('i.select.noMatch');  
93 - } 87 + type: String
94 } 88 }
95 }, 89 },
96 data () { 90 data () {
@@ -153,6 +147,20 @@ @@ -153,6 +147,20 @@
153 } 147 }
154 148
155 return style; 149 return style;
  150 + },
  151 + localePlaceholder () {
  152 + if (this.placeholder === undefined) {
  153 + return this.t('i.select.placeholder');
  154 + } else {
  155 + return this.placeholder;
  156 + }
  157 + },
  158 + localeNotFoundText () {
  159 + if (this.notFoundText === undefined) {
  160 + return this.t('i.select.noMatch');
  161 + } else {
  162 + return this.notFoundText;
  163 + }
156 } 164 }
157 }, 165 },
158 methods: { 166 methods: {
src/components/table/table.vue
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 :data="rebuildData"></table-head> 12 :data="rebuildData"></table-head>
13 </div> 13 </div>
14 <div :class="[prefixCls + '-body']" :style="bodyStyle" ref="body" @scroll="handleBodyScroll" 14 <div :class="[prefixCls + '-body']" :style="bodyStyle" ref="body" @scroll="handleBodyScroll"
15 - v-show="!((!!noDataText && (!data || data.length === 0)) || (!!noFilteredDataText && (!rebuildData || rebuildData.length === 0)))"> 15 + v-show="!((!!localeNoDataText && (!data || data.length === 0)) || (!!localeNoFilteredDataText && (!rebuildData || rebuildData.length === 0)))">
16 <table-body 16 <table-body
17 ref="tbody" 17 ref="tbody"
18 :prefix-cls="prefixCls" 18 :prefix-cls="prefixCls"
@@ -24,13 +24,13 @@ @@ -24,13 +24,13 @@
24 </div> 24 </div>
25 <div 25 <div
26 :class="[prefixCls + '-tip']" 26 :class="[prefixCls + '-tip']"
27 - v-show="((!!noDataText && (!data || data.length === 0)) || (!!noFilteredDataText && (!rebuildData || rebuildData.length === 0)))"> 27 + v-show="((!!localeNoDataText && (!data || data.length === 0)) || (!!localeNoFilteredDataText && (!rebuildData || rebuildData.length === 0)))">
28 <table cellspacing="0" cellpadding="0" border="0"> 28 <table cellspacing="0" cellpadding="0" border="0">
29 <tbody> 29 <tbody>
30 <tr> 30 <tr>
31 <td :style="{ 'height': bodyStyle.height }"> 31 <td :style="{ 'height': bodyStyle.height }">
32 - <span v-html="noDataText" v-if="!data || data.length === 0"></span>  
33 - <span v-html="noFilteredDataText" v-else></span> 32 + <span v-html="localeNoDataText" v-if="!data || data.length === 0"></span>
  33 + <span v-html="localeNoFilteredDataText" v-else></span>
34 </td> 34 </td>
35 </tr> 35 </tr>
36 </tbody> 36 </tbody>
@@ -88,13 +88,15 @@ @@ -88,13 +88,15 @@
88 import tableHead from './table-head.vue'; 88 import tableHead from './table-head.vue';
89 import tableBody from './table-body.vue'; 89 import tableBody from './table-body.vue';
90 import { oneOf, getStyle, deepCopy, getScrollBarSize } from '../../utils/assist'; 90 import { oneOf, getStyle, deepCopy, getScrollBarSize } from '../../utils/assist';
91 - import { t } from '../../locale';  
92 import Csv from '../../utils/csv'; 91 import Csv from '../../utils/csv';
93 import ExportCsv from './export-csv'; 92 import ExportCsv from './export-csv';
  93 + import Locale from '../../mixins/locale';
  94 +
94 const prefixCls = 'ivu-table'; 95 const prefixCls = 'ivu-table';
95 96
96 export default { 97 export default {
97 name: 'Table', 98 name: 'Table',
  99 + mixins: [ Locale ],
98 components: { tableHead, tableBody }, 100 components: { tableHead, tableBody },
99 props: { 101 props: {
100 data: { 102 data: {
@@ -146,16 +148,10 @@ @@ -146,16 +148,10 @@
146 type: Object 148 type: Object
147 }, 149 },
148 noDataText: { 150 noDataText: {
149 - type: String,  
150 - default () {  
151 - return t('i.table.noDataText');  
152 - } 151 + type: String
153 }, 152 },
154 noFilteredDataText: { 153 noFilteredDataText: {
155 - type: String,  
156 - default () {  
157 - return t('i.table.noFilteredDataText');  
158 - } 154 + type: String
159 } 155 }
160 }, 156 },
161 data () { 157 data () {
@@ -178,6 +174,20 @@ @@ -178,6 +174,20 @@
178 }; 174 };
179 }, 175 },
180 computed: { 176 computed: {
  177 + localeNoDataText () {
  178 + if (this.noDataText === undefined) {
  179 + return this.t('i.table.noDataText');
  180 + } else {
  181 + return this.noDataText;
  182 + }
  183 + },
  184 + localeNoFilteredDataText () {
  185 + if (this.noFilteredDataText === undefined) {
  186 + return this.t('i.table.noFilteredDataText');
  187 + } else {
  188 + return this.noFilteredDataText;
  189 + }
  190 + },
181 wrapClasses () { 191 wrapClasses () {
182 return [ 192 return [
183 `${prefixCls}-wrapper`, 193 `${prefixCls}-wrapper`,
src/components/transfer/transfer.vue
1 -<!-- <template>  
2 - <div :class="classes">  
3 - <List  
4 - ref="left"  
5 - :prefix-cls="prefixCls + '-list'"  
6 - :data="leftData"  
7 - :render-format="renderFormat"  
8 - :checked-keys="leftCheckedKeys"  
9 - @on-checked-keys-change="handleLeftCheckedKeysChange"  
10 - :valid-keys-count="leftValidKeysCount"  
11 - :style="listStyle"  
12 - :title="titles[0]"  
13 - :filterable="filterable"  
14 - :filter-placeholder="filterPlaceholder"  
15 - :filter-method="filterMethod"  
16 - :not-found-text="notFoundText">  
17 - <slot></slot>  
18 - </List>  
19 - <Operation  
20 - :prefix-cls="prefixCls"  
21 - :operations="operations"  
22 - :left-active="leftValidKeysCount > 0"  
23 - :right-active="rightValidKeysCount > 0">  
24 - </Operation>  
25 - <List  
26 - ref="right"  
27 - :prefix-cls="prefixCls + '-list'"  
28 - :data="rightData"  
29 - :render-format="renderFormat"  
30 - :checked-keys="rightCheckedKeys"  
31 - @on-checked-keys-change="handleRightCheckedKeysChange"  
32 - :valid-keys-count="rightValidKeysCount"  
33 - :style="listStyle"  
34 - :title="titles[1]"  
35 - :filterable="filterable"  
36 - :filter-placeholder="filterPlaceholder"  
37 - :filter-method="filterMethod"  
38 - :not-found-text="notFoundText">  
39 - <slot></slot>  
40 - </List>  
41 - </div>  
42 -</template> -->  
43 <script> 1 <script>
44 import List from './list.vue'; 2 import List from './list.vue';
45 import Operation from './operation.vue'; 3 import Operation from './operation.vue';
46 - import { t } from '../../locale'; 4 + import Locale from '../../mixins/locale';
47 import Emitter from '../../mixins/emitter'; 5 import Emitter from '../../mixins/emitter';
48 6
49 const prefixCls = 'ivu-transfer'; 7 const prefixCls = 'ivu-transfer';
50 8
51 export default { 9 export default {
52 - mixins: [ Emitter ], 10 + mixins: [ Emitter, Locale ],
53 render (createElement) { 11 render (createElement) {
54 12
55 function cloneVNode (vnode) { 13 function cloneVNode (vnode) {
@@ -82,11 +40,11 @@ @@ -82,11 +40,11 @@
82 checkedKeys: this.leftCheckedKeys, 40 checkedKeys: this.leftCheckedKeys,
83 validKeysCount: this.leftValidKeysCount, 41 validKeysCount: this.leftValidKeysCount,
84 style: this.listStyle, 42 style: this.listStyle,
85 - title: this.titles[0], 43 + title: this.localeTitles[0],
86 filterable: this.filterable, 44 filterable: this.filterable,
87 - filterPlaceholder: this.filterPlaceholder, 45 + filterPlaceholder: this.localeFilterPlaceholder,
88 filterMethod: this.filterMethod, 46 filterMethod: this.filterMethod,
89 - notFoundText: this.notFoundText 47 + notFoundText: this.localeNotFoundText
90 }, 48 },
91 on: { 49 on: {
92 'on-checked-keys-change': this.handleLeftCheckedKeysChange 50 'on-checked-keys-change': this.handleLeftCheckedKeysChange
@@ -111,11 +69,11 @@ @@ -111,11 +69,11 @@
111 checkedKeys: this.rightCheckedKeys, 69 checkedKeys: this.rightCheckedKeys,
112 validKeysCount: this.rightValidKeysCount, 70 validKeysCount: this.rightValidKeysCount,
113 style: this.listStyle, 71 style: this.listStyle,
114 - title: this.titles[1], 72 + title: this.localeTitles[1],
115 filterable: this.filterable, 73 filterable: this.filterable,
116 - filterPlaceholder: this.filterPlaceholder, 74 + filterPlaceholder: this.localeFilterPlaceholder,
117 filterMethod: this.filterMethod, 75 filterMethod: this.filterMethod,
118 - notFoundText: this.notFoundText 76 + notFoundText: this.localeNotFoundText
119 }, 77 },
120 on: { 78 on: {
121 'on-checked-keys-change': this.handleRightCheckedKeysChange 79 'on-checked-keys-change': this.handleRightCheckedKeysChange
@@ -157,10 +115,7 @@ @@ -157,10 +115,7 @@
157 } 115 }
158 }, 116 },
159 titles: { 117 titles: {
160 - type: Array,  
161 - default () {  
162 - return [t('i.transfer.titles.source'), t('i.transfer.titles.target')];  
163 - } 118 + type: Array
164 }, 119 },
165 operations: { 120 operations: {
166 type: Array, 121 type: Array,
@@ -173,10 +128,7 @@ @@ -173,10 +128,7 @@
173 default: false 128 default: false
174 }, 129 },
175 filterPlaceholder: { 130 filterPlaceholder: {
176 - type: String,  
177 - default () {  
178 - return t('i.transfer.filterPlaceholder');  
179 - } 131 + type: String
180 }, 132 },
181 filterMethod: { 133 filterMethod: {
182 type: Function, 134 type: Function,
@@ -186,10 +138,7 @@ @@ -186,10 +138,7 @@
186 } 138 }
187 }, 139 },
188 notFoundText: { 140 notFoundText: {
189 - type: String,  
190 - default () {  
191 - return t('i.transfer.notFoundText');  
192 - } 141 + type: String
193 } 142 }
194 }, 143 },
195 data () { 144 data () {
@@ -212,6 +161,27 @@ @@ -212,6 +161,27 @@
212 }, 161 },
213 rightValidKeysCount () { 162 rightValidKeysCount () {
214 return this.getValidKeys('right').length; 163 return this.getValidKeys('right').length;
  164 + },
  165 + localeFilterPlaceholder () {
  166 + if (this.filterPlaceholder === undefined) {
  167 + return this.t('i.transfer.filterPlaceholder');
  168 + } else {
  169 + return this.filterPlaceholder;
  170 + }
  171 + },
  172 + localeNotFoundText () {
  173 + if (this.notFoundText === undefined) {
  174 + return this.t('i.transfer.notFoundText');
  175 + } else {
  176 + return this.notFoundText;
  177 + }
  178 + },
  179 + localeTitles () {
  180 + if (this.titles === undefined) {
  181 + return [this.t('i.transfer.titles.source'), this.t('i.transfer.titles.target')];
  182 + } else {
  183 + return this.titles;
  184 + }
215 } 185 }
216 }, 186 },
217 methods: { 187 methods: {
src/components/tree/tree.vue
@@ -8,20 +8,20 @@ @@ -8,20 +8,20 @@
8 :multiple="multiple" 8 :multiple="multiple"
9 :show-checkbox="showCheckbox"> 9 :show-checkbox="showCheckbox">
10 </Tree-node> 10 </Tree-node>
11 - <div :class="[prefixCls + '-empty']" v-if="!data.length">{{ emptyText }}</div> 11 + <div :class="[prefixCls + '-empty']" v-if="!data.length">{{ localeEmptyText }}</div>
12 </div> 12 </div>
13 </template> 13 </template>
14 <script> 14 <script>
15 import TreeNode from './node.vue'; 15 import TreeNode from './node.vue';
16 import { findComponentsDownward } from '../../utils/assist'; 16 import { findComponentsDownward } from '../../utils/assist';
17 import Emitter from '../../mixins/emitter'; 17 import Emitter from '../../mixins/emitter';
18 - import { t } from '../../locale'; 18 + import Locale from '../../mixins/locale';
19 19
20 const prefixCls = 'ivu-tree'; 20 const prefixCls = 'ivu-tree';
21 21
22 export default { 22 export default {
23 name: 'Tree', 23 name: 'Tree',
24 - mixins: [ Emitter ], 24 + mixins: [ Emitter, Locale ],
25 components: { TreeNode }, 25 components: { TreeNode },
26 props: { 26 props: {
27 data: { 27 data: {
@@ -39,10 +39,7 @@ @@ -39,10 +39,7 @@
39 default: false 39 default: false
40 }, 40 },
41 emptyText: { 41 emptyText: {
42 - type: String,  
43 - default () {  
44 - return t('i.tree.emptyText');  
45 - } 42 + type: String
46 } 43 }
47 }, 44 },
48 data () { 45 data () {
@@ -50,6 +47,15 @@ @@ -50,6 +47,15 @@
50 prefixCls: prefixCls 47 prefixCls: prefixCls
51 }; 48 };
52 }, 49 },
  50 + computed: {
  51 + localeEmptyText () {
  52 + if (this.emptyText === undefined) {
  53 + return this.t('i.tree.emptyText');
  54 + } else {
  55 + return this.emptyText;
  56 + }
  57 + }
  58 + },
53 methods: { 59 methods: {
54 getSelectedNodes () { 60 getSelectedNodes () {
55 const nodes = findComponentsDownward(this, 'TreeNode'); 61 const nodes = findComponentsDownward(this, 'TreeNode');