UNPKG

shu-c-view

Version:

rollup 打包vue组件库框架

415 lines (413 loc) 10.7 kB
/** * @desc 下拉图标选择器-只能单选 */ 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 _isString from 'lodash/isString'; import _isArray from 'lodash/isArray'; import _includes from 'lodash/includes'; import _find from 'lodash/find'; import { devConsole } from '../helper/util.js'; const BaseSelectIconPicker = { name: 'BaseSelectIconPicker', inheritAttrs: false, model: { prop: 'value', event: 'selectChange' }, props: { // v-model value: { type: String, required: true }, // 数据 options: { type: Array, default() { return []; } }, // svg component 静态数据 svgIconsOptions: { type: Array, default() { return []; } }, width: { type: String, default: 'auto' }, ctStyle: { type: Object, default() { return {}; } }, ctCls: { type: Object, default() { return {}; } }, displayField: { type: String, default: 'name' }, valueField: { type: String, default: 'id' }, isRender: { type: Boolean, default: true }, isDisplay: { type: Boolean, default: true }, listeners: { type: Object, default: () => {} }, // 图标的尺寸 svgSize: { type: String, default: '16px' }, // 亮色和暗色 模式 bgModelVal: { type: String, default: 'light', validator(value) { return ['dark', 'light'].includes(value); } } }, data() { this.vValue = this.value; return { vOptions: this.options, iconPicture: this.value }; }, 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++) { let option = this.vOptions[i]; if (_isString(option)) { option = { [this.displayField]: option, [this.valueField]: `symbol-${option}` }; } elOptions.push( this.$createElement( 'el-option', { props: { key: option[this.valueField], label: option[this.displayField], value: option[this.valueField], disabled: option.disabled } }, [ this.getIconNode(_get(option, this.valueField)), h('span', { style: 'float: right' }, [ _get(option, this.displayField) ]) ] ) ); } for (let i = 0; i < this.svgIconsOptions.length; i++) { const option = { [this.displayField]: this.svgIconsOptions[i].name, [this.valueField]: `svg-${this.svgIconsOptions[i].name}` }; elOptions.push( this.$createElement( 'el-option', { props: { key: option[this.valueField], label: option[this.displayField], value: option[this.valueField], disabled: option.disabled } }, [ this.getIconNode(_get(option, this.valueField)), h('span', { style: 'float: right' }, [ _get(option, this.displayField) ]) ] ) ); } return elOptions; }, slotElement() { return this.$createElement('template', { slot: 'prefix' }, [ this.getIconNode(this.iconPicture) ]); }, bgModel() { return this.bgModelVal; } }, watch: { value(value, oldValue) { if (!_isEqual(value, oldValue) && !_isEqual(this.vValue, value)) { this.vValue = value; this.iconPicture = this.vValue; this._changeEvent(this.vValue); this._selectChangeEvent(this.vValue); } } }, methods: { /** * @desc 选中值发生变化时触发 * @event FastComboBox#_changeEvent * @param {Array} value - 选中项 */ _changeEvent(value) { const v = value; this.iconPicture = 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 = 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(); } }, /** * @desc iconUrl->VNode */ getIconNode(iconUrl) { if (_includes(iconUrl, 'svg-')) { // svg图 const curUrl = iconUrl.replace('svg-', ''); const svgObj = _find(this.svgIconsOptions, o => o.name === curUrl); if (!_isNil(svgObj)) { iconUrl = this.$createElement(_get(svgObj, 'component', 'span'), { style: { width: this.svgSize, height: this.svgSize, marginRight: '5px', display: 'inline' } }); } else { // iconUrl = this.$createElement('i', {}, []); } } else if (/\.(gif|png|jpg|jpeg|webp|svg|psd|bmp|tif)$/.test(iconUrl)) { // 静态资源图 iconUrl = this.$createElement('img', { style: { marginRight: '5px', display: 'inline' }, attrs: { src: iconUrl, width: this.svgSize, height: this.svgSize } }); } else if (iconUrl.indexOf('symbol-') !== -1) { // symbol 图 iconUrl = this.$createElement( 'base-svg-icon', { style: { marginRight: '5px', display: 'inline' }, props: { size: this.svgSize, iconname: iconUrl.replace('symbol-', '') } }, [] ); } else { iconUrl = this.$createElement('i', { class: iconUrl }); } return iconUrl; } }, 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') { 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-icon-picker': true, 'base-select-icon-picker__dark': this.bgModel === 'dark' }, _get(this.$props, 'ctCls', {}) ), style, attrs: { id: this.$attrs.id }, props: _assign({}, this.$attrs, { value: this.vValue, multiple: false, popperClass: this.bgModel === 'dark' ? 'select-icon-picker__popover-dark' : '' }), // { ...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] ); } }; BaseSelectIconPicker.install = function(Vue, ElComponents) { // 用于按需加载的时候独立使用 devConsole(`按需加载独立组件:${BaseSelectIconPicker.name}`); if (_isArray(ElComponents) && !_isEmpty(ElComponents)) { for (let i = 0; i < ElComponents.length; i++) { if (ElComponents[i].name !== BaseSelectIconPicker.name) { Vue.use(ElComponents[i]); } } } Vue.component(BaseSelectIconPicker.name, BaseSelectIconPicker); }; export { BaseSelectIconPicker };