UNPKG

shu-c-view

Version:

rollup 打包vue@2.7组件库框架

490 lines (488 loc) 12.7 kB
// @ts-nocheck /** * Select 选择器 */ import _get from 'lodash/get'; import _isNil from 'lodash/isNil'; import _set from 'lodash/set'; import _isEqual from 'lodash/isEqual'; import _isEmpty from 'lodash/isEmpty'; import _assign from 'lodash/assign'; import _has from 'lodash/has'; import _isArray from 'lodash/isArray'; import _clone from 'lodash/clone'; import _map from 'lodash/map'; import _find from 'lodash/find'; import { devConsole } from '../helper/util.js'; const BaseSelect = { name: 'BaseSelect', inheritAttrs: false, model: { prop: 'value', event: 'selectChange' }, props: { value: { type: [String, Number, Array, Boolean], required: true }, api: { type: String, default: '' }, queryParams: { type: Object, default() { return {}; } }, // 第一次载入时是否自动刷新列表数据 isReloadGrid: { type: Boolean, default: true }, options: { type: Array }, // isWidthAdapt: true,宽度则使用auto width: { type: String, default: 'auto' }, ctStyle: { type: Object, default() { return {}; } }, ctCls: { type: Object, default() { return {}; } }, loadFilter: { type: Function, default: null }, displayField: { type: String, default: 'name' }, valueField: { type: String, default: 'id' }, slotNode: { type: Object, default: () => {} }, isRender: { type: Boolean, default: true }, isDisplay: { type: Boolean, default: true }, listeners: { type: Object, default: () => {} }, // 前缀的单位 preUnit: { type: String, default: '' }, // 后缀的单位 sufUnit: { type: String, default: '' }, // 是否选中第一个,单选时起效 isSelectedFirstRow: { type: Boolean, default: false }, // 动态宽度-单选时生效,设置后 width 参数将失效 isWidthAdapt: { type: Boolean, default: false } }, data() { this.vQueryParams = _isEmpty(this.api) ? {} : _assign({}, this.queryParams); this.events = { onLoadSuccess: 'onLoadSuccess' }; // this.vValue = this.$attrs.multiple ? _assign([], this.value) : this.value; return { vValue: this.$attrs.multiple ? _assign([], this.value) : this.value, vOptions: [] }; }, computed: { elOptions() { const elOptions = []; const h = this.$createElement; if (this.options) { this.vOptions = this.options; } if (_isNil(this.vOptions)) { return; } for (let i = 0; i < this.vOptions.length; i++) { const option = this.vOptions[i]; if (_has(this.$scopedSlots, 'default')) { elOptions.push( h( 'el-option', { props: { key: option[this.valueField], label: this.preUnit + option[this.displayField] + this.sufUnit, value: option[this.valueField], disabled: option.disabled } }, [ h('template', { slot: 'default' }, [ /* this.$scopedSlots.default({ [this.displayField]: option[this.displayField], [this.valueField]: option[this.valueField] }) */ this.$scopedSlots.default(_clone(option)) ]) ] ) ); } else { elOptions.push( h('el-option', { props: { key: option[this.valueField], label: this.preUnit + option[this.displayField] + this.sufUnit, value: option[this.valueField], disabled: option.disabled } }) ); } } /* const elOptions = this.vOptions.map(option => { return this.$createElement('el-option', { props: { key: option[this.valueField], label: option[this.displayField], value: option[this.valueField], disabled: option.disabled } }) }) */ return elOptions; }, optionLabel() { const option = this.vOptions.find( item => item[this.valueField] === this.vValue ); return _get(option, this.displayField); }, slotElement() { const nodes = []; const multiple = _get(this.$attrs, 'multiple', false); if (this.isWidthAdapt && !multiple) { nodes.push( this.$createElement('template', { slot: 'prefix' }, [ this.optionLabel ]) ); } if (!this.isWidthAdapt && _has(this.$slots, 'prefix')) { nodes.push( this.$createElement('template', { slot: 'prefix' }, [ this.$slots.prefix ]) ); } // if (_has(this.$slots, 'empty')) { // nodes.push( // this.$createElement('template', { slot: 'empty' }, [ // this.$slots.empty // ]) // ); // } // } return nodes; } }, watch: { value(value, oldValue) { if (!_isEqual(value, oldValue) && !_isEqual(this.vValue, value)) { this.vValue = value; // this._changeEvent(this.vValue); // this._selectChangeEvent(this.vValue); } }, api: { handler() { this.isReloadGrid && this._fetchList(); }, immediate: true }, options: { handler() { if (!_isEmpty(this.options) && this.api.length === 0) { if ( this.isSelectedFirstRow && (!_has(this.$attrs, 'multiple') || this.$attrs.multiple === false) ) { this.vValue = _get(this.options, `[0].${this.valueField}`); setTimeout(() => { this._selectChangeEvent(this.vValue); }, 0); } } }, deep: true, immediate: true } }, methods: { /** * @desc 获取远程服务器数据的操作 * @method */ _fetchList() { if (_isEmpty(this.api) || _isNil(this.$api)) { return; } this.$api[this.api](this.vQueryParams) .then(resData => { if (!_isNil(this.loadFilter)) { resData = this.loadFilter(resData.data); } if ( this.isSelectedFirstRow && !_isEmpty(resData.data) && (!_has(this.$attrs, 'multiple') || this.$attrs.multiple === false) ) { this.vValue = _get(resData, `data[0].${this.valueField}`); setTimeout(() => { this._selectChangeEvent(this.vValue); }, 0); } setTimeout(() => { this.$emit(this.events.onLoadSuccess, resData.data); }, 0); this.vOptions = resData.data; return true; }) .catch(error => { console.error(error); }); }, /** * @desc 选中值发生变化时触发 * @event FastComboBox#_changeEvent * @param {Array} value - 选中项 */ _changeEvent(value) { const v = this.multiple ? _assign([], value) : value; if ( _isEqual(_isNil(this.listeners), false) && _has(this.listeners, 'change') ) { this.listeners.change(v); return; } this.$emit('change', v); }, /** * @desc 下拉框出现/隐藏时触发 * @event FastComboBox#_visibleChangeEvent * @param {boolean} value */ _visibleChangeEvent(value) { if ( _isEqual(_isNil(this.listeners), false) && _has(this.listeners, 'visible-change') ) { this.listeners['visible-change'](value); return; } this.$emit('visible-change', value); }, /** * @desc 多选模式下移除tag时触发 * @event FastComboBox#_removeTag * @param {*} value */ _removeTag(value) { if ( _isEqual(_isNil(this.listeners), false) && _has(this.listeners, 'remove-tag') ) { this.listeners['remove-tag'](value); return; } this.$emit('remove-tag', value); }, /** * @desc 可清空的单选模式下用户点击清空按钮时触发 * @event FastComboBox#_clearEvent */ _clearEvent() { if ( _isEqual(_isNil(this.listeners), false) && _has(this.listeners, 'clear') ) { this.listeners.clear(); return; } this.$emit('clear'); }, /** * @desc 当 input 失去焦点时触发 * @event FastComboBox#_blurEvent * @param {*} event */ _blurEvent(event) { if ( _isEqual(_isNil(this.listeners), false) && _has(this.listeners, 'blur') ) { this.listeners.blur(event); return; } this.$emit('blur', event); }, /** * @desc 当 input 获得焦点时触发 * @event FastComboBox#_focusEvent * @param {*} event */ _focusEvent(event) { if ( _isEqual(_isNil(this.listeners), false) && _has(this.listeners, 'focus') ) { this.listeners.focus(event); return; } this.$emit('focus', event); }, /** * @desc 下拉选择项发生改变时 * @event FastInput#_selectChangeEvent * @param {Array} value - 选中项 */ _selectChangeEvent(value) { const v = this.multiple ? _assign([], value) : value; if ( _isEqual(_isNil(this.listeners), false) && _has(this.listeners, 'selectChange') ) { this.listeners.selectChange(v); return; } // v-model this.$emit('selectChange', v); }, /** * @desc 手动执行刷新数据操作 * @method * @param {Object} params - 查询条件 */ reload(params = {}) { if (!_isEmpty(this.api)) { _assign(this.vQueryParams, params); this._fetchList(); } }, getOptions() { return _map(this.vOptions, p => { return { ...p }; }); }, getChangedOption() { if (_has(this.$attrs, 'multiple') && this.$attrs.multiple) { // 多选 return _map(this.vValue, v => { return { ..._find(this.vOptions, o => o[this.valueField] === v) }; }); } // 单选 const option = _find( this.vOptions, item => item[this.valueField] === this.vValue ); if (option) { return { ...option }; } } }, render(h) { // v-if if (_isEqual(this.isRender, false)) { return h(); } const style = _assign({}, _get(this.$props, 'ctStyle', {})); // { ..._get(this.$props, 'ctStyle', {}) } if (this.width !== 'auto' && !this.isWidthAdapt) { style.width = this.width; } // v-show if (_isEqual(this.isDisplay, false)) { _set(style, 'display', 'none'); } return h( 'el-select', { ref: 'el-select-ref', class: _assign( { 'base-select': true, select__autoWidth: this.isWidthAdapt && this.optionLabel }, _get(this.$props, 'ctCls', {}) ), style, attrs: { id: this.$attrs.id }, props: _assign({}, this.$attrs, { value: this.vValue }), // { ...this.$attrs, value: this.vValue }, on: { change: this._changeEvent, 'visible-change': this._visibleChangeEvent, 'remove-tag': this._removeTag, clear: this._clearEvent, blur: this._blurEvent, focus: this._focusEvent, input: val => { // v-model this.vValue = val; this._selectChangeEvent(this.vValue); } } }, [ this.elOptions, this.slotElement, h('template', { slot: 'empty' }, [this.$slots.empty]) ] ); } }; BaseSelect.install = function(Vue, ElComponents) { // 用于按需加载的时候独立使用 devConsole(`按需加载独立组件:${BaseSelect.name}`); if (_isArray(ElComponents) && !_isEmpty(ElComponents)) { for (let i = 0; i < ElComponents.length; i++) { if (ElComponents[i].name !== BaseSelect.name) { Vue.use(ElComponents[i]); } } } Vue.component(BaseSelect.name, BaseSelect); }; export { BaseSelect };