diff --git a/designer-demo/public/mock/bundle.json b/designer-demo/public/mock/bundle.json index 64fbf4bf1b..9cd3cdf17d 100644 --- a/designer-demo/public/mock/bundle.json +++ b/designer-demo/public/mock/bundle.json @@ -10152,6 +10152,54 @@ } } }, + { + "icon": "grid", + "name": { + "zh_CN": "表格行" + }, + "component": "TinyGridColumn", + "description": "提供了非常强大数据表格功能,可以展示数据列表,可以对数据列表进行选择、编辑等", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyGridColumn" + }, + "group": "component", + "priority": 2, + "schema": { + "properties": [], + "events": {}, + "shortcuts": {}, + "contentMenu": { + "actions": ["create symbol"] + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": {}, + "contextMenu": { + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, { "name": { "zh_CN": "分页" diff --git a/mockServer/src/assets/json/appinfo.json b/mockServer/src/assets/json/appinfo.json index 156bb9ccee..d15b9c6f4b 100644 --- a/mockServer/src/assets/json/appinfo.json +++ b/mockServer/src/assets/json/appinfo.json @@ -26956,6 +26956,54 @@ } } }, + { + "icon": "grid", + "name": { + "zh_CN": "表格行" + }, + "component": "TinyGridColumn", + "description": "提供了非常强大数据表格功能,可以展示数据列表,可以对数据列表进行选择、编辑等", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyGridColumn" + }, + "group": "component", + "priority": 2, + "schema": { + "properties": [], + "events": {}, + "shortcuts": {}, + "contentMenu": { + "actions": ["create symbol"] + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": {}, + "contextMenu": { + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, { "name": { "zh_CN": "分页" diff --git a/mockServer/src/mock/get/app-center/v1/apps/schema/918.json b/mockServer/src/mock/get/app-center/v1/apps/schema/918.json index 3c9a13c849..4d20d698f7 100644 --- a/mockServer/src/mock/get/app-center/v1/apps/schema/918.json +++ b/mockServer/src/mock/get/app-center/v1/apps/schema/918.json @@ -1904,6 +1904,13 @@ "destructuring": true, "version": "0.1.16" }, + { + "componentName": "TinyGridColumn", + "package": "@opentiny/vue", + "exportName": "TinyGridColumn", + "destructuring": true, + "version": "0.1.16" + }, { "componentName": "TinyNumeric", "package": "@opentiny/vue", diff --git a/packages/engine-cli/template/designer/public/mock/bundle.json b/packages/engine-cli/template/designer/public/mock/bundle.json index 64fbf4bf1b..9cd3cdf17d 100644 --- a/packages/engine-cli/template/designer/public/mock/bundle.json +++ b/packages/engine-cli/template/designer/public/mock/bundle.json @@ -10152,6 +10152,54 @@ } } }, + { + "icon": "grid", + "name": { + "zh_CN": "表格行" + }, + "component": "TinyGridColumn", + "description": "提供了非常强大数据表格功能,可以展示数据列表,可以对数据列表进行选择、编辑等", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyGridColumn" + }, + "group": "component", + "priority": 2, + "schema": { + "properties": [], + "events": {}, + "shortcuts": {}, + "contentMenu": { + "actions": ["create symbol"] + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": {}, + "contextMenu": { + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, { "name": { "zh_CN": "分页" diff --git a/packages/vue-generator/src/generator/vue/sfc/genSetupSFC.js b/packages/vue-generator/src/generator/vue/sfc/genSetupSFC.js index 23d2dcee36..a4914569e1 100644 --- a/packages/vue-generator/src/generator/vue/sfc/genSetupSFC.js +++ b/packages/vue-generator/src/generator/vue/sfc/genSetupSFC.js @@ -216,11 +216,10 @@ const generateSFCFile = (schema, componentsMap, config = {}, nextPage) => { export const genSFCWithDefaultPlugin = (schema, componentsMap, config = {}, nextPage) => { const { templateItemValidate = [], genTemplate = [], parseScript = [], genScript = {} } = config.hooks || {} - const defaultComponentHooks = [handleComponentNameHook, handleTinyIcon] + const defaultComponentHooks = [handleComponentNameHook, handleTinyIcon, handleTinyGrid] const defaultAttributeHook = [ handleSlotParams, - handleTinyGrid, handleJsxModelValueUpdate, handleConditionAttrHook, handleLoopAttrHook, diff --git a/packages/vue-generator/src/generator/vue/sfc/generateTemplate.js b/packages/vue-generator/src/generator/vue/sfc/generateTemplate.js index f4ceddd6c3..d1663171ba 100644 --- a/packages/vue-generator/src/generator/vue/sfc/generateTemplate.js +++ b/packages/vue-generator/src/generator/vue/sfc/generateTemplate.js @@ -10,6 +10,7 @@ import { import { generateTag, HTML_DEFAULT_VOID_ELEMENTS } from './generateTag' import { specialTypeHandler } from './generateAttribute' import { thisPropsBindRe, thisRegexp } from '@/utils' +import { getImportMap } from './parseImport' export const handleComponentNameHook = (optionData) => { const { componentName, schema } = optionData @@ -66,37 +67,60 @@ export const handleTinyIcon = (nameObj, globalHooks) => { delete nameObj.schema.props.name } -const handleTinyGridSlots = (value, globalHooks, config) => { - if (!Array.isArray(value)) { +const transformSlots = (slots) => { + if (!slots || typeof slots !== 'object') { + return [] + } + + const res = Object.entries(slots).map(([key, value]) => { + return { + componentName: 'template', + props: { + slot: { + name: key, + params: value?.params || '' + } + }, + children: value?.value + } + }) + + return res +} + +const transformColumnToChildren = (columns) => { + if (!Array.isArray(columns)) { return } - value.forEach((slotItem) => { - const name = slotItem.componentName + const res = columns.map((item) => { + const { slots, ...restItem } = item + + let children = [] - if (!name) { - return + if (slots) { + children = transformSlots(slots) } - if (slotItem.componentType === 'Block') { - const importPath = `${config.blockRelativePath}${name}${config.blockSuffix}` + return { + componentName: 'TinyGridColumn', + props: restItem, + children + } + }) - globalHooks.addImport(importPath, { - exportName: name, - componentName: name, - package: importPath - }) - } else if (name?.startsWith?.('Tiny')) { - globalHooks.addImport('@opentiny/vue', { - destructuring: true, - exportName: name.slice(4), - componentName: name, - package: '@opentiny/vue' - }) + return res +} + +// 检测 tinyGrid 表格列是否有插槽配置 +const columnHasSlots = (columns) => { + for (const columnItem of columns) { + if (columnItem.slots && typeof columnItem.slots === 'object' && Object.keys(columnItem.slots).length > 0) { + return true } + } - handleTinyGridSlots(slotItem.children, globalHooks, config) - }) + return false } export const handleTinyGrid = (schemaData, globalHooks, config) => { @@ -129,11 +153,26 @@ export const handleTinyGrid = (schemaData, globalHooks, config) => { value: name } } - - if (typeof item.slots === 'object') { - Object.values(item.slots).forEach((slotItem) => handleTinyGridSlots(slotItem?.value, globalHooks, config)) - } }) + + const hasSlots = columnHasSlots(props.columns) + + // 存在 slots,将表格列转化成 children 的配置 + if (hasSlots) { + schemaData.schema.children = schemaData.schema.children || [] + schemaData.schema.children.push(...transformColumnToChildren(props.columns)) + + // 解析 slot 中的 依赖 + const { pkgMap = {}, blockPkgMap = {} } = getImportMap(schemaData.schema, config.componentsMap, config) + + Object.entries({ ...pkgMap, ...blockPkgMap }).forEach(([key, value]) => { + value.forEach((valueItem) => { + globalHooks.addImport(key, valueItem) + }) + }) + + delete props.columns + } } /** diff --git a/packages/vue-generator/test/testcases/sfc/case01/componentsMap.json b/packages/vue-generator/test/testcases/sfc/case01/componentsMap.json index 2f62c77fbf..4afeb3a2ef 100644 --- a/packages/vue-generator/test/testcases/sfc/case01/componentsMap.json +++ b/packages/vue-generator/test/testcases/sfc/case01/componentsMap.json @@ -27,6 +27,13 @@ "version": "^3.10.0", "destructuring": true }, + { + "componentName": "TinyGridColumn", + "exportName": "GridColumn", + "package": "@opentiny/vue", + "version": "^3.10.0", + "destructuring": true + }, { "componentName": "TinyInput", "exportName": "Input", diff --git a/packages/vue-generator/test/testcases/sfc/case01/expected/FormTable.vue b/packages/vue-generator/test/testcases/sfc/case01/expected/FormTable.vue index e262db8ce5..ade1506a08 100644 --- a/packages/vue-generator/test/testcases/sfc/case01/expected/FormTable.vue +++ b/packages/vue-generator/test/testcases/sfc/case01/expected/FormTable.vue @@ -38,7 +38,26 @@
- + + + + + + + + + +
循环渲染:
@@ -72,6 +91,7 @@ import { Grid as TinyGrid, Input as TinyInput, Select as TinySelect, + GridColumn as TinyGridColumn, Switch as TinySwitch } from '@opentiny/vue' import { IconSearch, IconDel, iconHelpCircle, IconEdit } from '@opentiny/vue-icon' @@ -97,30 +117,6 @@ const { utils } = wrap(function () { return this })() const state = vue.reactive({ - columns6cio: [ - { type: 'index', width: 60, title: '' }, - { type: 'selection', width: 60 }, - { field: 'employees', title: '员工数', slots: { default: ({ row, rowIndex }, h) => } }, - { field: 'city', title: '城市' }, - { - title: '产品', - slots: { - default: ({ row }, h) => ( -
- -
- ) - } - }, - { - title: '操作', - slots: { - default: ({ row }, h) => ( - emit(eventArgs, row)}> - ) - } - } - ], IconPlusSquare: utils.IconPlusSquare(), theme: "{ 'id': 22, 'name': '@cloud/tinybuilder-theme-dark', 'description': '黑暗主题' }", companyName: '', diff --git a/packages/vue-generator/test/testcases/sfc/slotModelValue/expected/slotModelValueTest.vue b/packages/vue-generator/test/testcases/sfc/slotModelValue/expected/slotModelValueTest.vue index 7d5e5f083a..cda4839120 100644 --- a/packages/vue-generator/test/testcases/sfc/slotModelValue/expected/slotModelValueTest.vue +++ b/packages/vue-generator/test/testcases/sfc/slotModelValue/expected/slotModelValueTest.vue @@ -2,8 +2,8 @@