Commit e5337c810c3a25c0b448d7a6dcbff97d2a1faeae

Authored by 梁灏
1 parent ed91d9b0

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

examples/routers/modal.vue
1 1 <template>
2 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 6 </div>
18 7 </template>
19 8 <script>
20 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 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 3 import Icon from '../icon/icon.vue';
4 4 import iButton from '../button/button.vue';
5 5 import { camelcaseToHyphen } from '../../utils/assist';
6   -import { t } from '../../locale';
  6 +import Locale from '../../mixins/locale';
7 7  
8 8 const prefixCls = 'ivu-modal-confirm';
9 9  
... ... @@ -27,8 +27,8 @@ Modal.newInstance = properties =&gt; {
27 27 <div v-html="body"></div>
28 28 </div>
29 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 32 </div>
33 33 </div>
34 34 </Modal>
... ... @@ -37,6 +37,7 @@ Modal.newInstance = properties =&gt; {
37 37  
38 38 const modal = new Vue({
39 39 el: div,
  40 + mixins: [ Locale ],
40 41 components: { Modal, iButton, Icon },
41 42 data: Object.assign(_props, {
42 43 visible: false,
... ... @@ -45,8 +46,8 @@ Modal.newInstance = properties =&gt; {
45 46 body: '',
46 47 iconType: '',
47 48 iconName: '',
48   - okText: t('i.modal.okText'),
49   - cancelText: t('i.modal.cancelText'),
  49 + okText: undefined,
  50 + cancelText: undefined,
50 51 showCancel: false,
51 52 loading: false,
52 53 buttonLoading: false,
... ... @@ -64,6 +65,20 @@ Modal.newInstance = properties =&gt; {
64 65 'ivu-icon',
65 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 84 methods: {
... ...
src/components/modal/modal.vue
... ... @@ -16,8 +16,8 @@
16 16 <div :class="[prefixCls + '-body']"><slot></slot></div>
17 17 <div :class="[prefixCls + '-footer']" v-if="!footerHide">
18 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 21 </slot>
22 22 </div>
23 23 </div>
... ... @@ -30,11 +30,13 @@
30 30 import Icon from '../icon';
31 31 import iButton from '../button/button.vue';
32 32 import { getScrollBarSize } from '../../utils/assist';
33   - import { t } from '../../locale';
  33 + import Locale from '../../mixins/locale';
34 34  
35 35 const prefixCls = 'ivu-modal';
36 36  
37 37 export default {
  38 + name: 'Modal',
  39 + mixins: [ Locale ],
38 40 components: { Icon, iButton },
39 41 props: {
40 42 value: {
... ... @@ -57,16 +59,10 @@
57 59 default: 520
58 60 },
59 61 okText: {
60   - type: String,
61   - default () {
62   - return t('i.modal.okText');
63   - }
  62 + type: String
64 63 },
65 64 cancelText: {
66   - type: String,
67   - default () {
68   - return t('i.modal.cancelText');
69   - }
  65 + type: String
70 66 },
71 67 loading: {
72 68 type: Boolean,
... ... @@ -125,6 +121,20 @@
125 121 Object.assign(style, styleWidth, customStyle);
126 122  
127 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 140 methods: {
... ...
src/components/poptip/poptip.vue
... ... @@ -22,8 +22,8 @@
22 22 <div :class="[prefixCls + '-body-message']"><slot name="title">{{ title }}</slot></div>
23 23 </div>
24 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 27 </div>
28 28 </div>
29 29 <div :class="[prefixCls + '-inner']" v-if="!confirm">
... ... @@ -42,13 +42,13 @@
42 42 import iButton from '../button/button.vue';
43 43 import clickoutside from '../../directives/clickoutside';
44 44 import { oneOf } from '../../utils/assist';
45   - import { t } from '../../locale';
  45 + import Locale from '../../mixins/locale';
46 46  
47 47 const prefixCls = 'ivu-poptip';
48 48  
49 49 export default {
50 50 name: 'Poptip',
51   - mixins: [Popper],
  51 + mixins: [ Popper, Locale ],
52 52 directives: { clickoutside },
53 53 components: { iButton },
54 54 props: {
... ... @@ -79,16 +79,10 @@
79 79 default: false
80 80 },
81 81 okText: {
82   - type: String,
83   - default () {
84   - return t('i.poptip.okText');
85   - }
  82 + type: String
86 83 },
87 84 cancelText: {
88   - type: String,
89   - default () {
90   - return t('i.poptip.cancelText');
91   - }
  85 + type: String
92 86 }
93 87 },
94 88 data () {
... ... @@ -114,6 +108,20 @@
114 108 style.width = `${this.width}px`;
115 109 }
116 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 127 methods: {
... ...
src/components/select/select.vue
... ... @@ -8,14 +8,14 @@
8 8 <span class="ivu-tag-text">{{ item.label }}</span>
9 9 <Icon type="ios-close-empty" @click.native.stop="removeTag(index)"></Icon>
10 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 12 <span :class="[prefixCls + '-selected-value']" v-show="!showPlaceholder && !multiple && !filterable">{{ selectedSingle }}</span>
13 13 <input
14 14 type="text"
15 15 v-if="filterable"
16 16 v-model="query"
17 17 :class="[prefixCls + '-input']"
18   - :placeholder="showPlaceholder ? placeholder : ''"
  18 + :placeholder="showPlaceholder ? localePlaceholder : ''"
19 19 :style="inputStyle"
20 20 @blur="handleBlur"
21 21 @keydown="resetInputState"
... ... @@ -26,7 +26,7 @@
26 26 </div>
27 27 <transition name="slide-up">
28 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 30 <ul v-show="!notFound" :class="[prefixCls + '-dropdown-list']" ref="options"><slot></slot></ul>
31 31 </Drop>
32 32 </transition>
... ... @@ -37,14 +37,14 @@
37 37 import Drop from './dropdown.vue';
38 38 import clickoutside from '../../directives/clickoutside';
39 39 import { oneOf, findComponentDownward } from '../../utils/assist';
40   - import { t } from '../../locale';
41 40 import Emitter from '../../mixins/emitter';
  41 + import Locale from '../../mixins/locale';
42 42  
43 43 const prefixCls = 'ivu-select';
44 44  
45 45 export default {
46 46 name: 'iSelect',
47   - mixins: [ Emitter ],
  47 + mixins: [ Emitter, Locale ],
48 48 components: { Icon, Drop },
49 49 directives: { clickoutside },
50 50 props: {
... ... @@ -65,10 +65,7 @@
65 65 default: false
66 66 },
67 67 placeholder: {
68   - type: String,
69   - default () {
70   - return t('i.select.placeholder');
71   - }
  68 + type: String
72 69 },
73 70 filterable: {
74 71 type: Boolean,
... ... @@ -87,10 +84,7 @@
87 84 default: false
88 85 },
89 86 notFoundText: {
90   - type: String,
91   - default () {
92   - return t('i.select.noMatch');
93   - }
  87 + type: String
94 88 }
95 89 },
96 90 data () {
... ... @@ -153,6 +147,20 @@
153 147 }
154 148  
155 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 166 methods: {
... ...
src/components/table/table.vue
... ... @@ -12,7 +12,7 @@
12 12 :data="rebuildData"></table-head>
13 13 </div>
14 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 16 <table-body
17 17 ref="tbody"
18 18 :prefix-cls="prefixCls"
... ... @@ -24,13 +24,13 @@
24 24 </div>
25 25 <div
26 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 28 <table cellspacing="0" cellpadding="0" border="0">
29 29 <tbody>
30 30 <tr>
31 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 34 </td>
35 35 </tr>
36 36 </tbody>
... ... @@ -88,13 +88,15 @@
88 88 import tableHead from './table-head.vue';
89 89 import tableBody from './table-body.vue';
90 90 import { oneOf, getStyle, deepCopy, getScrollBarSize } from '../../utils/assist';
91   - import { t } from '../../locale';
92 91 import Csv from '../../utils/csv';
93 92 import ExportCsv from './export-csv';
  93 + import Locale from '../../mixins/locale';
  94 +
94 95 const prefixCls = 'ivu-table';
95 96  
96 97 export default {
97 98 name: 'Table',
  99 + mixins: [ Locale ],
98 100 components: { tableHead, tableBody },
99 101 props: {
100 102 data: {
... ... @@ -146,16 +148,10 @@
146 148 type: Object
147 149 },
148 150 noDataText: {
149   - type: String,
150   - default () {
151   - return t('i.table.noDataText');
152   - }
  151 + type: String
153 152 },
154 153 noFilteredDataText: {
155   - type: String,
156   - default () {
157   - return t('i.table.noFilteredDataText');
158   - }
  154 + type: String
159 155 }
160 156 },
161 157 data () {
... ... @@ -178,6 +174,20 @@
178 174 };
179 175 },
180 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 191 wrapClasses () {
182 192 return [
183 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 1 <script>
44 2 import List from './list.vue';
45 3 import Operation from './operation.vue';
46   - import { t } from '../../locale';
  4 + import Locale from '../../mixins/locale';
47 5 import Emitter from '../../mixins/emitter';
48 6  
49 7 const prefixCls = 'ivu-transfer';
50 8  
51 9 export default {
52   - mixins: [ Emitter ],
  10 + mixins: [ Emitter, Locale ],
53 11 render (createElement) {
54 12  
55 13 function cloneVNode (vnode) {
... ... @@ -82,11 +40,11 @@
82 40 checkedKeys: this.leftCheckedKeys,
83 41 validKeysCount: this.leftValidKeysCount,
84 42 style: this.listStyle,
85   - title: this.titles[0],
  43 + title: this.localeTitles[0],
86 44 filterable: this.filterable,
87   - filterPlaceholder: this.filterPlaceholder,
  45 + filterPlaceholder: this.localeFilterPlaceholder,
88 46 filterMethod: this.filterMethod,
89   - notFoundText: this.notFoundText
  47 + notFoundText: this.localeNotFoundText
90 48 },
91 49 on: {
92 50 'on-checked-keys-change': this.handleLeftCheckedKeysChange
... ... @@ -111,11 +69,11 @@
111 69 checkedKeys: this.rightCheckedKeys,
112 70 validKeysCount: this.rightValidKeysCount,
113 71 style: this.listStyle,
114   - title: this.titles[1],
  72 + title: this.localeTitles[1],
115 73 filterable: this.filterable,
116   - filterPlaceholder: this.filterPlaceholder,
  74 + filterPlaceholder: this.localeFilterPlaceholder,
117 75 filterMethod: this.filterMethod,
118   - notFoundText: this.notFoundText
  76 + notFoundText: this.localeNotFoundText
119 77 },
120 78 on: {
121 79 'on-checked-keys-change': this.handleRightCheckedKeysChange
... ... @@ -157,10 +115,7 @@
157 115 }
158 116 },
159 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 120 operations: {
166 121 type: Array,
... ... @@ -173,10 +128,7 @@
173 128 default: false
174 129 },
175 130 filterPlaceholder: {
176   - type: String,
177   - default () {
178   - return t('i.transfer.filterPlaceholder');
179   - }
  131 + type: String
180 132 },
181 133 filterMethod: {
182 134 type: Function,
... ... @@ -186,10 +138,7 @@
186 138 }
187 139 },
188 140 notFoundText: {
189   - type: String,
190   - default () {
191   - return t('i.transfer.notFoundText');
192   - }
  141 + type: String
193 142 }
194 143 },
195 144 data () {
... ... @@ -212,6 +161,27 @@
212 161 },
213 162 rightValidKeysCount () {
214 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 187 methods: {
... ...
src/components/tree/tree.vue
... ... @@ -8,20 +8,20 @@
8 8 :multiple="multiple"
9 9 :show-checkbox="showCheckbox">
10 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 12 </div>
13 13 </template>
14 14 <script>
15 15 import TreeNode from './node.vue';
16 16 import { findComponentsDownward } from '../../utils/assist';
17 17 import Emitter from '../../mixins/emitter';
18   - import { t } from '../../locale';
  18 + import Locale from '../../mixins/locale';
19 19  
20 20 const prefixCls = 'ivu-tree';
21 21  
22 22 export default {
23 23 name: 'Tree',
24   - mixins: [ Emitter ],
  24 + mixins: [ Emitter, Locale ],
25 25 components: { TreeNode },
26 26 props: {
27 27 data: {
... ... @@ -39,10 +39,7 @@
39 39 default: false
40 40 },
41 41 emptyText: {
42   - type: String,
43   - default () {
44   - return t('i.tree.emptyText');
45   - }
  42 + type: String
46 43 }
47 44 },
48 45 data () {
... ... @@ -50,6 +47,15 @@
50 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 59 methods: {
54 60 getSelectedNodes () {
55 61 const nodes = findComponentsDownward(this, 'TreeNode');
... ...