UNPKG

@qymh/vue-q-select

Version:

一个高性能的vue移动端下拉选择插件

416 lines (384 loc) 8.04 kB
import { ref, onMounted, onBeforeUnmount, watch, createComponent } from '@vue/composition-api'; import QSelect from '@qymh/q-select'; import { VueSlash } from '../index'; import { assert } from '@qymh/q-select/src/uitls'; interface IProps { visible: boolean; data: Data; index: number[]; title: string; count: number; chunkHeight: number; confirmBtn: string; cancelBtn: string; inline: boolean; loading: boolean; deep: boolean; disableDefaultCancel: boolean; defaultKey: any[]; defaultValue: any[]; bkIndex: number; selectIndex: number; } const Component = createComponent({ setup(props: IProps, context) { const pending = ref(true); const uid = ref(0); let ins: QSelect; onMounted(() => { ins = new QSelect({ data: props.data, index: props.index, target: props.inline ? `.q-select-inline--${uid.value}` : '', count: props.count, title: props.title, chunkHeight: props.chunkHeight, cancelBtn: props.cancelBtn, confirmBtn: props.confirmBtn, loading: props.loading, disableDefaultCancel: props.disableDefaultCancel, bkIndex: props.bkIndex, selectIndex: props.selectIndex, ready(value, key, data) { pending.value = false; context.emit('ready', value, key, data); }, cancel() { context.emit('input', false); context.emit('cancel'); }, confirm(value, key, data) { context.emit('input', false); context.emit('confirm', value, key, data); }, change(weight, value, key, data) { context.emit('change', weight, value, key, data); }, show() { context.emit('show'); }, hide() {} }); }); onBeforeUnmount(() => { ins && ins.destroy(); }); const warnIns = () => { if (!ins) { return assert(false, 'You should new QSelect before you use it'); } else { return true; } }; const show = () => { if (warnIns()) { context.emit('input', true); return ins.show(); } }; const close = () => { if (warnIns()) { context.emit('input', false); return ins.close(); } }; const destroy = () => { if (warnIns()) { return ins.destroy(); } }; const setData = (data: Data, index?: number[]) => { if (warnIns()) { return ins.setData(data, index); } return ''; }; const setColumnData = ( column: number | number[], data: NotGangedData | NotGangedData[] ) => { if (warnIns()) { return ins.setColumnData(column, data); } return ''; }; const scrollTo = (column: number, index: number) => { if (warnIns()) { return ins.scrollTo(column, index); } return ''; }; const setIndex = (index: number[]) => { if (warnIns()) { return ins.setIndex(index); } return ''; }; const setTitle = (title: string) => { if (warnIns()) { return ins.setTitle(title); } }; const setValue = (value: any[]) => { if (warnIns()) { return ins.setValue(value); } return ''; }; const setKey = (key: any[]) => { if (warnIns()) { return ins.setKey(key); } return ''; }; const getData = () => { if (warnIns()) { return ins.getData(); } return []; }; const getIndex = () => { if (warnIns()) { return ins.getIndex(); } return []; }; const getValue = () => { if (warnIns()) { return ins.getValue(); } return []; }; const getKey = () => { if (warnIns()) { return ins.getKey(); } return []; }; const setLoading = () => { if (warnIns()) { return ins.setLoading(); } }; const cancelLoading = () => { if (warnIns()) { return ins.cancelLoading(); } }; watch( () => props.defaultKey, val => { if (val && val.length) { if (pending.value) { VueSlash.nextTick(() => { ins.setKey(props.defaultKey); }); } else { ins.setKey(props.defaultKey); } } } ); watch( () => props.defaultValue, val => { if (val && val.length) { if (pending.value) { VueSlash.nextTick(() => { ins.setValue(props.defaultValue); }); } else { ins.setValue(props.defaultValue); } } } ); watch( () => props.visible, val => { if (val) { if (pending.value) { VueSlash.nextTick(() => { show(); }); } else { show(); } } else { if (!pending.value) { context.emit('hide'); close(); } } } ); watch( () => props.loading, val => { if (val) { if (pending.value) { } else { setLoading(); } } else { if (!pending.value) { cancelLoading(); } } } ); watch( () => props.data, (val: Data) => { setData(val); if (props.defaultValue && props.defaultValue.length) { setValue(props.defaultValue); } if (props.defaultKey && props.defaultKey.length) { setKey(props.defaultKey); } if (props.index && props.index.length) { setIndex(props.index); } }, { lazy: true, deep: props.deep } ); watch( () => props.index, val => { setIndex(val); }, { lazy: true } ); watch( () => props.title, val => { setTitle(val); }, { lazy: true } ); return { uid, destroy, setIndex, setData, setColumnData, scrollTo, setValue, setKey, setTitle, getData, getIndex, getValue, getKey }; }, name: 'QSelect', model: { prop: 'visible' }, props: { // 是否显示 visible: { type: Boolean, default: false }, // data值 data: { type: Array, default: () => [['']] }, // 索引 index: { type: Array, default: () => [] }, // 标题 title: { type: String, default: '请选择' }, // 展示多少个 count: { type: Number, default: 7 }, // 一个块的高度 chunkHeight: { type: Number, default: 40 }, // 确定按钮 confirmBtn: { type: String, default: '确定' }, // 取消按钮 cancelBtn: { type: String, default: '取消' }, // 是否内联展示 inline: { type: Boolean, default: false }, // 是否异步加载 loading: { type: Boolean, default: false }, // 深度观察data deep: { type: Boolean, default: false }, // 是否禁止默认关闭事件 disableDefaultCancel: { type: Boolean, default: false }, // 默认key defaultKey: { type: Array, default: () => [] }, // 默认value defaultValue: { type: Array, default: () => [] }, // 背景index bkIndex: { type: Number, default: 500 }, // select index selectIndex: { type: Number, default: 600 } }, render(this: any, h) { this.uid = this._uid; if (this.inline) { return h('div', { class: `q-select-inline--${this._uid}` }); } else { return h(''); } } }); export default Component;