diff --git a/demo/app.ts b/demo/app.ts index c43a974..7e0099c 100644 --- a/demo/app.ts +++ b/demo/app.ts @@ -1,4 +1,5 @@ import mpx, { createApp } from '@mpxjs/core' +import { onChildPathchange } from '@mpxjs/vuese-website/dist/iframe-sync' import apiProxy from '@mpxjs/api-proxy' mpx.use(apiProxy, { usePromise: true }) @@ -9,15 +10,9 @@ createApp({}) const isIframe = __mpx_mode__ === 'web' && window.parent !== window if (isIframe) { - let prevPath = '' - const handleMessage = (e) => { - const { to } = (typeof e.data === 'object' ? e.data : {}) as any - if (to !== undefined && to !== prevPath) { - mpx.redirectTo({ - url: `/pages/${to && to !== 'intro' ? `${to}/` : ''}index` - }) - prevPath = to - } - } - window.addEventListener('message', handleMessage) + onChildPathchange((to) => { + mpx.redirectTo({ + url: `/pages/${to && to !== 'intro' ? `${to}/` : ''}index` + }) + }) } diff --git a/demo/pages/index.ts b/demo/pages/index.ts index c33a169..8bde6c3 100644 --- a/demo/pages/index.ts +++ b/demo/pages/index.ts @@ -1,4 +1,5 @@ import mpx, { createPage, ref, onMounted, onUnmounted } from '@mpxjs/core' +import { syncPathToChild } from '@mpxjs/vuese-website/dist/iframe-sync' import demoConfig from '../common/config' const SCROLL_KEY = '___scoll_top___' @@ -10,9 +11,7 @@ createPage({ const component = `${item.replace(/\(.*\)/, '')}` const route = `./${component}/index` if (__mpx_mode__ === 'web' && window.parent !== window) { - window.parent.postMessage({ - component - }, '*') + syncPathToChild(component) return } mpx.navigateTo({ diff --git a/packages/website/lib/iframe-sync.ts b/packages/website/lib/iframe-sync.ts new file mode 100644 index 0000000..17e6b6e --- /dev/null +++ b/packages/website/lib/iframe-sync.ts @@ -0,0 +1,44 @@ +/** + * 同步路由到主窗口 + * @param iframe + * @param to + */ +export const syncPathToParent = (iframe: HTMLIFrameElement, to: string) => { + iframe?.contentWindow?.postMessage({ + value: to + }, '*') +} + +const cache = { + prevPath: '' +} +/** + * 监听子路由的变化 + * @param callback + * @returns + */ +export const onChildPathchange = (callback?: (path: string) => void): () => void => { + const handleMessage = (e: { data: { value: string } }) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const { value } = (typeof e.data === 'object' ? e.data || {} : {}) + if (value !== undefined && value !== cache.prevPath) { + callback?.(value) + cache.prevPath = value + } + } + window.addEventListener('message', handleMessage) + return () => { + window.removeEventListener('message', handleMessage) + } +} + +/** + * 同步路由到子窗口 + * @param to + */ +export const syncPathToChild = (to: string) => { + window.parent.postMessage({ + value: to + }, '*') +} diff --git a/packages/website/rollup.config.js b/packages/website/rollup.config.js new file mode 100644 index 0000000..a3bfc89 --- /dev/null +++ b/packages/website/rollup.config.js @@ -0,0 +1,24 @@ +const path = require('path') +const ts = require('rollup-plugin-typescript2') + +const generateConfig = (input, output, external = [], plugins = []) => { + return { + input, + output, + external, + plugins: [ + ts({ + tsconfig: path.resolve(__dirname, './tsconfig.json') + }), + ...plugins, + ], + } +} + +module.exports = [ + generateConfig(path.resolve(__dirname, './lib/iframe-sync.ts'), { + file: path.resolve(__dirname, './dist/iframe-sync.js'), + format: 'es', + name: 'websiteIframeSync' + }) +] diff --git a/packages/website/theme/components/Preview.vue b/packages/website/theme/components/Preview.vue index 53d10ce..e30299a 100644 --- a/packages/website/theme/components/Preview.vue +++ b/packages/website/theme/components/Preview.vue @@ -28,6 +28,7 @@ import { throttle } from 'lodash-es' import { ref, onMounted, computed, watch, onUnmounted } from 'vue' import { useRouter, useRoute, useData } from 'vitepress' +import { syncPathToParent } from '@mpxjs/vuese-website/dist/iframe-sync' const COMPONENT_DIR_NAME = 'components' @@ -62,10 +63,7 @@ const title = computed(() => { const iframeRef = ref() const syncChildPath = to => { - iframeRef.value?.contentWindow.postMessage({ - to: getComponentName(), - origin: route.path - }, '*') + syncPathToParent(iframeRef.value, getComponentName()) } const isShowBack = ref(false) @@ -83,10 +81,10 @@ watch(() => route.path, (newPath, oldPath) => { }) const handleMessage = e => { - if (e.data?.component !== undefined) { + if (e.data?.value !== undefined) { const data = e.data - if (data.component) { - router.go(`${site.value.base}${COMPONENT_DIR_NAME}/${data.component}.html`) + if (data.value) { + router.go(`${site.value.base}${COMPONENT_DIR_NAME}/${data.value}.html`) return } const findComponent = list => { @@ -94,7 +92,7 @@ const handleMessage = e => { return null } for (const item of list) { - if (item.path?.endsWith(data.component)) { + if (item.path?.endsWith(data.value)) { return item } const target = findComponent(item.children) diff --git a/scripts/build.js b/scripts/build.js index 9063f0f..46ecd81 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -19,6 +19,10 @@ function makeBuild() { if (pkgMeta.private) return await fs.remove(`${pkgDir}/dist`) await execa('rollup', ['-c', '--environment', `PKG_DIR:${pkgDirName}`], {}) + const config = `${pkgDir}/rollup.config.js` + if (fs.pathExistsSync(config)) { + await execa('rollup', ['--config', config]) + } const dtsOutDir = `${pkgDir}/${pkgMeta.types}`