| <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> |