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 @@