UNPKG

shu-c-view

Version:

rollup 打包vue@2.7组件库框架

442 lines (440 loc) 12.9 kB
/** * @desc 属性 grid */ import _isString from 'lodash/isString'; import _isEmpty from 'lodash/isEmpty'; import _has from 'lodash/has'; import _isBoolean from 'lodash/isBoolean'; import _get from 'lodash/get'; import _omit from 'lodash/omit'; import _assign from 'lodash/assign'; import _set from 'lodash/set'; import _isNil from 'lodash/isNil'; import _isArray from 'lodash/isArray'; import _find from 'lodash/find'; import _forEach from 'lodash/forEach'; import { apply, devConsole } from '../helper/util.js'; const BasePropertyGrid = { name: 'BasePropertyGrid', inheritAttrs: false, props: { labelAlign: { type: String, default: 'left' }, width: { type: [String, Number], default: '100%' }, labelField: { type: String, default: 'label' }, valueField: { type: String, default: 'value' }, // 数据集对象 tableData: { type: Array, default() { return []; } }, // 一个可选添加的CSS样式类,加入到组件的容器上 ctCls: { type: String }, // table 原生属性 tableAttributes: { type: Object, default() { return {}; } }, // 列对应的组件配置 customEditors: { type: Object }, // 校验规则 rules: { type: Object }, // 一次是否只编辑一个列 isOnlyColumnEdit: { type: Boolean, default: false }, // 校验信息是否单行展示 inlineMessage: { type: Boolean, default: false }, // 设定列的宽度 nameColumnWidth: { type: String } }, watch: { tableData: { handler: function(val, oldVal) { if (!_isEmpty(val)) { for (let i = 0, len = this.tableData.length; i < len; i++) { const item = this.tableData[i]; if (!_has(item, 'edit')) { this.$set(item, 'edit', false); // 普通行元素-非编辑模式 } if (!_isNil(this.rules)) { this.$set(this.model, item.name, item.value); // form.model } this.$set(this.bbb, item.name, item.value); // 响应式值 } } }, immediate: true } }, data() { return { model: {}, bbb: {}, allEdit: false }; }, methods: { /** * @desc 打开编辑模式 */ openEdit() { _forEach(this.tableData, item => { item.edit = true; }); this.allEdit = true; }, /** * @desc 取消编辑模式 */ cancelEdit() { _forEach(this.tableData, item => { item.edit = false; }); this.allEdit = false; }, /** * @desc 获取表单 */ getForm() { return this.$refs.ruleFormRef; }, /** * @desc 校验 * @param {Function} callback - 校验的回调函数 */ validate(callback) { if (!_isNil(this.rules)) { return this.getForm().validate(callback); } }, /** * @desc 转换字典数据 */ filter2DictValue(props) { const dict = _find( this.$dict.get(_get(this.customEditors, props.row.name + '.filter')), item => { return ( item.paramValue === props.row[this.valueField] || item.paramValue === `${props.row[this.valueField]}` ); } ); if (!_isNil(dict)) { return dict.paramDesc; } }, /** * @desc el-input */ createInput(data) { const h = this.$createElement; return h( 'el-input', { attrs: { placeholder: '请输入内容' }, props: { value: !_isNil(this.rules) ? _get(this.model, data.row.name) : data.row[this.valueField], clearable: true }, on: { input: value => { data.row[this.valueField] = value; if (!_isNil(this.rules)) { _set(this.model, data.row.name, value); } if (_has(this.bbb, data.row.name)) { _set(this.bbb, data.row.name, value); } this.$emit('propertyChange', value); } } }, [] ); }, /** * @desc 插件boolean类型的select下拉只有 true和false两个 */ createBooleanSelect(data) { const h = this.$createElement; const options = [ { value: true, label: 'true' }, { value: false, label: 'false' } ]; const vNodes = []; for (let i = 0, len = options.length; i < len; i++) { const item = options[i]; vNodes.push( h( 'el-option', { props: { key: item.value, label: item.label, value: item.value } }, [] ) ); } return h( 'el-select', { attrs: { placeholder: '请选择' }, props: { value: !_isNil(this.rules) ? _get(this.model, data.row.name) : data.row[this.valueField] }, on: { input: val => { data.row[this.valueField] = val; if (!_isNil(this.rules)) { _set(this.model, data.row.name, val); } if (_has(this.bbb, data.row.name)) { _set(this.bbb, data.row.name, val); } this.$emit('propertyChange', val); } } }, vNodes ); }, /** * @desc 创建动态组件 */ createComponent(columnComponent, data) { const h = this.$createElement; return h( columnComponent.el, { attrs: _omit(columnComponent, ['el']), props: _assign( { value: !_isNil(this.rules) ? _get(this.model, data.row.name) : data.row[this.valueField], selectTreeValue: !_isNil(this.rules) ? _get(this.model, data.row.name) : data.row[this.valueField] }, _omit(columnComponent, ['el']) ), on: { input: value => { data.row[this.valueField] = value; if (!_isNil(this.rules)) { _set(this.model, data.row.name, value); } if (_has(this.bbb, data.row.name)) { _set(this.bbb, data.row.name, value); } this.$emit('propertyChange', value); // 当属性改变之后触发的事件 }, selectChange: value => { data.row[this.valueField] = value; if (!_isNil(this.rules)) { _set(this.model, data.row.name, value); } if (_has(this.bbb, data.row.name)) { _set(this.bbb, data.row.name, value); } this.$emit('propertyChange', value); }, selectTreeChange: value => { data.row[this.valueField] = value; if (!_isNil(this.rules)) { _set(this.model, data.row.name, value); } if (_has(this.bbb, data.row.name)) { _set(this.bbb, data.row.name, value); } this.$emit('propertyChange', value); } } }, [] ); }, /** * @desc 创建 el-table */ createTable() { const h = this.$createElement; const nameProps = { prop: this.labelField, label: '名称', align: this.labelAlign }; if (!_isNil(this.nameColumnWidth)) { nameProps.width = this.nameColumnWidth; } return h( 'el-table', { class: { 'base-property-grid': true, [this.ctCls]: !_isNil(this.ctCls) }, style: { width: _isString(this.width) ? this.width : `${this.width}px` }, props: apply({ data: this.tableData }, this.tableAttributes), on: { 'cell-click': row => { if (!this.allEdit) { _forEach(this.tableData, item => { if (item.edit && item.name !== row.name) { item.edit = false; } }); } }, 'cell-dblclick': row => { if (!this.allEdit) { // 设置为编辑模式 if (this.isOnlyColumnEdit) { _forEach(this.tableData, item => { if (item.edit) { item.edit = false; } }); } this.$nextTick(() => { row.edit = true; this.$emit('afterEdit', JSON.parse(JSON.stringify(row))); // 当一个单元格被编辑后触发 }); } } } }, [ h( 'el-table-column', { props: nameProps }, [] ), h( 'el-table-column', { props: { prop: this.valueField, label: '值' }, scopedSlots: { default: props => { const value = props.row[this.valueField]; if (!props.row.edit) { if ( !_isNil(this.customEditors) && _has(this.customEditors, props.row.name) ) { if ( _has(this.customEditors, props.row.name + '.asyncLoad') ) { // 异步转换-只支持 Promise 可以转换值 this.customEditors[props.row.name] .asyncLoad(props) .then(v => { this.$set(this.bbb, props.row.name, v); }) .catch(error => { throw new Error(error); }); return this.bbb[props.row.name]; } if ( _has(this.customEditors, props.row.name + '.filter') ) { if (_has(this.$scopedSlots, props.row.name)) { return this.$scopedSlots[props.row.name](props); } return this.filter2DictValue(props); } } if (_has(this.$scopedSlots, props.row.name)) { return this.$scopedSlots[props.row.name](props); } return value; } else { let node = this.createInput(props); if ( _has(props, 'row.name') && !_isNil(this.customEditors) ) { const name = props.row.name; const columnComponent = _get(this.customEditors, name); if (!_isNil(columnComponent)) { node = this.createComponent(columnComponent, props); } } if (_isBoolean(value)) { node = this.createBooleanSelect(props); } if (_isNil(this.rules)) { return node; } return h( 'el-form-item', { props: { prop: props.row.name } }, [node] ); } } } }, [] ) ] ); } }, render(h) { if (_isNil(this.rules)) { return this.createTable(); } return h( 'el-form', { class: { 'base-property-grid': true, [this.ctCls]: !_isNil(this.ctCls), 'base-property-grid_form': !!this.inlineMessage }, ref: 'ruleFormRef', props: { model: this.model, rules: this.rules } }, [this.createTable()] ); } }; BasePropertyGrid.install = function(Vue, ElComponents) { // 用于按需加载的时候独立使用 devConsole('按需加载独立组件:' + BasePropertyGrid.name); if (_isArray(ElComponents) && !_isEmpty(ElComponents)) { for (let i = 0; i < ElComponents.length; i++) { if (ElComponents[i].name !== BasePropertyGrid.name) { Vue.use(ElComponents[i]); } } } Vue.component(BasePropertyGrid.name, BasePropertyGrid); }; export { BasePropertyGrid };