Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions packages/canvas/src/components/render/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ const { BROADCAST_CHANNEL } = constants
const { hyphenateRE } = utils
const customElements = {}

const transformJSX = (code) =>
transformSync(code, {
const transformJSX = (code) => {
const res = transformSync(code, {
plugins: [
[
babelPluginJSX,
Expand All @@ -46,6 +46,13 @@ const transformJSX = (code) =>
]
]
})
return (res.code || '')
.replace(/import \{.+\} from "vue";/, '')
.replace(/h\(_?resolveComponent\((.*?)\)/g, `h(this.getComponent($1)`)
.replace(/_?resolveComponent/g, 'h')
.replace(/_?createTextVNode\((.*?)\)/g, '$1')
.trim()
}

export const blockSlotDataMap = reactive({})

Expand Down Expand Up @@ -138,20 +145,25 @@ export const newFn = (...argv) => {
return new Fn(...argv)
}

const parseExpression = (data, scope, ctx) => {
const parseExpression = (data, scope, ctx, isJsx = false) => {
try {
if (data.value.indexOf('this.i18n') > -1) {
ctx.i18n = i18nHost.global.t
} else if (data.value.indexOf('t(') > -1) {
ctx.t = i18nHost.global.t
}

return newFn('$scope', `with($scope || {}) { return ${data.value} }`).call(ctx, {
const expression = isJsx ? transformJSX(data.value) : data.value
return newFn('$scope', `with($scope || {}) { return ${expression} }`).call(ctx, {
...ctx,
...scope,
slotScope: scope
})
} catch (err) {
// 解析抛出异常,则再尝试解析 JSX 语法。如果解析 JSX 语法仍然出现错误,isJsx 变量会确保不会再次递归执行解析
if (!isJsx) {
return parseExpression(data, scope, ctx, true)
}
return undefined
}
}
Expand Down Expand Up @@ -347,10 +359,6 @@ export const getComponent = (name) => {
const parseJSXFunction = (data, ctx) => {
try {
const newValue = transformJSX(data.value)
.code.replace(/import \{.+\} from "vue";/, '')
.replace(/h\(_?resolveComponent\((.*?)\)/g, `h(this.getComponent($1)`)
.replace(/_?resolveComponent/g, 'h')
.replace(/_?createTextVNode\((.*?)\)/g, '$1')
const fnInfo = parseFunctionString(newValue)
if (!fnInfo) throw Error('函数解析失败,请检查格式。示例:function fnName() { }')

Expand Down
2 changes: 1 addition & 1 deletion packages/common/component/MetaCodeEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export default {

watchEffect(() => {
const { modelValue, dataType } = props
const val = dataType ? modelValue?.value : modelValue
const val = dataType ? modelValue?.value || '' : modelValue
value.value = typeof val === 'string' ? val : JSON.stringify(val, null, 2)
})

Expand Down
22 changes: 11 additions & 11 deletions packages/common/js/ast.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/

import { parse, parseExpression } from '@babel/parser'
import generate from '@babel/generator'
Expand All @@ -24,7 +24,7 @@ export const insertName = (name, content) => content.replace(METHOD_REGEXP, `fun

export const removeName = (content) => content.replace(METHOD_REGEXP, 'function (')

export const string2Ast = (string = '') => parse(string, { sourceType: 'module', plugins: ['typescript'] })
export const string2Ast = (string = '') => parse(string, { sourceType: 'module', plugins: ['typescript', 'jsx'] })

export const ast2String = (ast) => generate(ast, { retainLines: true }).code

Expand Down
46 changes: 45 additions & 1 deletion packages/design-core/public/mock/bundle.json
Original file line number Diff line number Diff line change
Expand Up @@ -10910,7 +10910,7 @@
"zh_CN": "基础信息"
},
"collapse": {
"number": 6,
"number": 10,
"text": {
"zh_CN": "显示更多"
}
Expand Down Expand Up @@ -10985,6 +10985,28 @@
},
"labelPosition": "left"
},
{
"property": "render-content",
"label": {
"text": {
"zh_CN": "渲染函数"
}
},
"required": false,
"readOnly": false,
"disabled": false,
"cols": 12,
"widget": {
"component": "MetaInput",
Comment thread
hexqi marked this conversation as resolved.
"props": {
"disabled": true,
"placeholder": "请使用变量绑定来绑定函数"
}
},
"description": {
"zh_CN": "树节点的内容区的渲染函数"
}
},
{
"property": "icon-trigger-click-node",
"label": {
Expand Down Expand Up @@ -11532,6 +11554,28 @@
"zh_CN": "显示的内容,也可以通过 slot#content 传入 DOM"
}
},
{
"property": "render-content",
"label": {
"text": {
"zh_CN": "渲染函数"
}
},
"required": false,
"readOnly": false,
"disabled": false,
"cols": 12,
"widget": {
"component": "MetaInput",
"props": {
"disabled": true,
"placeholder": "请使用变量绑定来绑定函数"
}
},
"description": {
"zh_CN": "自定义渲染函数,返回需要渲染的节点内容"
}
},
{
"property": "modelValue",
"label": {
Expand Down