diff --git a/gulpfile.js b/gulpfile.js index ec86f6bae..009b67a03 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -43,6 +43,7 @@ const components = [ 'input', 'textarea', 'button', + 'button-group', 'modal', 'tooltip', 'form', diff --git a/package.json b/package.json index aff242116..d2a94acb1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vxe-table", - "version": "3.7.10", + "version": "3.8.0-beta.0", "description": "一个基于 vue 的 PC 端表单/表格组件,支持增删改查、虚拟列表、虚拟树、懒加载、快捷菜单、数据校验、树形结构、打印导出、表单渲染、数据分页、弹窗、自定义模板、渲染器、JSON 配置式...", "scripts": { "update": "npm install --legacy-peer-deps", diff --git a/packages/checkbox/src/group.js b/packages/checkbox/src/group.js index 914ee58f9..9191c08e9 100644 --- a/packages/checkbox/src/group.js +++ b/packages/checkbox/src/group.js @@ -5,6 +5,8 @@ export default { name: 'VxeCheckboxGroup', props: { value: Array, + options: Array, + optionProps: Object, disabled: Boolean, max: [String, Number], size: { type: String, default: () => GlobalConfig.checkbox.size || GlobalConfig.size } @@ -32,13 +34,28 @@ export default { return value.length >= XEUtils.toNumber(max) } return false + }, + propsOpts () { + return this.optionProps || {} + }, + labelField () { + return this.propsOpts.label || 'label' + }, + valueField () { + return this.propsOpts.value || 'value' } }, render (h) { - const { $scopedSlots } = this + const { $scopedSlots, options, valueField, labelField } = this + const defaultSlots = $scopedSlots.default return h('div', { class: 'vxe-checkbox-group' - }, $scopedSlots.default ? $scopedSlots.default.call(this, {}) : []) + }, defaultSlots ? defaultSlots.call(this, {}) : (options ? options.map(item => { + return h('vxe-checkbox', { + label: item[valueField], + content: item[labelField] + }) + }) : [])) }, methods: { handleChecked (params, evnt) { diff --git a/packages/export/src/mixin.js b/packages/export/src/mixin.js index d76286f58..5c15cbd2f 100644 --- a/packages/export/src/mixin.js +++ b/packages/export/src/mixin.js @@ -336,6 +336,7 @@ function createHtmlPage (opts, content) { '', '', `${opts.sheetName}`, + '', ``, style ? `` : '', '', diff --git a/packages/radio/src/group.js b/packages/radio/src/group.js index 6b7e6329a..3ee040010 100644 --- a/packages/radio/src/group.js +++ b/packages/radio/src/group.js @@ -5,6 +5,8 @@ export default { name: 'VxeRadioGroup', props: { value: [String, Number, Boolean], + options: Array, + optionProps: Object, disabled: Boolean, strict: { type: Boolean, default: () => GlobalConfig.radioGroup.strict }, size: { type: String, default: () => GlobalConfig.radioGroup.size || GlobalConfig.size } @@ -25,6 +27,15 @@ export default { computed: { vSize () { return this.size || this.$parent.size || this.$parent.vSize + }, + propsOpts () { + return this.optionProps || {} + }, + labelField () { + return this.propsOpts.label || 'label' + }, + valueField () { + return this.propsOpts.value || 'value' } }, data () { @@ -33,10 +44,16 @@ export default { } }, render (h) { - const { $scopedSlots } = this + const { $scopedSlots, options, valueField, labelField } = this + const defaultSlots = $scopedSlots.default return h('div', { class: 'vxe-radio-group' - }, $scopedSlots.default ? $scopedSlots.default.call(this, {}) : []) + }, defaultSlots ? defaultSlots.call(this, {}) : (options ? options.map(item => { + return h('vxe-radio', { + label: item[valueField], + content: item[labelField] + }) + }) : [])) }, methods: { handleChecked (params, evnt) { diff --git a/packages/v-x-e-table/src/conf.js b/packages/v-x-e-table/src/conf.js index 37f1eaef3..e52b0a036 100644 --- a/packages/v-x-e-table/src/conf.js +++ b/packages/v-x-e-table/src/conf.js @@ -342,6 +342,9 @@ export default { checkbox: { // size: null }, + checkboxGroup: { + // size: null + }, switch: { // size: null }, diff --git a/packages/v-x-e-table/src/renderer.js b/packages/v-x-e-table/src/renderer.js index 0a0d126a8..0fb571c1a 100644 --- a/packages/v-x-e-table/src/renderer.js +++ b/packages/v-x-e-table/src/renderer.js @@ -257,6 +257,16 @@ function nativeEditRender (h, renderOpts, params) { ] } +function defaultCellRender (h, renderOpts, params) { + return [ + h(getDefaultComponentName(renderOpts), { + props: getCellEditProps(renderOpts, params), + on: getOns(renderOpts, params), + nativeOn: getNativeOns(renderOpts, params) + }) + ] +} + function defaultEditRender (h, renderOpts, params) { const { row, column } = params const cellValue = UtilTools.getCellValue(row, column) @@ -488,7 +498,7 @@ function handleExportSelectMethod (params) { * 渲染表单-项中 * 单选框和复选框 */ -function defaultFormItemRadioAndCheckboxRender (h, renderOpts, params) { +function defaultFormItemRender (h, renderOpts, params) { const { options, optionProps = {} } = renderOpts const { data, property } = params const labelProp = optionProps.label || 'label' @@ -524,6 +534,111 @@ function defaultFormItemRadioAndCheckboxRender (h, renderOpts, params) { ] } +/** + * 已废弃 + */ +function defaultOldFormItemRadioAndCheckboxRender (h, renderOpts, params) { + const { options, optionProps = {} } = renderOpts + const { data, property } = params + const labelProp = optionProps.label || 'label' + const valueProp = optionProps.value || 'value' + const disabledProp = optionProps.disabled || 'disabled' + const itemValue = XEUtils.get(data, property) + const name = getDefaultComponentName(renderOpts) + // 如果是分组 + if (options) { + return [ + h(`${name}-group`, { + props: getItemProps(renderOpts, params, itemValue), + on: getItemOns(renderOpts, params), + nativeOn: getNativeOns(renderOpts, params) + }, options.map((item, index) => { + return h(name, { + key: index, + props: { + label: item[valueProp], + content: item[labelProp], + disabled: item[disabledProp] + } + }) + })) + ] + } + return [ + h(name, { + props: getItemProps(renderOpts, params, itemValue), + on: getItemOns(renderOpts, params), + nativeOn: getNativeOns(renderOpts, params) + }) + ] +} + +const VxeInputRender = { + autofocus: '.vxe-input--inner', + renderEdit: defaultEditRender, + renderCell (h, renderOpts, params) { + const { props = {} } = renderOpts + const { row, column } = params + const digits = props.digits || GlobalConfig.input.digits + let cellValue = XEUtils.get(row, column.property) + if (cellValue) { + switch (props.type) { + case 'date': + case 'week': + case 'month': + case 'year': + cellValue = getLabelFormatDate(cellValue, props) + break + case 'float': + cellValue = XEUtils.toFixed(XEUtils.floor(cellValue, digits), digits) + break + } + } + return getCellLabelVNs(h, renderOpts, params, cellValue) + }, + renderDefault: defaultEditRender, + renderFilter: defaultFilterRender, + defaultFilterMethod: handleFilterMethod, + renderItemContent: defaultItemRender +} + +const VxeSelectRender = { + autofocus: '.vxe-input--inner', + renderEdit: defaultSelectEditRender, + renderDefault: defaultSelectEditRender, + renderCell (h, renderOpts, params) { + return getCellLabelVNs(h, renderOpts, params, getSelectCellValue(renderOpts, params)) + }, + renderFilter (h, renderOpts, params) { + const { column } = params + const { options, optionProps, optionGroups, optionGroupProps } = renderOpts + const nativeOn = getNativeOns(renderOpts, params) + return column.filters.map((option, oIndex) => { + const optionValue = option.data + return h(getDefaultComponentName(renderOpts), { + key: oIndex, + props: getFilterProps(renderOpts, params, optionValue, { options, optionProps, optionGroups, optionGroupProps }), + on: getFilterOns(renderOpts, params, option), + nativeOn + }) + }) + }, + defaultFilterMethod: handleFilterMethod, + renderItemContent (h, renderOpts, params) { + const { data, property } = params + const { options, optionProps, optionGroups, optionGroupProps } = renderOpts + const itemValue = XEUtils.get(data, property) + return [ + h(getDefaultComponentName(renderOpts), { + props: getItemProps(renderOpts, params, itemValue, { options, optionProps, optionGroups, optionGroupProps }), + on: getItemOns(renderOpts, params), + nativeOn: getNativeOns(renderOpts, params) + }) + ] + }, + cellExportMethod: handleExportSelectMethod +} + /** * 内置的组件渲染 */ @@ -572,34 +687,45 @@ const renderMap = { }, cellExportMethod: handleExportSelectMethod }, - $input: { - autofocus: '.vxe-input--inner', - renderEdit: defaultEditRender, - renderCell (h, renderOpts, params) { - const { props = {} } = renderOpts - const { row, column } = params - const digits = props.digits || GlobalConfig.input.digits - let cellValue = XEUtils.get(row, column.property) - if (cellValue) { - switch (props.type) { - case 'date': - case 'week': - case 'month': - case 'year': - cellValue = getLabelFormatDate(cellValue, props) - break - case 'float': - cellValue = XEUtils.toFixed(XEUtils.floor(cellValue, digits), digits) - break - } - } - return getCellLabelVNs(h, renderOpts, params, cellValue) - }, - renderDefault: defaultEditRender, - renderFilter: defaultFilterRender, - defaultFilterMethod: handleFilterMethod, + VxeInput: VxeInputRender, + VxeTextarea: { + autofocus: '.vxe-textarea--inner', renderItemContent: defaultItemRender }, + VxeButton: { + renderDefault: defaultCellRender, + renderItemContent: defaultFormItemRender + }, + VxeButtonGroup: { + renderDefault: defaultCellRender, + renderItemContent: defaultFormItemRender + }, + VxeSelect: VxeSelectRender, + VxeRadio: { + autofocus: '.vxe-radio--input', + renderItemContent: defaultFormItemRender + }, + VxeRadioGroup: { + autofocus: '.vxe-radio--input', + renderItemContent: defaultFormItemRender + }, + VxeCheckbox: { + autofocus: '.vxe-checkbox--input', + renderItemContent: defaultFormItemRender + }, + VxeCheckboxGroup: { + autofocus: '.vxe-checkbox--input', + renderItemContent: defaultFormItemRender + }, + VxeSwitch: { + autofocus: '.vxe-switch--button', + renderEdit: defaultEditRender, + renderDefault: defaultEditRender, + renderItemContent: defaultItemRender + }, + + // 以下已废弃 + $input: VxeInputRender, $textarea: { autofocus: '.vxe-textarea--inner', renderItemContent: defaultItemRender @@ -612,49 +738,14 @@ const renderMap = { renderDefault: defaultButtonsEditRender, renderItemContent: defaultButtonsItemRender }, - $select: { - autofocus: '.vxe-input--inner', - renderEdit: defaultSelectEditRender, - renderDefault: defaultSelectEditRender, - renderCell (h, renderOpts, params) { - return getCellLabelVNs(h, renderOpts, params, getSelectCellValue(renderOpts, params)) - }, - renderFilter (h, renderOpts, params) { - const { column } = params - const { options, optionProps, optionGroups, optionGroupProps } = renderOpts - const nativeOn = getNativeOns(renderOpts, params) - return column.filters.map((option, oIndex) => { - const optionValue = option.data - return h(getDefaultComponentName(renderOpts), { - key: oIndex, - props: getFilterProps(renderOpts, params, optionValue, { options, optionProps, optionGroups, optionGroupProps }), - on: getFilterOns(renderOpts, params, option), - nativeOn - }) - }) - }, - defaultFilterMethod: handleFilterMethod, - renderItemContent (h, renderOpts, params) { - const { data, property } = params - const { options, optionProps, optionGroups, optionGroupProps } = renderOpts - const itemValue = XEUtils.get(data, property) - return [ - h(getDefaultComponentName(renderOpts), { - props: getItemProps(renderOpts, params, itemValue, { options, optionProps, optionGroups, optionGroupProps }), - on: getItemOns(renderOpts, params), - nativeOn: getNativeOns(renderOpts, params) - }) - ] - }, - cellExportMethod: handleExportSelectMethod - }, + $select: VxeSelectRender, $radio: { autofocus: '.vxe-radio--input', - renderItemContent: defaultFormItemRadioAndCheckboxRender + renderItemContent: defaultOldFormItemRadioAndCheckboxRender }, $checkbox: { autofocus: '.vxe-checkbox--input', - renderItemContent: defaultFormItemRadioAndCheckboxRender + renderItemContent: defaultOldFormItemRadioAndCheckboxRender }, $switch: { autofocus: '.vxe-switch--button', @@ -662,6 +753,7 @@ const renderMap = { renderDefault: defaultEditRender, renderItemContent: defaultItemRender } + // 以上已废弃 } /** diff --git a/styles/all.scss b/styles/all.scss index f3e1f775a..69aa526f8 100644 --- a/styles/all.scss +++ b/styles/all.scss @@ -17,6 +17,7 @@ @import './input.scss'; @import './textarea.scss'; @import './button.scss'; +@import './button-group.scss'; @import './modal.scss'; @import './tooltip.scss'; @import './form.scss'; diff --git a/styles/button-group.scss b/styles/button-group.scss new file mode 100644 index 000000000..054a56ec7 --- /dev/null +++ b/styles/button-group.scss @@ -0,0 +1 @@ +/**Variable**/ diff --git a/types/all.d.ts b/types/all.d.ts index 7dc1cd761..ab082a55d 100644 --- a/types/all.d.ts +++ b/types/all.d.ts @@ -65,6 +65,7 @@ export * from './radio-button' export * from './input' export * from './textarea' export * from './button' +export * from './button-group' export * from './select' export * from './optgroup' export * from './option' diff --git a/types/button-group.d.ts b/types/button-group.d.ts new file mode 100644 index 000000000..5bee85d7a --- /dev/null +++ b/types/button-group.d.ts @@ -0,0 +1,9 @@ +import { VXETableComponent } from './component' + +/** + * 按钮组 + */ +export declare class ButtonGroup extends VXETableComponent { + options?: any[]; + disabled?: boolean; +}