diff --git a/packages/table/editor.vue b/packages/table/editor.vue index 863480f..67b246e 100644 --- a/packages/table/editor.vue +++ b/packages/table/editor.vue @@ -37,49 +37,82 @@ function cellRender(h, context, item) { }; } +// 表单项渲染 +function formItemRender(h, context, item, scope, children) { + // 渲染函数配置 + const contentProps = context.props || {}; + // 编辑器统一配置 + const editorProps = get(contentProps, 'editor.props') || {}; + let formItemProp = [editorProps.path].filter(i => i); + formItemProp.push(scope.$index); + formItemProp.push(item.prop); + formItemProp = formItemProp.join('.'); + return h( + editorProps.formItem || 'el-form-item', + { + props: { prop: formItemProp, rules: item.rules, 'inline-message': true }, + }, + children, + ); +} + // 编辑器渲染 function editorRender(h, context, item) { const editorSlot = context.scopedSlots[`editor-${item.prop}`]; const contentProps = context.props || {}; return function(scope) { const value = get(scope.row, item.prop); - // 自定义具名插槽 - if (editorSlot) { - return editorSlot({ item, value, index: scope.$index, ...scope }); - } + let vnode = {}; // 默认 - const vnode = h(item.is, { - attrs: item.attrs, - props: { ...(item.props || {}), value }, - on: { - input(val) { - if (get(contentProps, 'editor.deep') === true) { - if (item.prop.indexOf('.') > -1 || item.prop.indexOf('[') > -1) { - let separator = ''; - if (item.prop.indexOf('.') > -1) { - separator = '.'; - } else if (item.prop.indexOf('[') > -1) { - separator = '['; - } - const path = item.prop.split(separator); - const bindProp = path[0]; - const propValue = cloneDeep(scope.row); - set(propValue, item.prop, val); - vnode.componentInstance.$set(scope.row, bindProp, propValue[bindProp]); - } else { - // set(scope.row, item.prop, val); - scope.row[item.prop] = val; - } - } else { - scope.row[item.prop] = val; - // set(contentProps.data, `[${[scope.$index]}]${item.prop}`, val); + const inputEvent = val => { + if (get(contentProps, 'editor.deep') === true) { + if (item.prop.indexOf('.') > -1 || item.prop.indexOf('[') > -1) { + let separator = ''; + if (item.prop.indexOf('.') > -1) { + separator = '.'; + } else if (item.prop.indexOf('[') > -1) { + separator = '['; } - if (item.on && item.on.input) { - item.on.input(val); - } - }, - }, + const path = item.prop.split(separator); + const bindProp = path[0]; + const propValue = cloneDeep(scope.row); + set(propValue, item.prop, val); + vnode.componentInstance.$set(scope.row, bindProp, propValue[bindProp]); + } else { + // set(scope.row, item.prop, val); + scope.row[item.prop] = val; + } + } else { + scope.row[item.prop] = val; + // set(contentProps.data, `[${[scope.$index]}]${item.prop}`, val); + } + if (item.on && item.on.input) { + item.on.input(val); + } + }; + const blurEvent = val => { + if (item.on && item.on.blur) { + item.on.blur(val); + } + }; + // 编辑表单项配置 + const itemProps = item.props || {}; + // 编辑器统一配置 + const editorProps = get(contentProps, 'editor.props') || {}; + // 生成虚拟节点 + vnode = h(item.is, { + attrs: item.attrs, + props: { ...editorProps, ...itemProps, value }, + on: { input: inputEvent, blur: blurEvent }, }); + // 自定义具名插槽 + if (editorSlot) { + return editorSlot({ item, value, index: scope.$index, ...scope, onInput: inputEvent }); + } + // 需要校验时外层嵌套校验组件 + if (editorProps.validate) { + return formItemRender(h, context, item, scope, [vnode]); + } return vnode; }; } @@ -90,11 +123,18 @@ function createElTableColumns(h, context, columns) { const editorConfig = props.editor || {}; return columns.map((item, index) => { const { attrs, on, ...props } = item; - const editorMatch = editorConfig.inputs.find(i => i.prop === item.prop); + const items = editorConfig.items || []; + // 当前列编辑器配置 + let editorItem = items.find(i => i.prop === item.prop); + // 当前列有编辑器配置或编辑器插槽的情况 + const isEditor = editorItem || context.scopedSlots[`editor-${item.prop}`]; + if (context.scopedSlots[`editor-${item.prop}`] && !editorItem) { + editorItem = item; + } // 处理插槽 const scopedSlots = { header: headerRender(h, context, item), - default: editorMatch ? editorRender(h, context, editorMatch) : cellRender(h, context, item), + default: isEditor ? editorRender(h, context, editorItem) : cellRender(h, context, item), }; return h('el-table-column', { key: index, attrs, props, on, scopedSlots }); }); @@ -106,6 +146,9 @@ export default { render(h, context) { console.log(context); const props = context.props || {}; + // 设置默认class名称,用来追加一些默认的样式 + const className = get(context, 'data.class'); + set(context, 'data.class', className ? `${className} z-table-editor` : 'z-table-editor'); let scopedSlots = context.scopedSlots || {}; // 如有默认插槽则相当于直接写el-table if (scopedSlots.default) { @@ -128,3 +171,16 @@ export default { }, }; + + diff --git a/packages/table/index.vue b/packages/table/index.vue index fdd4c3e..eab85fe 100644 --- a/packages/table/index.vue +++ b/packages/table/index.vue @@ -9,7 +9,7 @@ export default { if (Object.prototype.hasOwnProperty.call(props, 'editable') && props.editable !== false) { return h('z-table-editable', { props, scopedSlots: context.scopedSlots, on: context.listeners }); } - if (props.editor) { + if (Object.prototype.hasOwnProperty.call(props, 'editor')) { return ref('z-table-editor', context); } return ref('z-table-normal', context); -- libgit2 0.21.0