|
@@ -1,228 +0,0 @@
|
|
|
-<template>
|
|
|
- <div class="el-transfer-panel">
|
|
|
- <p class="el-transfer-panel__header">
|
|
|
- <el-checkbox v-model="allChecked" @change="handleAllCheckedChange" :indeterminate="isIndeterminate">
|
|
|
- {{ title }}
|
|
|
- <span>{{ checkedSummary }}</span>
|
|
|
- </el-checkbox>
|
|
|
- </p>
|
|
|
-
|
|
|
- <div :class="['el-transfer-panel__body', hasFooter ? 'is-with-footer' : '']">
|
|
|
- <el-input class="el-transfer-panel__filter" v-model="query" size="small" :placeholder="placeholder"
|
|
|
- @mouseenter.native="inputHover = true" @mouseleave.native="inputHover = false" v-if="filterable">
|
|
|
- <i slot="prefix" :class="['el-input__icon', 'el-icon-' + inputIcon]" @click="clearQuery"></i>
|
|
|
- </el-input>
|
|
|
- <el-checkbox-group v-model="checked" v-show="!hasNoMatch && data.length > 0"
|
|
|
- :class="{ 'is-filterable': filterable }" class="el-transfer-panel__list">
|
|
|
- <el-checkbox class="el-transfer-panel__item" :label="item[keyProp]" :disabled="item[disabledProp]"
|
|
|
- :key="item[keyProp]" v-for="item in filteredData">
|
|
|
- <option-content :option="item"></option-content>
|
|
|
- </el-checkbox>
|
|
|
- </el-checkbox-group>
|
|
|
- <p class="el-transfer-panel__empty" v-show="hasNoMatch">{{ t('el.transfer.noMatch') }}</p>
|
|
|
- <p class="el-transfer-panel__empty" v-show="data.length === 0 && !hasNoMatch">{{ t('el.transfer.noData') }}</p>
|
|
|
- </div>
|
|
|
- <p class="el-transfer-panel__footer" v-if="hasFooter">
|
|
|
- <slot></slot>
|
|
|
- </p>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script>
|
|
|
-import ElCheckboxGroup from 'element-ui/packages/checkbox-group';
|
|
|
-import ElCheckbox from 'element-ui/packages/checkbox';
|
|
|
-import ElInput from 'element-ui/packages/input';
|
|
|
-import Locale from 'element-ui/src/mixins/locale';
|
|
|
-
|
|
|
-export default {
|
|
|
- mixins: [Locale],
|
|
|
-
|
|
|
- name: 'ElTransferPanel',
|
|
|
-
|
|
|
- componentName: 'ElTransferPanel',
|
|
|
-
|
|
|
- components: {
|
|
|
- ElCheckboxGroup,
|
|
|
- ElCheckbox,
|
|
|
- ElInput,
|
|
|
- OptionContent: {
|
|
|
- props: {
|
|
|
- option: Object
|
|
|
- },
|
|
|
- render(h) {
|
|
|
- const getParent = vm => {
|
|
|
- if (vm.$options.componentName === 'ElTransferPanel') {
|
|
|
- return vm;
|
|
|
- } else if (vm.$parent) {
|
|
|
- return getParent(vm.$parent);
|
|
|
- } else {
|
|
|
- return vm;
|
|
|
- }
|
|
|
- };
|
|
|
- const panel = getParent(this);
|
|
|
- const transfer = panel.$parent || panel;
|
|
|
- return panel.renderContent
|
|
|
- ? panel.renderContent(h, this.option)
|
|
|
- : transfer.$scopedSlots.default
|
|
|
- ? transfer.$scopedSlots.default({ option: this.option })
|
|
|
- : <span>{this.option[panel.labelProp] || this.option[panel.keyProp]}</span>;
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- props: {
|
|
|
- data: {
|
|
|
- type: Array,
|
|
|
- default() {
|
|
|
- return [];
|
|
|
- }
|
|
|
- },
|
|
|
- renderContent: Function,
|
|
|
- placeholder: String,
|
|
|
- title: String,
|
|
|
- filterable: Boolean,
|
|
|
- format: Object,
|
|
|
- filterMethod: Function,
|
|
|
- defaultChecked: Array,
|
|
|
- props: Object
|
|
|
- },
|
|
|
-
|
|
|
- data() {
|
|
|
- return {
|
|
|
- checked: [],
|
|
|
- allChecked: false,
|
|
|
- query: '',
|
|
|
- inputHover: false,
|
|
|
- checkChangeByUser: true
|
|
|
- };
|
|
|
- },
|
|
|
-
|
|
|
- watch: {
|
|
|
- checked(val, oldVal) {
|
|
|
- this.updateAllChecked();
|
|
|
- if (this.checkChangeByUser) {
|
|
|
- const movedKeys = val.concat(oldVal)
|
|
|
- .filter(v => val.indexOf(v) === -1 || oldVal.indexOf(v) === -1);
|
|
|
- this.$emit('checked-change', val, movedKeys);
|
|
|
- } else {
|
|
|
- this.$emit('checked-change', val);
|
|
|
- this.checkChangeByUser = true;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- data() {
|
|
|
- const checked = [];
|
|
|
- const filteredDataKeys = this.filteredData.map(item => item[this.keyProp]);
|
|
|
- this.checked.forEach(item => {
|
|
|
- if (filteredDataKeys.indexOf(item) > -1) {
|
|
|
- checked.push(item);
|
|
|
- }
|
|
|
- });
|
|
|
- this.checkChangeByUser = false;
|
|
|
- this.checked = checked;
|
|
|
- },
|
|
|
-
|
|
|
- checkableData() {
|
|
|
- this.updateAllChecked();
|
|
|
- },
|
|
|
-
|
|
|
- defaultChecked: {
|
|
|
- immediate: true,
|
|
|
- handler(val, oldVal) {
|
|
|
- if (oldVal && val.length === oldVal.length &&
|
|
|
- val.every(item => oldVal.indexOf(item) > -1)) return;
|
|
|
- const checked = [];
|
|
|
- const checkableDataKeys = this.checkableData.map(item => item[this.keyProp]);
|
|
|
- val.forEach(item => {
|
|
|
- if (checkableDataKeys.indexOf(item) > -1) {
|
|
|
- checked.push(item);
|
|
|
- }
|
|
|
- });
|
|
|
- this.checkChangeByUser = false;
|
|
|
- this.checked = checked;
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- computed: {
|
|
|
- filteredData() {
|
|
|
- return this.data.filter(item => {
|
|
|
- if (typeof this.filterMethod === 'function') {
|
|
|
- return this.filterMethod(this.query, item);
|
|
|
- } else {
|
|
|
- const label = item[this.labelProp] || item[this.keyProp].toString();
|
|
|
- return label.toLowerCase().indexOf(this.query.toLowerCase()) > -1;
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- checkableData() {
|
|
|
- return this.filteredData.filter(item => !item[this.disabledProp]);
|
|
|
- },
|
|
|
-
|
|
|
- checkedSummary() {
|
|
|
- const checkedLength = this.checked.length;
|
|
|
- const dataLength = this.data.length;
|
|
|
- const { noChecked, hasChecked } = this.format;
|
|
|
- if (noChecked && hasChecked) {
|
|
|
- return checkedLength > 0
|
|
|
- ? hasChecked.replace(/\${checked}/g, checkedLength).replace(/\${total}/g, dataLength)
|
|
|
- : noChecked.replace(/\${total}/g, dataLength);
|
|
|
- } else {
|
|
|
- return `${checkedLength}/${dataLength}`;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- isIndeterminate() {
|
|
|
- const checkedLength = this.checked.length;
|
|
|
- return checkedLength > 0 && checkedLength < this.checkableData.length;
|
|
|
- },
|
|
|
-
|
|
|
- hasNoMatch() {
|
|
|
- return this.query.length > 0 && this.filteredData.length === 0;
|
|
|
- },
|
|
|
-
|
|
|
- inputIcon() {
|
|
|
- return this.query.length > 0 && this.inputHover
|
|
|
- ? 'circle-close'
|
|
|
- : 'search';
|
|
|
- },
|
|
|
-
|
|
|
- labelProp() {
|
|
|
- return this.props.label || 'label';
|
|
|
- },
|
|
|
-
|
|
|
- keyProp() {
|
|
|
- return this.props.key || 'key';
|
|
|
- },
|
|
|
-
|
|
|
- disabledProp() {
|
|
|
- return this.props.disabled || 'disabled';
|
|
|
- },
|
|
|
-
|
|
|
- hasFooter() {
|
|
|
- return !!this.$slots.default;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- methods: {
|
|
|
- updateAllChecked() {
|
|
|
- const checkableDataKeys = this.checkableData.map(item => item[this.keyProp]);
|
|
|
- this.allChecked = checkableDataKeys.length > 0 &&
|
|
|
- checkableDataKeys.every(item => this.checked.indexOf(item) > -1);
|
|
|
- },
|
|
|
-
|
|
|
- handleAllCheckedChange(value) {
|
|
|
- this.checked = value
|
|
|
- ? this.checkableData.map(item => item[this.keyProp])
|
|
|
- : [];
|
|
|
- },
|
|
|
-
|
|
|
- clearQuery() {
|
|
|
- if (this.inputIcon === 'circle-close') {
|
|
|
- this.query = '';
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-</script>
|