f5276519993fa22f10fb217f92e3c98ddea4006943cca0d8e137a42ba21266df1b567bb368e1ded201de58614065ff2fafc34c361700fe60ac3ef8fb1f76d8 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <template>
  2. <div class="el-transfer">
  3. <transfer-panel
  4. v-bind="$props"
  5. ref="leftPanel"
  6. :data="sourceData"
  7. :title="titles[0] || t('el.transfer.titles.0')"
  8. :default-checked="leftDefaultChecked"
  9. :placeholder="filterPlaceholder || t('el.transfer.filterPlaceholder')"
  10. @checked-change="onSourceCheckedChange">
  11. <slot name="left-footer"></slot>
  12. </transfer-panel>
  13. <div class="el-transfer__buttons">
  14. <el-button
  15. type="primary"
  16. :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
  17. @click.native="addToLeft"
  18. :disabled="rightChecked.length === 0">
  19. <i class="el-icon-arrow-left"></i>
  20. <span v-if="buttonTexts[0] !== undefined">{{ buttonTexts[0] }}</span>
  21. </el-button>
  22. <el-button
  23. type="primary"
  24. :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
  25. @click.native="addToRight"
  26. :disabled="leftChecked.length === 0">
  27. <span v-if="buttonTexts[1] !== undefined">{{ buttonTexts[1] }}</span>
  28. <i class="el-icon-arrow-right"></i>
  29. </el-button>
  30. </div>
  31. <transfer-panel
  32. v-bind="$props"
  33. ref="rightPanel"
  34. :data="targetData"
  35. :title="titles[1] || t('el.transfer.titles.1')"
  36. :default-checked="rightDefaultChecked"
  37. :placeholder="filterPlaceholder || t('el.transfer.filterPlaceholder')"
  38. @checked-change="onTargetCheckedChange">
  39. <slot name="right-footer"></slot>
  40. </transfer-panel>
  41. </div>
  42. </template>
  43. <script>
  44. import ElButton from 'element-ui/packages/button';
  45. import Emitter from 'element-ui/src/mixins/emitter';
  46. import Locale from 'element-ui/src/mixins/locale';
  47. import TransferPanel from './transfer-panel.vue';
  48. import Migrating from 'element-ui/src/mixins/migrating';
  49. export default {
  50. name: 'ElTransfer',
  51. mixins: [Emitter, Locale, Migrating],
  52. components: {
  53. TransferPanel,
  54. ElButton
  55. },
  56. props: {
  57. data: {
  58. type: Array,
  59. default() {
  60. return [];
  61. }
  62. },
  63. titles: {
  64. type: Array,
  65. default() {
  66. return [];
  67. }
  68. },
  69. buttonTexts: {
  70. type: Array,
  71. default() {
  72. return [];
  73. }
  74. },
  75. filterPlaceholder: {
  76. type: String,
  77. default: ''
  78. },
  79. filterMethod: Function,
  80. leftDefaultChecked: {
  81. type: Array,
  82. default() {
  83. return [];
  84. }
  85. },
  86. rightDefaultChecked: {
  87. type: Array,
  88. default() {
  89. return [];
  90. }
  91. },
  92. renderContent: Function,
  93. value: {
  94. type: Array,
  95. default() {
  96. return [];
  97. }
  98. },
  99. format: {
  100. type: Object,
  101. default() {
  102. return {};
  103. }
  104. },
  105. filterable: Boolean,
  106. props: {
  107. type: Object,
  108. default() {
  109. return {
  110. label: 'label',
  111. key: 'key',
  112. disabled: 'disabled'
  113. };
  114. }
  115. },
  116. targetOrder: {
  117. type: String,
  118. default: 'original'
  119. }
  120. },
  121. data() {
  122. return {
  123. leftChecked: [],
  124. rightChecked: []
  125. };
  126. },
  127. computed: {
  128. dataObj() {
  129. const key = this.props.key;
  130. return this.data.reduce((o, cur) => (o[cur[key]] = cur) && o, {});
  131. },
  132. sourceData() {
  133. return this.data.filter(item => this.value.indexOf(item[this.props.key]) === -1);
  134. },
  135. targetData() {
  136. if (this.targetOrder === 'original') {
  137. return this.data.filter(item => this.value.indexOf(item[this.props.key]) > -1);
  138. } else {
  139. return this.value.reduce((arr, cur) => {
  140. const val = this.dataObj[cur];
  141. if (val) {
  142. arr.push(val);
  143. }
  144. return arr;
  145. }, []);
  146. }
  147. },
  148. hasButtonTexts() {
  149. return this.buttonTexts.length === 2;
  150. }
  151. },
  152. watch: {
  153. value(val) {
  154. this.dispatch('ElFormItem', 'el.form.change', val);
  155. }
  156. },
  157. methods: {
  158. getMigratingConfig() {
  159. return {
  160. props: {
  161. 'footer-format': 'footer-format is renamed to format.'
  162. }
  163. };
  164. },
  165. onSourceCheckedChange(val, movedKeys) {
  166. this.leftChecked = val;
  167. if (movedKeys === undefined) return;
  168. this.$emit('left-check-change', val, movedKeys);
  169. },
  170. onTargetCheckedChange(val, movedKeys) {
  171. this.rightChecked = val;
  172. if (movedKeys === undefined) return;
  173. this.$emit('right-check-change', val, movedKeys);
  174. },
  175. addToLeft() {
  176. let currentValue = this.value.slice();
  177. this.rightChecked.forEach(item => {
  178. const index = currentValue.indexOf(item);
  179. if (index > -1) {
  180. currentValue.splice(index, 1);
  181. }
  182. });
  183. this.$emit('input', currentValue);
  184. this.$emit('change', currentValue, 'left', this.rightChecked);
  185. },
  186. addToRight() {
  187. let currentValue = this.value.slice();
  188. const itemsToBeMoved = [];
  189. const key = this.props.key;
  190. this.data.forEach(item => {
  191. const itemKey = item[key];
  192. if (
  193. this.leftChecked.indexOf(itemKey) > -1 &&
  194. this.value.indexOf(itemKey) === -1
  195. ) {
  196. itemsToBeMoved.push(itemKey);
  197. }
  198. });
  199. currentValue = this.targetOrder === 'unshift'
  200. ? itemsToBeMoved.concat(currentValue)
  201. : currentValue.concat(itemsToBeMoved);
  202. this.$emit('input', currentValue);
  203. this.$emit('change', currentValue, 'right', this.leftChecked);
  204. },
  205. clearQuery(which) {
  206. if (which === 'left') {
  207. this.$refs.leftPanel.query = '';
  208. } else if (which === 'right') {
  209. this.$refs.rightPanel.query = '';
  210. }
  211. }
  212. }
  213. };
  214. </script>