diff --git a/.github/workflows/push-check.yml b/.github/workflows/push-check.yml
index 7f0d4ed41..5abf1018f 100644
--- a/.github/workflows/push-check.yml
+++ b/.github/workflows/push-check.yml
@@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
- node-version: 16
+ node-version: 18
- name: Install pnpm
run: npm i -g pnpm
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 851c9a155..28a861d55 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
@@ -1690,7 +1690,7 @@
],
"fileName": "createVm",
"meta": {
- "id": 1977,
+ "id": "NTJ4MjvqoVj8OVsc",
"parentId": "0",
"group": "staticPages",
"occupier": {
diff --git a/packages/blockToWebComponentTemplate/package.json b/packages/blockToWebComponentTemplate/package.json
index c857539ae..4124d3074 100644
--- a/packages/blockToWebComponentTemplate/package.json
+++ b/packages/blockToWebComponentTemplate/package.json
@@ -32,9 +32,9 @@
"dependencies": {
"@opentiny/tiny-engine-i18n-host": "workspace:*",
"@opentiny/tiny-engine-webcomponent-core": "workspace:*",
- "@opentiny/vue": "~3.11.0",
- "@opentiny/vue-icon": "~3.11.0",
- "@opentiny/vue-theme": "~3.11.0",
+ "@opentiny/vue": "~3.14.0",
+ "@opentiny/vue-icon": "~3.14.0",
+ "@opentiny/vue-theme": "~3.14.0",
"@vue/shared": "^3.3.11",
"vue": "^3.4.15",
"vue-i18n": "^9.9.0"
diff --git a/packages/blockToWebComponentTemplate/vite.config.js b/packages/blockToWebComponentTemplate/vite.config.js
index 446d0050c..ddbf655c3 100644
--- a/packages/blockToWebComponentTemplate/vite.config.js
+++ b/packages/blockToWebComponentTemplate/vite.config.js
@@ -43,7 +43,7 @@ export default defineConfig(({ command, mode }) => {
}
const vuePluginConfig = {}
- const styleLinks = ['https://npm.onmicrosoft.cn/@opentiny/vue-theme@3.11/index.css']
+ const styleLinks = ['https://npm.onmicrosoft.cn/@opentiny/vue-theme@3.14/index.css']
config.publicDir = false
diff --git a/packages/builtinComponent/package.json b/packages/builtinComponent/package.json
index 92ff6b3ee..f25d3a77d 100644
--- a/packages/builtinComponent/package.json
+++ b/packages/builtinComponent/package.json
@@ -20,12 +20,14 @@
"preview": "vite preview"
},
"dependencies": {
- "@opentiny/vue": "~3.10.0",
"vite-plugin-css-injected-by-js": "^3.3.1"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"vite": "^4.5.0"
+ },
+ "peerDependencies": {
+ "vue": "^3.4.15"
}
}
diff --git a/packages/canvas/package.json b/packages/canvas/package.json
index 2725df3c3..962ac659c 100644
--- a/packages/canvas/package.json
+++ b/packages/canvas/package.json
@@ -32,9 +32,6 @@
"@opentiny/tiny-engine-i18n-host": "workspace:*",
"@opentiny/tiny-engine-utils": "workspace:*",
"@opentiny/tiny-engine-webcomponent-core": "workspace:*",
- "@opentiny/vue": "~3.10.0",
- "@opentiny/vue-icon": "~3.10.0",
- "@opentiny/vue-renderless": "~3.10.0",
"@vue/babel-plugin-jsx": "1.1.1",
"@vue/shared": "^3.3.4",
"@vueuse/core": "^9.6.0"
@@ -46,6 +43,9 @@
"vite": "^4.3.7"
},
"peerDependencies": {
+ "@opentiny/vue": "^3.14.0",
+ "@opentiny/vue-icon": "^3.14.0",
+ "@opentiny/vue-renderless": "^3.14.0",
"vue": "^3.4.15",
"vue-i18n": "^9.9.0"
}
diff --git a/packages/canvas/src/components/container/CanvasAction.vue b/packages/canvas/src/components/container/CanvasAction.vue
index 5008e1c46..24de3beeb 100644
--- a/packages/canvas/src/components/container/CanvasAction.vue
+++ b/packages/canvas/src/components/container/CanvasAction.vue
@@ -27,14 +27,46 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
@@ -540,11 +572,12 @@ export default {
height: 100%;
background: var(--ti-lowcode-canvas-hover-line-in-bg-color);
}
- &.forbid {
- width: 100%;
- height: 100%;
+ &.forbidden:not(.in) {
background: var(--ti-lowcode-canvas-hover-line-forbid-bg-color);
}
+ &.forbidden.in {
+ background: var(--ti-lowcode-canvas-hover-line-in-forbid-bg-color);
+ }
}
.choose-slots {
diff --git a/packages/canvas/src/components/container/CanvasContainer.vue b/packages/canvas/src/components/container/CanvasContainer.vue
index 21abc307f..c110bb7dd 100644
--- a/packages/canvas/src/components/container/CanvasContainer.vue
+++ b/packages/canvas/src/components/container/CanvasContainer.vue
@@ -6,7 +6,7 @@
:windowGetClickEventTarget="target"
:resize="canvasState.type === 'absolute'"
@select-slot="selectSlot"
- @setting="settingModle"
+ @setting="settingModel"
>
@@ -55,7 +55,8 @@ import {
initCanvas,
clearLineState,
querySelectById,
- getCurrent
+ getCurrent,
+ canvasApi
} from './container'
export default {
@@ -71,7 +72,7 @@ export default {
const insertPanel = ref(null)
const insertPosition = ref(false)
const loading = computed(() => useCanvas().isLoading())
- let showSettingModle = ref(false)
+ let showSettingModel = ref(false)
let target = ref(null)
const setCurrentNode = async (event) => {
@@ -105,6 +106,8 @@ export default {
}
}
+ useCanvas().initCanvasApi(canvasApi)
+
const beforeCanvasReady = () => {
if (iframe.value) {
const win = iframe.value.contentWindow
@@ -119,7 +122,6 @@ export default {
iframeMonitoring()
initCanvas({ emit, renderer: detail, iframe: iframe.value, controller: props.controller })
- useCanvas().renderer.value = { ...detail, ...window.canvasApi }
const doc = iframe.value.contentDocument
const win = iframe.value.contentWindow
@@ -179,8 +181,8 @@ export default {
}
}
// 设置弹窗
- const settingModle = () => {
- showSettingModle.value = true
+ const settingModel = () => {
+ showSettingModel.value = true
}
const updateI18n = (message) => {
@@ -237,9 +239,9 @@ export default {
canvasState,
insertComponent,
insertPanel,
- settingModle,
+ settingModel,
target,
- showSettingModle,
+ showSettingModel,
insertPosition,
loading
}
diff --git a/packages/canvas/src/components/container/CanvasFooter.vue b/packages/canvas/src/components/container/CanvasFooter.vue
index 84293a9b9..6377cdba3 100644
--- a/packages/canvas/src/components/container/CanvasFooter.vue
+++ b/packages/canvas/src/components/container/CanvasFooter.vue
@@ -17,7 +17,7 @@ export default {
props: {
data: {
type: Array,
- default: []
+ default: () => []
}
},
emits: ['click']
@@ -44,37 +44,23 @@ export default {
li {
width: unset !important;
background: var(--ti-lowcode-breadcrumb-bg);
- a {
+ .label {
padding: 0 3px 0 16px;
border-top: 0;
color: var(--ti-lowcode-breadcrumb-color);
transition: 0.3s;
- &::after {
- display: inline-block;
- right: -6px;
- border-left: 6px solid var(--ti-lowcode-breadcrumb-bg);
- transition: 0.3s;
- }
- &::before {
- display: inline-block;
- right: -7px;
- left: unset;
- border-left: 6px solid var(--ti-lowcode-breadcrumb-icon-color);
- transition: 0.3s;
- z-index: 1;
- }
&:hover {
- background: var(--ti-lowcode-breadcrumb-hover-bg);
+ cursor: pointer;
&::after {
- border-left-color: var(--ti-lowcode-breadcrumb-hover-bg);
+ border-left-color: var(--ti-steps-advanced-li-hover-bg-color);
}
}
}
- &:last-child a {
+ &:last-child .label {
border-right: 0px solid var(--ti-lowcode-breadcrumb-color);
border-radius: 0;
}
- &:first-child a {
+ &:first-child .label {
border-right: 0px solid var(--ti-lowcode-breadcrumb-color);
border-radius: 0;
border-left: unset;
diff --git a/packages/canvas/src/components/container/container.js b/packages/canvas/src/components/container/container.js
index 581282576..aac3f21e0 100644
--- a/packages/canvas/src/components/container/container.js
+++ b/packages/canvas/src/components/container/container.js
@@ -20,15 +20,16 @@ import {
NODE_LOOP
} from '../common'
import { useCanvas, useLayout, useResource, useTranslate } from '@opentiny/tiny-engine-controller'
+import { isVsCodeEnv } from '@opentiny/tiny-engine-controller/js/environments'
+import Builtin from '../builtin/builtin.json'
+
export const POSITION = Object.freeze({
TOP: 'top',
BOTTOM: 'bottom',
LEFT: 'left',
RIGHT: 'right',
- IN: 'in',
- FORBID: 'forbid'
+ IN: 'in'
})
-import { isVsCodeEnv } from '@opentiny/tiny-engine-controller/js/environments'
const initialDragState = {
keydown: false,
@@ -98,6 +99,7 @@ const initialLineState = {
width: 0,
left: 0,
position: '',
+ forbidden: false,
id: '',
config: null,
doc: null
@@ -320,19 +322,19 @@ export const scrollToNode = (element) => {
if (element) {
const container = getDocument().documentElement
const { clientWidth, clientHeight } = container
- const { x, y, width, height } = element.getBoundingClientRect()
+ const { left, right, top, bottom, width, height } = element.getBoundingClientRect()
const option = {}
- if (x < 0) {
- option.left = container.scrollLeft + x - SCROLL_MARGIN
- } else if (x > clientWidth) {
- option.left = x + width - clientWidth + SCROLL_MARGIN
+ if (right < 0) {
+ option.left = container.scrollLeft + left - SCROLL_MARGIN
+ } else if (left > clientWidth) {
+ option.left = container.scrollLeft + left - clientWidth + width + SCROLL_MARGIN
}
- if (y < 0) {
- option.top = container.scrollTop + y - SCROLL_MARGIN
- } else if (y > clientHeight) {
- option.top = y + height - clientHeight + SCROLL_MARGIN
+ if (bottom < 0) {
+ option.top = container.scrollTop + top - SCROLL_MARGIN
+ } else if (top > clientHeight) {
+ option.top = container.scrollTop + top - clientHeight + height + SCROLL_MARGIN
}
if (typeof option.left === 'number' || typeof option.top === 'number') {
@@ -416,6 +418,23 @@ export const allowInsert = (configure = hoverState.configure || {}, data = dragS
return flag
}
+const isAncestor = (ancestor, descendant) => {
+ const ancestorId = typeof ancestor === 'string' ? ancestor : ancestor.id
+ let descendantId = typeof descendant === 'string' ? descendant : descendant.id
+
+ while (descendantId) {
+ const { parent } = getNode(descendantId, true) || {}
+
+ if (parent.id === ancestorId) {
+ return true
+ }
+
+ descendantId = parent.id
+ }
+
+ return false
+}
+
// 获取位置信息,返回状态
const lineAbs = 20
const getPosLine = (rect, configure) => {
@@ -423,6 +442,7 @@ const getPosLine = (rect, configure) => {
const yAbs = Math.min(lineAbs, rect.height / 3)
const xAbs = Math.min(lineAbs, rect.width / 3)
let type
+ let forbidden = false
if (mousePos.y < rect.top + yAbs) {
type = POSITION.TOP
@@ -433,12 +453,21 @@ const getPosLine = (rect, configure) => {
} else if (mousePos.x > rect.right - xAbs) {
type = POSITION.RIGHT
} else if (configure.isContainer) {
- type = allowInsert() ? POSITION.IN : POSITION.FORBID
+ type = POSITION.IN
+ if (!allowInsert()) {
+ forbidden = true
+ }
} else {
type = POSITION.BOTTOM
}
- return { type }
+ // 如果被拖拽的节点不是新增的,并且是放置的节点的祖先节点,则禁止插入
+ const draggedId = dragState.data?.id
+ if (draggedId && isAncestor(draggedId, lineState.id)) {
+ forbidden = true
+ }
+
+ return { type, forbidden }
}
const isBodyEl = (element) => element.nodeName === 'BODY'
@@ -484,20 +513,24 @@ const setHoverRect = (element, data) => {
const childRect = getRect(childEle)
const { left, height, top, width } = childRect
const { x, y } = getOffset(childEle)
+ const posLine = getPosLine(childRect, lineState.configure)
Object.assign(lineState, {
width: width * scale,
height: height * scale,
top: top * scale + y - siteCanvasRect.y,
left: left * scale + x - siteCanvasRect.x,
- position: canvasState.type === 'absolute' || getPosLine(childRect, lineState.configure).type
+ position: canvasState.type === 'absolute' || posLine.type,
+ forbidden: posLine.forbidden
})
} else {
+ const posLine = getPosLine(rect, configure)
Object.assign(lineState, {
width: width * scale,
height: height * scale,
top: top * scale + y - siteCanvasRect.y,
left: left * scale + x - siteCanvasRect.x,
- position: canvasState.type === 'absolute' || getPosLine(rect, configure).type
+ position: canvasState.type === 'absolute' || posLine.type,
+ forbidden: posLine.forbidden
})
}
@@ -670,13 +703,12 @@ export const copyNode = (id) => {
export const onMouseUp = () => {
const { draging, data } = dragState
- const { position } = lineState
+ const { position, forbidden } = lineState
const absolute = canvasState.type === 'absolute'
const sourceId = data?.id
const lineId = lineState.id
- const allowInsert = position !== POSITION.FORBID
- if (draging && allowInsert) {
+ if (draging && !forbidden) {
const { parent, node } = getNode(lineId, true) || {} // target
const targetNode = { parent, node, data: toRaw(data) }
@@ -823,6 +855,49 @@ export const canvasDispatch = (name, data, doc = getDocument()) => {
doc.dispatchEvent(new CustomEvent(name, data))
}
+export const canvasApi = {
+ dragStart,
+ updateRect,
+ getContext,
+ getNodePath,
+ dragMove,
+ setLocales,
+ setState,
+ deleteState,
+ getRenderer,
+ clearSelect,
+ selectNode,
+ hoverNode,
+ insertNode,
+ removeNode,
+ addComponent,
+ setPageCss,
+ addScript,
+ addStyle,
+ getNode,
+ getCurrent,
+ setSchema,
+ setUtils,
+ updateUtils,
+ deleteUtils,
+ getSchema,
+ setI18n,
+ getCanvasType,
+ setCanvasType,
+ setProps,
+ setGlobalState,
+ getGlobalState,
+ getDocument,
+ canvasDispatch,
+ Builtin,
+ setDataSourceMap: (...args) => {
+ return canvasState.renderer.setDataSourceMap(...args)
+ },
+ getDataSourceMap: (...args) => {
+ return canvasState.renderer.getDataSourceMap(...args)
+ }
+}
+
export const initCanvas = ({ renderer, iframe, emit, controller }) => {
const currentSchema = getSchema()
diff --git a/packages/canvas/src/components/render/RenderMain.js b/packages/canvas/src/components/render/RenderMain.js
index 97040fc15..6081d487e 100644
--- a/packages/canvas/src/components/render/RenderMain.js
+++ b/packages/canvas/src/components/render/RenderMain.js
@@ -18,8 +18,6 @@ import { generateFunction } from '@opentiny/tiny-engine-controller/utils'
import renderer, { parseData, setConfigure, setController, globalNotify, isStateAccessor } from './render'
import { getNode as getNodeById, clearNodes, getRoot, setContext, getContext, setCondition, context } from './context'
import CanvasEmpty from './CanvasEmpty.vue'
-import { getCurrent, setLocales, updateRect, addStyle, addScript, canvasDispatch } from '../container/container'
-import Builtin from '../builtin/builtin.json'
const { BROADCAST_CHANNEL } = constants
@@ -426,17 +424,3 @@ export const api = {
setDataSourceMap,
setGlobalState
}
-
-const canvasApi = {
- getCurrent,
- setLocales,
- getNodeById: getNode,
- updateRect,
- addStyle,
- addScript,
- canvasDispatch
-}
-
-window.api = api
-window.canvasApi = canvasApi
-window.Builtin = Builtin
diff --git a/packages/canvas/src/components/render/render.js b/packages/canvas/src/components/render/render.js
index cb9438035..0dbcf8b12 100644
--- a/packages/canvas/src/components/render/render.js
+++ b/packages/canvas/src/components/render/render.js
@@ -598,6 +598,20 @@ const getLoopScope = ({ scope, index, item, loopArgs }) => {
}
}
+const injectPlaceHolder = (componentName, children) => {
+ const isEmptyArr = Array.isArray(children) && !children.length
+
+ if (configure[componentName]?.isContainer && (!children || isEmptyArr)) {
+ return [
+ {
+ componentName: 'CanvasPlaceholder'
+ }
+ ]
+ }
+
+ return children
+}
+
const renderGroup = (children, scope, parent) => {
return children.map?.((schema) => {
const { componentName, children, loop, loopArgs, condition, id } = schema
@@ -617,10 +631,14 @@ const renderGroup = (children, scope, parent) => {
return null
}
+ const renderChildren = injectPlaceHolder(componentName, children)
+
return h(
getComponent(componentName),
getBindProps(schema, mergeScope),
- Array.isArray(children) ? renderSlot(children, mergeScope, schema) : parseData(children, mergeScope)
+ Array.isArray(renderChildren)
+ ? renderSlot(renderChildren, mergeScope, schema)
+ : parseData(renderChildren, mergeScope)
)
}
@@ -628,19 +646,9 @@ const renderGroup = (children, scope, parent) => {
})
}
-const ContainerComponent = ['CanvasCol', 'CanvasRow', 'CanvasRowColContainer']
-
const getChildren = (schema, mergeScope) => {
const { componentName, children } = schema
- let renderChildren = children
-
- if (ContainerComponent.includes(componentName) && !renderChildren?.length) {
- renderChildren = [
- {
- componentName: 'CanvasPlaceholder'
- }
- ]
- }
+ const renderChildren = injectPlaceHolder(componentName, children)
const component = getComponent(componentName)
const isNative = typeof component === 'string'
diff --git a/packages/canvas/src/components/render/runner.js b/packages/canvas/src/components/render/runner.js
index bf70d32ff..93d9902db 100644
--- a/packages/canvas/src/components/render/runner.js
+++ b/packages/canvas/src/components/render/runner.js
@@ -26,73 +26,77 @@ const dispatch = (name, data) => {
window.parent.document.dispatchEvent(new CustomEvent(name, data))
}
-dispatch('beforeCanvasReady')
-
-TinyI18nHost.lowcode = lowcode
-
-// 目前先兼容老区块发布的代码,后期区块发布整改后再删除
-window.React = {}
-window.React.createElement = Vue.h
-
-// 不能采用new Proxy代理Vue的方案,在编译后的vue会报错警告,采用一下方案扩展用于注入一些区块加载逻辑
-window.Vue = {
- ...Vue,
- resolveComponent(...args) {
- // 此处先执行vue内部的解析组件的方法,如果可以拿到组件对象则直接返回,反之则去注册区块
- const component = Vue.resolveComponent(args[0])
- if (component && typeof component === 'string') {
- return getComponent(capitalize(camelize(args[0])))
- } else {
- return component
- }
- },
- // renderSlot方法第三个参数是作用域插槽传递的数据,格式{ data: vue.unref(state).componentData }
- renderSlot(...args) {
- // 获取当前vue的实例
- const instance = Vue.getCurrentInstance()
-
- // 获取当前区块名称
- const blockName = instance.attrs.dataTag
-
- const [, slotName, slotData] = args
-
- // 如果是作用域插槽,则获取作用域插槽传递过来的参数
- if (slotData) {
- if (blockSlotDataMap[blockName]) {
- blockSlotDataMap[blockName][slotName] = slotData
+const initRenderContext = () => {
+ dispatch('beforeCanvasReady')
+
+ TinyI18nHost.lowcode = lowcode
+
+ // 目前先兼容老区块发布的代码,后期区块发布整改后再删除
+ window.React = {}
+ window.React.createElement = Vue.h
+
+ // 不能采用new Proxy代理Vue的方案,在编译后的vue会报错警告,采用一下方案扩展用于注入一些区块加载逻辑
+ window.Vue = {
+ ...Vue,
+ resolveComponent(...args) {
+ // 此处先执行vue内部的解析组件的方法,如果可以拿到组件对象则直接返回,反之则去注册区块
+ const component = Vue.resolveComponent(args[0])
+ if (component && typeof component === 'string') {
+ return getComponent(capitalize(camelize(args[0])))
} else {
- blockSlotDataMap[blockName] = { [slotName]: slotData }
+ return component
+ }
+ },
+ // renderSlot方法第三个参数是作用域插槽传递的数据,格式{ data: vue.unref(state).componentData }
+ renderSlot(...args) {
+ // 获取当前vue的实例
+ const instance = Vue.getCurrentInstance()
+
+ // 获取当前区块名称
+ const blockName = instance.attrs.dataTag
+
+ const [, slotName, slotData] = args
+
+ // 如果是作用域插槽,则获取作用域插槽传递过来的参数
+ if (slotData) {
+ if (blockSlotDataMap[blockName]) {
+ blockSlotDataMap[blockName][slotName] = slotData
+ } else {
+ blockSlotDataMap[blockName] = { [slotName]: slotData }
+ }
+ }
+
+ /**
+ * vue源码中的renderSlot会忽略default插槽的名称,所以这里必须手动添加args第三个参数的name值
+ * vue源码如右所示:if (name !== 'default') props.name = name; return createVNode('slot', props, fallback && fallback());
+ **/
+ if (slotName === 'default') {
+ args[2] = args[2] || {}
+ args[2].name = slotName
}
+
+ return Vue.renderSlot(...args)
}
+ }
- /**
- * vue源码中的renderSlot会忽略default插槽的名称,所以这里必须手动添加args第三个参数的name值
- * vue源码如右所示:if (name !== 'default') props.name = name; return createVNode('slot', props, fallback && fallback());
- **/
- if (slotName === 'default') {
- args[2] = args[2] || {}
- args[2].name = slotName
+ window.VueI18n = VueI18n
+ window.TinyVue = TinyVue
+ window.TinyVueIcon = TinyVueIcon
+ window.TinyWebcomponentCore = TinyWebcomponentCore
+ window.TinyI18nHost = TinyI18nHost
+ window.TinyLowcodeComponent = {}
+ window.TinyComponentLibs = {}
+
+ Object.entries(TinyVue).forEach(([_key, component]) => {
+ const { name } = component
+ if (name) {
+ window.TinyLowcodeComponent[name] = component
}
+ })
- return Vue.renderSlot(...args)
- }
+ document.addEventListener('updateDependencies', updateDependencies)
}
-window.VueI18n = VueI18n
-window.TinyVue = TinyVue
-window.TinyVueIcon = TinyVueIcon
-window.TinyWebcomponentCore = TinyWebcomponentCore
-window.TinyI18nHost = TinyI18nHost
-window.TinyLowcodeComponent = {}
-window.TinyComponentLibs = {}
-
-Object.entries(TinyVue).forEach(([_key, component]) => {
- const { name } = component
- if (name) {
- window.TinyLowcodeComponent[name] = component
- }
-})
-
let App = null
const renderer = {
@@ -129,6 +133,7 @@ const create = () => {
}
export const createRender = (config) => {
+ initRenderContext()
const { dslMode, canvasOptions } = config
const { styles = [], scripts = [] } = canvasOptions[dslMode]
const { styles: thirdStyles = [], scripts: thirdScripts = [] } = window.thirdPartyDeps || {}
@@ -138,5 +143,3 @@ export const createRender = (config) => {
...scripts.map((src) => addScript(src)).concat([...thirdStyles, ...styles].map((src) => addStyle(src)))
]).finally(create)
}
-
-document.addEventListener('updateDependencies', updateDependencies)
diff --git a/packages/canvas/src/index.js b/packages/canvas/src/index.js
index fcf1d07ee..b61e634b9 100644
--- a/packages/canvas/src/index.js
+++ b/packages/canvas/src/index.js
@@ -10,93 +10,7 @@
*
*/
-import CanvasContainer from './components/container/CanvasContainer.vue'
-import CanvasAction from './components/container/CanvasAction.vue'
-import CanvasDragItem from './components/container/CanvasDragItem.vue'
-import CanvasFooter from './components/container/CanvasFooter.vue'
-import CanvasResize from './components/container/CanvasResize.vue'
-import Builtin from './components/builtin/builtin.json'
-import RenderMain, { api as renderApi } from './components/render/RenderMain'
-import { createRender } from './components/render/runner'
-import {
- dragStart,
- updateRect,
- getContext,
- getNodePath,
- dragMove,
- setLocales,
- setState,
- deleteState,
- getRenderer,
- clearSelect,
- selectNode,
- hoverNode,
- insertNode,
- removeNode,
- addComponent,
- setPageCss,
- addScript,
- addStyle,
- getNode,
- getCurrent,
- setSchema,
- setUtils,
- updateUtils,
- deleteUtils,
- getSchema,
- setI18n,
- getCanvasType,
- setCanvasType,
- setProps,
- setGlobalState,
- getGlobalState,
- getDocument,
- canvasDispatch
-} from './components/container/container'
-
-export {
- CanvasContainer,
- CanvasAction,
- CanvasFooter,
- CanvasDragItem,
- CanvasResize,
- RenderMain,
- renderApi,
- Builtin,
- dragStart,
- dragMove,
- updateRect,
- getContext,
- getNodePath,
- getNode,
- getCurrent,
- setSchema,
- setUtils,
- updateUtils,
- deleteUtils,
- getSchema,
- setLocales,
- setState,
- deleteState,
- setI18n,
- getRenderer,
- clearSelect,
- selectNode,
- insertNode,
- removeNode,
- hoverNode,
- addComponent,
- setPageCss,
- addScript,
- addStyle,
- getCanvasType,
- setCanvasType,
- setProps,
- setGlobalState,
- getGlobalState,
- getDocument,
- canvasDispatch,
- createRender
-}
-
-export default CanvasContainer
+export { default as CanvasContainer } from './components/container/CanvasContainer.vue'
+export { default as CanvasDragItem } from './components/container/CanvasDragItem.vue'
+export { default as CanvasFooter } from './components/container/CanvasFooter.vue'
+export { createRender } from './components/render/runner'
diff --git a/packages/common/component/BlockDeployDialog.vue b/packages/common/component/BlockDeployDialog.vue
index f5aa6c96c..33aaf918e 100644
--- a/packages/common/component/BlockDeployDialog.vue
+++ b/packages/common/component/BlockDeployDialog.vue
@@ -49,7 +49,7 @@
:modal="false"
:fullscreen="true"
:append-to-body="true"
- title="Schema 本地与线上差异"
+ title="Schema 线上与本地差异"
>
{
- const pageSchema = JSON.parse(state.newCode)
- setSchema(pageSchema)
-
- close()
+ if (!state.newCode) {
+ close()
+ return
+ }
+ try {
+ const pageSchema = JSON.parse(state.newCode)
+ const setSchema = useCanvas().canvasApi.value.setSchema
+ setSchema?.({ ...pageSchema, componentName: COMPONENT_NAME.Block })
+ close()
+ } catch (err) {
+ useNotify({
+ type: 'error',
+ message: '代码静态检查有错误,请先修改后再保存'
+ })
+ }
}
return {
diff --git a/packages/common/component/BlockLinkEvent.vue b/packages/common/component/BlockLinkEvent.vue
index cfc162415..5df20af68 100644
--- a/packages/common/component/BlockLinkEvent.vue
+++ b/packages/common/component/BlockLinkEvent.vue
@@ -21,7 +21,6 @@ import { capitalize } from '@vue/shared'
import { extend } from '@opentiny/vue-renderless/common/object'
import { Input as TinyInput, Form as TinyForm, FormItem as TinyFormItem, Popover as TinyPopover } from '@opentiny/vue'
import { useLayout, useModal, useCanvas, useBlock } from '@opentiny/tiny-engine-controller'
-import { getSchema, getCurrent } from '@opentiny/tiny-engine-canvas'
export default {
components: {
@@ -38,7 +37,8 @@ export default {
const { pageState } = useCanvas()
const { addBlockEvent, removeEventLink, getCurrentBlock, appendEventEmit } = useBlock()
const { PLUGIN_NAME, activePlugin } = useLayout()
- const { schema } = getSchema()
+
+ const { schema } = useCanvas().canvasApi.value?.getSchema?.() || {}
const events = schema?.events || []
const eventsList = Object.entries(events).map(([key, value]) => {
return {
@@ -88,7 +88,7 @@ export default {
const {
schema: { id, componentName }
- } = getCurrent()
+ } = useCanvas().canvasApi.value?.getCurrent?.() || {}
const newEvent = extend(true, {}, data.metaEvent, {
linked: {
@@ -117,7 +117,7 @@ export default {
const editEvent = (item, data) => {
const {
schema: { id, componentName }
- } = getCurrent()
+ } = useCanvas().canvasApi.value?.getCurrent?.() || {}
const oldEventName = data.linkedEventName
diff --git a/packages/common/component/BlockLinkField.vue b/packages/common/component/BlockLinkField.vue
index 95d2a2bb1..a7a838430 100644
--- a/packages/common/component/BlockLinkField.vue
+++ b/packages/common/component/BlockLinkField.vue
@@ -22,7 +22,6 @@ import { reactive, computed } from 'vue'
import { extend } from '@opentiny/vue-renderless/common/object'
import { Input as TinyInput, Popover as TinyPopover } from '@opentiny/vue'
import { useLayout, useModal, useCanvas, useBlock, useHistory } from '@opentiny/tiny-engine-controller'
-import { getSchema, getCurrent } from '@opentiny/tiny-engine-canvas'
export default {
components: {
@@ -36,10 +35,10 @@ export default {
},
setup(props) {
const { confirm } = useModal()
- const { pageState } = useCanvas()
+ const { pageState, canvasApi } = useCanvas()
const { addBlockProperty, removePropertyLink, getCurrentBlock, editBlockProperty } = useBlock()
const { PLUGIN_NAME, activePlugin } = useLayout()
- const { schema } = getSchema()
+ const { schema } = canvasApi.value.getSchema?.() || {}
const state = reactive({
newPropertyName: ''
@@ -68,7 +67,7 @@ export default {
exec() {
const {
schema: { id, componentName }
- } = getCurrent()
+ } = canvasApi.value?.getCurrent?.() || {}
const newProperty = extend(true, {}, property, {
property: state.newPropertyName || `${property.property}${id}`,
linked: {
@@ -87,7 +86,7 @@ export default {
const editProperty = (property) => {
const {
schema: { id, componentName }
- } = getCurrent()
+ } = canvasApi.value?.getCurrent?.() || {}
// 如果之前有关联关系,则需要去除关联
if (props.data?.linked) {
diff --git a/packages/common/component/LifeCycles.vue b/packages/common/component/LifeCycles.vue
index a608d0a81..c7abdcd28 100644
--- a/packages/common/component/LifeCycles.vue
+++ b/packages/common/component/LifeCycles.vue
@@ -78,9 +78,8 @@
diff --git a/packages/common/index.js b/packages/common/index.js
index cab3818fe..2fcb94fcc 100644
--- a/packages/common/index.js
+++ b/packages/common/index.js
@@ -79,6 +79,7 @@ import BlockDeployDialog from './component/BlockDeployDialog.vue'
import ProgressBar from './component/ProgressBar.vue'
import MetaButtonGroup from './component/MetaButtonGroup.vue'
import MetaTableColumns from './component/MetaTableColumns.vue'
+import SearchEmpty from './component/SearchEmpty.vue'
import i18n, { i18nKeyMaps } from '@opentiny/tiny-engine-controller/js/i18n'
@@ -145,7 +146,8 @@ export const MetaComponents = {
MetaIpSection,
MetaRelatedEditor,
MetaRelatedColumns,
- MetaTableColumns
+ MetaTableColumns,
+ SearchEmpty
}
export {
@@ -206,5 +208,6 @@ export {
BindI18n,
BlockDeployDialog,
ProgressBar,
- MetaTableColumns
+ MetaTableColumns,
+ SearchEmpty
}
diff --git a/packages/common/package.json b/packages/common/package.json
index 1c7016030..a2ced557c 100644
--- a/packages/common/package.json
+++ b/packages/common/package.json
@@ -31,9 +31,6 @@
"@opentiny/tiny-engine-controller": "workspace:*",
"@opentiny/tiny-engine-http": "workspace:*",
"@opentiny/tiny-engine-utils": "workspace:*",
- "@opentiny/vue": "~3.10.0",
- "@opentiny/vue-icon": "~3.10.0",
- "@opentiny/vue-renderless": "~3.10.0",
"@vue/shared": "^3.3.4",
"monaco-editor": "0.33.0",
"prettier": "2.7.1",
@@ -45,6 +42,9 @@
"vite": "^4.3.7"
},
"peerDependencies": {
+ "@opentiny/vue": "^3.14.0",
+ "@opentiny/vue-icon": "^3.14.0",
+ "@opentiny/vue-renderless": "^3.14.0",
"vue": "^3.4.15"
}
}
diff --git a/packages/controller/package.json b/packages/controller/package.json
index e5f5ed47a..c3eab01eb 100644
--- a/packages/controller/package.json
+++ b/packages/controller/package.json
@@ -38,9 +38,6 @@
"@opentiny/tiny-engine-http": "workspace:*",
"@opentiny/tiny-engine-i18n-host": "workspace:*",
"@opentiny/tiny-engine-utils": "workspace:*",
- "@opentiny/vue": "~3.10.0",
- "@opentiny/vue-locale": "~3.10.0",
- "@opentiny/vue-renderless": "~3.10.0",
"@vue/shared": "^3.3.4",
"css-tree": "^2.3.1",
"eslint-linter-browserify": "8.57.0",
@@ -53,6 +50,9 @@
"vite": "^4.3.7"
},
"peerDependencies": {
+ "@opentiny/vue": "^3.14.0",
+ "@opentiny/vue-locale": "^3.14.0",
+ "@opentiny/vue-renderless": "^3.14.0",
"vue": "^3.4.15",
"vue-i18n": "^9.9.0"
}
diff --git a/packages/controller/src/useBlock.js b/packages/controller/src/useBlock.js
index 0aaaf71bb..e871b9c1c 100644
--- a/packages/controller/src/useBlock.js
+++ b/packages/controller/src/useBlock.js
@@ -278,7 +278,7 @@ const initBlock = async (block = {}, _langs = {}, isEdit) => {
// 把区块的schema传递给画布
await resetBlockCanvasState({ pageSchema: getBlockPageSchema(block) })
// 这一步操作很重要,让区块管理面板和画布共同维护同一份区块schema
- block.content = useCanvas().renderer.value?.getSchema()
+ block.content = useCanvas().canvasApi.value?.getSchema()
setCurrentBlock(block)
setBreadcrumbBlock([block[nameCn] || block.label], block.histories)
@@ -361,7 +361,7 @@ const createEmptyBlock = ({ name_cn, label, path, categories }) => {
}
const setComponentLinkedValue = ({ propertyName, value }) => {
- const { schema } = useCanvas().renderer.value?.getCurrent() || {}
+ const { schema } = useCanvas().canvasApi.value?.getCurrent() || {}
if (!propertyName || !schema) {
return
diff --git a/packages/controller/src/useCanvas.js b/packages/controller/src/useCanvas.js
index c97b65f29..d7f424a33 100644
--- a/packages/controller/src/useCanvas.js
+++ b/packages/controller/src/useCanvas.js
@@ -51,14 +51,20 @@ const defaultSchema = {
outputs: []
}
-const renderer = ref(null)
+const canvasApi = ref({})
+const isCanvasApiReady = ref(false)
+
+const initCanvasApi = (newCanvasApi) => {
+ canvasApi.value = newCanvasApi
+ isCanvasApiReady.value = true
+}
const pageState = reactive({ ...defaultPageState, loading: true })
// 重置画布数据
const resetCanvasState = async (state = {}) => {
Object.assign(pageState, defaultPageState, state)
- await renderer.value?.setSchema(pageState.pageSchema)
+ await canvasApi.value?.setSchema(pageState.pageSchema)
}
// 页面重置画布数据
@@ -142,7 +148,6 @@ const getCurrentPage = () => pageState.currentPage
export default function () {
return {
pageState,
- renderer,
isBlock,
isSaved,
isLoading,
@@ -153,10 +158,11 @@ export default function () {
resetPageCanvasState,
resetBlockCanvasState,
clearCurrentState,
- getDataSourceMap: renderer.value?.getDataSourceMap,
- setDataSourceMap: renderer.value?.setDataSourceMap,
getCurrentSchema,
setCurrentSchema,
- getCurrentPage
+ getCurrentPage,
+ initCanvasApi,
+ canvasApi,
+ isCanvasApiReady
}
}
diff --git a/packages/controller/src/useHistory.js b/packages/controller/src/useHistory.js
index 943dd92c2..82f0a6af0 100644
--- a/packages/controller/src/useHistory.js
+++ b/packages/controller/src/useHistory.js
@@ -61,7 +61,7 @@ const push = (schema) => {
const go = (addend, valid) => {
historyState.index = historyState.index + addend
- useCanvas().renderer.value?.setSchema(string2Schema(list[historyState.index]))
+ useCanvas().canvasApi.value?.setSchema(string2Schema(list[historyState.index]))
// 不是锁定状态,撤销操作后,传递第二个标识位,将 list 的长度减一,置灰 undoredo 操作按钮
if (typeof valid === 'boolean') {
@@ -95,7 +95,7 @@ const clear = () => {
const addHistory = (schema) => {
if (!schema) {
useCanvas().setSaved(false)
- push(useCanvas().renderer.value?.getSchema())
+ push(useCanvas().canvasApi.value?.getSchema())
} else {
clear()
// 初始 schema 需要设置为第一条历史记录
diff --git a/packages/controller/src/useProperties.js b/packages/controller/src/useProperties.js
index 8c0a91caf..8bc1298f3 100644
--- a/packages/controller/src/useProperties.js
+++ b/packages/controller/src/useProperties.js
@@ -191,7 +191,7 @@ const setProp = (name, value, type) => {
}
// 没有父级,或者不在节点上面,要更新内容。就用setState
- const { getNode, setState, updateRect } = useCanvas().renderer.value || {}
+ const { getNode, setState, updateRect } = useCanvas().canvasApi.value || {}
getNode(properties.schema.id, true)?.parent || setState(useCanvas().getPageSchema().state)
propsUpdateKey.value++
diff --git a/packages/controller/src/useResource.js b/packages/controller/src/useResource.js
index e8e462ad9..5df4dfa8d 100644
--- a/packages/controller/src/useResource.js
+++ b/packages/controller/src/useResource.js
@@ -137,7 +137,7 @@ const registerBlock = async (data, notFetchResouce) => {
return block
} else {
if (!blockResource.get(label)) {
- const { addScript, addStyle } = useCanvas().renderer.value
+ const { addScript, addStyle } = useCanvas().canvasApi.value
const promises = scripts
.filter((item) => item.includes('umd.js'))
.map(addScript)
@@ -372,7 +372,7 @@ const fetchResource = async ({ isInit = true } = {}) => {
const { id, type } = useEditorInfo().useInfo()
useApp().appInfoState.selectedId = id
- const Builtin = window.Builtin
+ const { Builtin } = useCanvas().canvasApi.value
Builtin.data.materials.components[0].children.map(registerComponent)
BuiltinComponentMaterials.components[0].children.map(registerComponent)
@@ -452,7 +452,7 @@ const updateCanvasDependencies = (blocks) => {
getBlockDeps(block.content.dependencies)
})
- useCanvas().renderer.value?.canvasDispatch('updateDependencies', { detail: resState.thirdPartyDeps })
+ useCanvas().canvasApi.value?.canvasDispatch('updateDependencies', { detail: resState.thirdPartyDeps })
}
export default function () {
diff --git a/packages/controller/src/useTranslate.js b/packages/controller/src/useTranslate.js
index 3df0e9442..3de96b042 100644
--- a/packages/controller/src/useTranslate.js
+++ b/packages/controller/src/useTranslate.js
@@ -101,7 +101,7 @@ const ensureI18n = (obj, send) => {
}
})
- useCanvas().renderer.value?.setLocales(messages, true)
+ useCanvas().canvasApi.value?.setLocales(messages, true)
} catch (e) {
// 不需要处理,有报错的词条会在画布初始化的时候统一调setLocales这个方法
}
@@ -171,7 +171,7 @@ const initAppI18n = async (appId) => {
host: appId,
hostType: HOST_TYPE.App
})
- useCanvas().renderer.value?.setLocales(i18nResource.messages)
+ useCanvas().canvasApi.value?.setLocales(i18nResource.messages)
}
}
@@ -181,7 +181,7 @@ const initBlockI18n = async (blockId) => {
host: blockId,
hostType: HOST_TYPE.Block
})
- useCanvas().renderer.value?.setLocales(i18nResource.messages)
+ useCanvas().canvasApi.value?.setLocales(i18nResource.messages)
}
}
@@ -192,7 +192,7 @@ const initBlockLocalI18n = async (langs = {}) => {
hostType: HOST_TYPE.Block,
local: true
})
- useCanvas().renderer.value?.setLocales(i18nResource.messages)
+ useCanvas().canvasApi.value?.setLocales(i18nResource.messages)
}
const format = (str = '', params = {}) => str.replace(/\$\{(.+?)\}/g, (substr, key) => params[key] || '')
diff --git a/packages/design-core/package.json b/packages/design-core/package.json
index 080d67f30..fd0fe8657 100644
--- a/packages/design-core/package.json
+++ b/packages/design-core/package.json
@@ -77,10 +77,10 @@
"@opentiny/tiny-engine-toolbar-setting": "workspace:*",
"@opentiny/tiny-engine-utils": "workspace:*",
"@opentiny/tiny-engine-webcomponent-core": "workspace:*",
- "@opentiny/vue": "~3.11.0",
- "@opentiny/vue-design-smb": "~3.11.0",
- "@opentiny/vue-renderless": "~3.11.0",
- "@opentiny/vue-theme": "~3.11.0",
+ "@opentiny/vue": "~3.14.0",
+ "@opentiny/vue-design-smb": "~3.14.0",
+ "@opentiny/vue-renderless": "~3.14.0",
+ "@opentiny/vue-theme": "~3.14.0",
"@vue/babel-plugin-jsx": "1.1.1",
"@vue/repl": "^2.9.0",
"@vueuse/core": "^9.6.0",
@@ -92,7 +92,7 @@
"monaco-editor": "0.33.0",
"prettier": "2.7.1",
"sortablejs": "^1.14.0",
- "vue": "^3.4.15",
+ "vue": "3.4.23",
"vue-i18n": "^9.9.0"
},
"devDependencies": {
diff --git a/packages/design-core/public/mock/bundle.json b/packages/design-core/public/mock/bundle.json
index 01d2c2b24..2fa58678f 100644
--- a/packages/design-core/public/mock/bundle.json
+++ b/packages/design-core/public/mock/bundle.json
@@ -311,7 +311,7 @@
"loop": true,
"condition": true,
"styles": true,
- "isContainer": false,
+ "isContainer": true,
"isModal": false,
"isPopper": false,
"nestingRule": {
@@ -632,7 +632,7 @@
"loop": true,
"condition": true,
"styles": true,
- "isContainer": false,
+ "isContainer": true,
"isModal": false,
"isPopper": false,
"nestingRule": {
@@ -1089,7 +1089,7 @@
"loop": true,
"condition": true,
"styles": true,
- "isContainer": false,
+ "isContainer": true,
"isModal": false,
"isPopper": false,
"nestingRule": {
@@ -4139,6 +4139,9 @@
"contentMenu": {
"actions": []
}
+ },
+ "configure": {
+ "isContainer": true
}
},
{
@@ -4497,6 +4500,9 @@
"contentMenu": {
"actions": []
}
+ },
+ "configure": {
+ "isContainer": true
}
},
{
@@ -5979,7 +5985,7 @@
"loop": true,
"condition": true,
"styles": true,
- "isContainer": true,
+ "isContainer": false,
"isModal": false,
"nestingRule": {
"childWhitelist": "",
@@ -6394,7 +6400,7 @@
"loop": true,
"condition": true,
"styles": true,
- "isContainer": true,
+ "isContainer": false,
"isModal": false,
"nestingRule": {
"childWhitelist": "",
@@ -8183,7 +8189,7 @@
"loop": true,
"condition": true,
"styles": true,
- "isContainer": true,
+ "isContainer": false,
"isModal": false,
"nestingRule": {
"childWhitelist": "",
@@ -8950,7 +8956,9 @@
"cols": 12,
"widget": {
"component": "MetaCodeEditor",
- "props": {}
+ "props": {
+ "language": "json"
+ }
},
"description": {
"zh_CN": ""
@@ -8996,7 +9004,7 @@
"loop": true,
"condition": true,
"styles": true,
- "isContainer": true,
+ "isContainer": false,
"clickCapture": false,
"isModal": false,
"nestingRule": {
diff --git a/packages/design-core/src/App.vue b/packages/design-core/src/App.vue
index e8c169a28..b029b7099 100644
--- a/packages/design-core/src/App.vue
+++ b/packages/design-core/src/App.vue
@@ -21,7 +21,15 @@
import { reactive, ref, watch, onUnmounted } from 'vue'
import { ConfigProvider as TinyConfigProvider } from '@opentiny/vue'
import designSmbConfig from '@opentiny/vue-design-smb'
-import { useResource, useLayout, useEditorInfo, useModal, useApp, useNotify } from '@opentiny/tiny-engine-controller'
+import {
+ useResource,
+ useLayout,
+ useEditorInfo,
+ useModal,
+ useApp,
+ useNotify,
+ useCanvas
+} from '@opentiny/tiny-engine-controller'
import AppManage from '@opentiny/tiny-engine-plugin-page'
import { isVsCodeEnv } from '@opentiny/tiny-engine-controller/js/environments'
import DesignToolbars from './DesignToolbars.vue'
@@ -90,7 +98,18 @@ export default {
}
useEditorInfo().getUserInfo()
- useResource().fetchResource()
+
+ watch(
+ useCanvas().isCanvasApiReady,
+ (ready) => {
+ if (ready) {
+ useResource().fetchResource()
+ }
+ },
+ {
+ immediate: true
+ }
+ )
const handlePopStateEvent = () => {
useResource().handlePopStateEvent()
@@ -154,6 +173,7 @@ export default {
}
}
.tiny-engine-right-wrap {
+ position: relative;
z-index: 4;
}
:deep(.monaco-editor .suggest-widget) {
diff --git a/packages/design-core/src/DesignCanvas.vue b/packages/design-core/src/DesignCanvas.vue
index dfad7bac2..a2c81063f 100644
--- a/packages/design-core/src/DesignCanvas.vue
+++ b/packages/design-core/src/DesignCanvas.vue
@@ -14,15 +14,8 @@