diff --git a/packages/canvas/DesignCanvas/src/DesignCanvas.vue b/packages/canvas/DesignCanvas/src/DesignCanvas.vue index 129b57a55..27b47bb83 100644 --- a/packages/canvas/DesignCanvas/src/DesignCanvas.vue +++ b/packages/canvas/DesignCanvas/src/DesignCanvas.vue @@ -247,6 +247,24 @@ export default { }) }) + function updatePreviewId(previewId, replace = false) { + const url = new URL(window.location.href) + if (previewId) { + if (previewId === url.searchParams.get('previewid')) { + return + } + url.searchParams.set('previewid', previewId) + } else { + url.searchParams.delete('previewid') + } + if (replace) { + window.history.replaceState({}, '', url) + } else { + window.history.pushState({}, '', url) + } + usePage().postLocationHistoryChanged({ previewId }) + } + return { removeNode, canvasSrc, @@ -264,6 +282,7 @@ export default { getPageAncestors: usePage().getAncestors, getBaseInfo: () => getMetaApi(META_SERVICE.GlobalService).getBaseInfo(), addHistoryDataChangedCallback, + updatePreviewId, ast, getBlockByName: useMaterial().getBlockByName, useModal, diff --git a/packages/canvas/render/src/RenderMain.ts b/packages/canvas/render/src/RenderMain.ts index 908fb77d8..fa1d08d90 100644 --- a/packages/canvas/render/src/RenderMain.ts +++ b/packages/canvas/render/src/RenderMain.ts @@ -28,6 +28,7 @@ import { getPageAncestors } from './material-function/page-getter' import CanvasEmpty from './canvas-function/CanvasEmpty.vue' import { setCurrentPage } from './canvas-function/page-switcher' import { useThrottleFn } from '@vueuse/core' +import { useRouterPreview } from './canvas-function/router-preview' // global-context singleton const { context: globalContext, setContext: setGlobalContext } = useContext() @@ -135,7 +136,7 @@ export default defineComponent({ pageContext.setCssScopeId(props.cssScopeId || `data-te-page-${pageContext.pageId}`) if (props.entry) { provide('page-ancestors', pageAncestors) - + provide('page-preview', useRouterPreview().previewPath) const updatePageAncestor = () => { if (routerViewSetting.viewMode === 'standalone') { pageAncestors.value = [] diff --git a/packages/canvas/render/src/canvas-function/router-preview.ts b/packages/canvas/render/src/canvas-function/router-preview.ts new file mode 100644 index 000000000..c04b54ff9 --- /dev/null +++ b/packages/canvas/render/src/canvas-function/router-preview.ts @@ -0,0 +1,79 @@ +import { onUnmounted, ref } from 'vue' +import { getController } from './controller' +import { getPageAncestors } from '../material-function/page-getter' + +export function useRouterPreview() { + const pageId = ref(getController().getBaseInfo().pageId) + const previewId = ref(getController().getBaseInfo().previewId) + const updatePreviewId = getController().updatePreviewId + const previewFullPath = ref([]) + const previewPath = ref([]) + + async function calcNewPreviewFullPath() { + if (!pageId.value) { + if (previewId.value) { + updatePreviewId(undefined, true) + return + } + previewFullPath.value = [] + previewPath.value = [] + return + } + if (!previewId.value) { + previewFullPath.value = await getPageAncestors(pageId.value) + previewPath.value = [] + return + } + + if (previewFullPath.value[previewFullPath.value.length - 1] !== previewId.value) { + // previewId changed + const fullPath = await getPageAncestors(previewId.value) + if (fullPath.includes(pageId.value)) { + previewFullPath.value = fullPath + } else { + updatePreviewId(pageId.value, true) + } + } + + if (previewFullPath.value.includes(pageId.value)) { + // only pageId changed and fast move + const fastJumpIndex = previewFullPath.value.indexOf(pageId.value) + if (fastJumpIndex + 1 < previewFullPath.value.length) { + previewPath.value = previewFullPath.value.slice(fastJumpIndex + 1) + } else { + previewPath.value = [] + } + } else { + previewFullPath.value = await getPageAncestors(pageId.value) + previewPath.value = [] + updatePreviewId(pageId.value, true) + } + } + + const cancel = getController().addHistoryDataChangedCallback(() => { + const newPageId = getController().getBaseInfo().pageId + const newPreviewId = getController().getBaseInfo().previewId + const pageIdChanged = newPageId !== pageId.value + const previewIdChanged = newPreviewId !== previewId.value + if (pageIdChanged) { + pageId.value = newPageId + } + if (previewIdChanged) { + previewId.value = newPreviewId + } + if (previewIdChanged || pageIdChanged) { + calcNewPreviewFullPath() + } + }) + + onUnmounted(() => { + cancel() + }) + + calcNewPreviewFullPath() + + return { + previewPath, + previewFullPath + } +} diff --git a/packages/canvas/render/src/render.ts b/packages/canvas/render/src/render.ts index 95ec2a3a7..e54c48e11 100644 --- a/packages/canvas/render/src/render.ts +++ b/packages/canvas/render/src/render.ts @@ -212,11 +212,13 @@ const getChildren = (schema, mergeScope, pageContext) => { } function getRenderPageId(currentPageId, isPageStart) { const pagePathFromRoot = (inject('page-ancestors') as Ref).value + const pagePreviewFromCurrentPageChild = (inject('page-preview') as Ref).value + const fullPath = [...pagePathFromRoot, ...pagePreviewFromCurrentPageChild] function getNextChild(currentPageId) { - const index = pagePathFromRoot.indexOf(currentPageId) - if (index > -1 && index + 1 < pagePathFromRoot.length) { - return pagePathFromRoot[index + 1] + const index = fullPath.indexOf(currentPageId) + if (index > -1 && index + 1 < fullPath.length) { + return fullPath[index + 1] } return null } @@ -256,7 +258,13 @@ export const renderer = defineComponent({ if (renderPageId) { return h(getPage(renderPageId), { key: ancestors, - [DESIGN_TAGKEY]: `${componentName}` + [DESIGN_TAGKEY]: `${componentName}`, + ...(pageContext.active && !isPageStart + ? { + [DESIGN_UIDKEY]: schema.id, + draggable: true + } + : {}) }) } } diff --git a/packages/common/composable/defaultGlobalService.js b/packages/common/composable/defaultGlobalService.js index edb09983c..9b38de54b 100644 --- a/packages/common/composable/defaultGlobalService.js +++ b/packages/common/composable/defaultGlobalService.js @@ -6,6 +6,7 @@ const getBaseInfo = () => { const id = paramsMap.get('id') const blockId = paramsMap.get('blockid') const pageId = paramsMap.get('pageid') + const previewId = paramsMap.get('previewid') const type = paramsMap.get('type') const version = paramsMap.get('version') @@ -13,6 +14,7 @@ const getBaseInfo = () => { type: type || 'app', id, pageId, + previewId, blockId, version }