// Utils import { createNamespace } from '../utils'; import { preventDefault } from '../utils/dom/event'; import { BORDER_TOP_BOTTOM, BORDER_UNSET_TOP_BOTTOM } from '../utils/constant'; import { pickerProps } from './shared'; // Components import Loading from '../loading'; import PickerColumn from './PickerColumn'; const [createComponent, bem, t] = createNamespace('picker'); export default createComponent({ props: { ...pickerProps, defaultIndex: { type: [Number, String], default: 0, }, columns: { type: Array, default: () => [], }, toolbarPosition: { type: String, default: 'top', }, valueKey: { type: String, default: 'text', }, }, data() { return { children: [], formattedColumns: [], }; }, computed: { dataType() { const { columns } = this; const firstColumn = columns[0] || {}; if (firstColumn.children) { return 'cascade'; } if (firstColumn.values) { return 'object'; } return 'text'; }, }, watch: { columns: { handler: 'format', immediate: true, }, }, methods: { format() { const { columns, dataType } = this; if (dataType === 'text') { this.formattedColumns = [{ values: columns }]; } else if (dataType === 'cascade') { this.formatCascade(); } else { this.formattedColumns = columns; } }, formatCascade() { const formatted = []; let cursor = { children: this.columns }; while (cursor && cursor.children) { const defaultIndex = cursor.defaultIndex || +this.defaultIndex; formatted.push({ values: cursor.children.map((item) => item[this.valueKey]), className: cursor.className, defaultIndex, }); cursor = cursor.children[defaultIndex]; } this.formattedColumns = formatted; }, emit(event) { if (this.dataType === 'text') { this.$emit(event, this.getColumnValue(0), this.getColumnIndex(0)); } else { this.$emit(event, this.getValues(), this.getIndexes()); } }, onCascadeChange(columnIndex) { let cursor = { children: this.columns }; const indexes = this.getIndexes(); for (let i = 0; i <= columnIndex; i++) { cursor = cursor.children[indexes[i]]; } while (cursor.children) { columnIndex++; this.setColumnValues( columnIndex, cursor.children.map((item) => item[this.valueKey]) ); cursor = cursor.children[cursor.defaultIndex || 0]; } }, onChange(columnIndex) { if (this.dataType === 'cascade') { this.onCascadeChange(columnIndex); } if (this.dataType === 'text') { this.$emit( 'change', this, this.getColumnValue(0), this.getColumnIndex(0) ); } else { this.$emit('change', this, this.getValues(), columnIndex); } }, // get column instance by index getColumn(index) { return this.children[index]; }, // @exposed-api // get column value by index getColumnValue(index) { const column = this.getColumn(index); return column && column.getValue(); }, // @exposed-api // set column value by index setColumnValue(index, value) { const column = this.getColumn(index); if (column) { column.setValue(value); if (this.dataType === 'cascade') { this.onCascadeChange(index); } } }, // @exposed-api // get column option index by column index getColumnIndex(columnIndex) { return (this.getColumn(columnIndex) || {}).currentIndex; }, // @exposed-api // set column option index by column index setColumnIndex(columnIndex, optionIndex) { const column = this.getColumn(columnIndex); if (column) { column.setIndex(optionIndex); if (this.dataType === 'cascade') { this.onCascadeChange(columnIndex); } } }, // @exposed-api // get options of column by index getColumnValues(index) { return (this.children[index] || {}).options; }, // @exposed-api // set options of column by index setColumnValues(index, options) { const column = this.children[index]; if (column) { column.setOptions(options); } }, // @exposed-api // get values of all columns getValues() { return this.children.map((child) => child.getValue()); }, // @exposed-api // set values of all columns setValues(values) { values.forEach((value, index) => { this.setColumnValue(index, value); }); }, // @exposed-api // get indexes of all columns getIndexes() { return this.children.map((child) => child.currentIndex); }, // @exposed-api // set indexes of all columns setIndexes(indexes) { indexes.forEach((optionIndex, columnIndex) => { this.setColumnIndex(columnIndex, optionIndex); }); }, // @exposed-api confirm() { this.children.forEach((child) => child.stopMomentum()); this.emit('confirm'); }, cancel() { this.emit('cancel'); }, genTitle() { const titleSlot = this.slots('title'); if (titleSlot) { return titleSlot; } if (this.title) { return