<template> <div class="el-transfer"> <transfer-panel v-bind="$props" ref="leftPanel" :data="sourceData" :title="titles[0] || t('el.transfer.titles.0')" :default-checked="leftDefaultChecked" :placeholder="filterPlaceholder || t('el.transfer.filterPlaceholder')" @checked-change="onSourceCheckedChange"> <slot name="left-footer"></slot> </transfer-panel> <div class="el-transfer__buttons"> <el-button type="primary" :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']" @click.native="addToLeft" :disabled="rightChecked.length === 0"> <i class="el-icon-arrow-left"></i> <span v-if="buttonTexts[0] !== undefined">{{ buttonTexts[0] }}</span> </el-button> <el-button type="primary" :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']" @click.native="addToRight" :disabled="leftChecked.length === 0"> <span v-if="buttonTexts[1] !== undefined">{{ buttonTexts[1] }}</span> <i class="el-icon-arrow-right"></i> </el-button> </div> <transfer-panel v-bind="$props" ref="rightPanel" :data="targetData" :title="titles[1] || t('el.transfer.titles.1')" :default-checked="rightDefaultChecked" :placeholder="filterPlaceholder || t('el.transfer.filterPlaceholder')" @checked-change="onTargetCheckedChange"> <slot name="right-footer"></slot> </transfer-panel> </div> </template> <script> import ElButton from 'element-ui/packages/button'; import Emitter from 'element-ui/src/mixins/emitter'; import Locale from 'element-ui/src/mixins/locale'; import TransferPanel from './transfer-panel.vue'; import Migrating from 'element-ui/src/mixins/migrating'; export default { name: 'ElTransfer', mixins: [Emitter, Locale, Migrating], components: { TransferPanel, ElButton }, props: { data: { type: Array, default() { return []; } }, titles: { type: Array, default() { return []; } }, buttonTexts: { type: Array, default() { return []; } }, filterPlaceholder: { type: String, default: '' }, filterMethod: Function, leftDefaultChecked: { type: Array, default() { return []; } }, rightDefaultChecked: { type: Array, default() { return []; } }, renderContent: Function, value: { type: Array, default() { return []; } }, format: { type: Object, default() { return {}; } }, filterable: Boolean, props: { type: Object, default() { return { label: 'label', key: 'key', disabled: 'disabled' }; } }, targetOrder: { type: String, default: 'original' } }, data() { return { leftChecked: [], rightChecked: [] }; }, computed: { dataObj() { const key = this.props.key; return this.data.reduce((o, cur) => (o[cur[key]] = cur) && o, {}); }, sourceData() { return this.data.filter(item => this.value.indexOf(item[this.props.key]) === -1); }, targetData() { if (this.targetOrder === 'original') { return this.data.filter(item => this.value.indexOf(item[this.props.key]) > -1); } else { return this.value.reduce((arr, cur) => { const val = this.dataObj[cur]; if (val) { arr.push(val); } return arr; }, []); } }, hasButtonTexts() { return this.buttonTexts.length === 2; } }, watch: { value(val) { this.dispatch('ElFormItem', 'el.form.change', val); } }, methods: { getMigratingConfig() { return { props: { 'footer-format': 'footer-format is renamed to format.' } }; }, onSourceCheckedChange(val, movedKeys) { this.leftChecked = val; if (movedKeys === undefined) return; this.$emit('left-check-change', val, movedKeys); }, onTargetCheckedChange(val, movedKeys) { this.rightChecked = val; if (movedKeys === undefined) return; this.$emit('right-check-change', val, movedKeys); }, addToLeft() { let currentValue = this.value.slice(); this.rightChecked.forEach(item => { const index = currentValue.indexOf(item); if (index > -1) { currentValue.splice(index, 1); } }); this.$emit('input', currentValue); this.$emit('change', currentValue, 'left', this.rightChecked); }, addToRight() { let currentValue = this.value.slice(); const itemsToBeMoved = []; const key = this.props.key; this.data.forEach(item => { const itemKey = item[key]; if ( this.leftChecked.indexOf(itemKey) > -1 && this.value.indexOf(itemKey) === -1 ) { itemsToBeMoved.push(itemKey); } }); currentValue = this.targetOrder === 'unshift' ? itemsToBeMoved.concat(currentValue) : currentValue.concat(itemsToBeMoved); this.$emit('input', currentValue); this.$emit('change', currentValue, 'right', this.leftChecked); }, clearQuery(which) { if (which === 'left') { this.$refs.leftPanel.query = ''; } else if (which === 'right') { this.$refs.rightPanel.query = ''; } } } }; </script>