Commit e5337c810c3a25c0b448d7a6dcbff97d2a1faeae
1 parent
ed91d9b0
fixed some components bug that can not translate when using vue-i18n
Showing
8 changed files
with
185 additions
and
153 deletions
Show diff stats
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 './modal.vue'; |
| 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 => { |
| 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 => { |
| 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 => { |
| 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 => { |
| 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'); | ... | ... |