@@ -30,6 +30,9 @@ const { deepClone } = utils
3030// 保存预览窗口引用
3131let previewWindow = null
3232
33+ // 创建 BroadcastChannel 实例用于通信
34+ const previewChannel = new BroadcastChannel ( 'tiny-engine-preview-channel' )
35+
3336const getScriptAndStyleDeps = ( ) => {
3437 const { scripts, styles } = useMaterial ( ) . getCanvasDeps ( )
3538 const utilsDeps = useResource ( ) . getUtilsDeps ( )
@@ -99,46 +102,29 @@ const sendSchemaUpdate = (data) => {
99102 )
100103}
101104
102- // 监听来自预览页面的消息
103- const setupMessageListener = ( ) => {
104- window . addEventListener ( 'message' , async ( event ) => {
105- // 确保消息来源安全
106- if ( event . origin === window . location . origin || event . origin . includes ( window . location . hostname ) ) {
107- const { event : eventType , source } = event . data || { }
108- // 通过 heartbeat 消息来重新建立连接,避免刷新页面后 previewWindow 为 null
109- if ( source === 'preview' && eventType === 'heartbeat' && ! previewWindow ) {
110- previewWindow = event . source
111- }
105+ let hasSchemaChangeListener = false
112106
113- if ( source === 'preview' && eventType === 'onMounted' && previewWindow ) {
114- const params = await getSchemaParams ( )
115- sendSchemaUpdate ( params )
116- }
117- }
107+ const cleanupSchemaChangeListener = ( ) => {
108+ const { unsubscribe } = useMessage ( )
109+ unsubscribe ( {
110+ topic : 'schemaChange' ,
111+ subscriber : 'preview-communication'
112+ } )
113+ unsubscribe ( {
114+ topic : 'schemaImport' ,
115+ subscriber : 'preview-communication'
116+ } )
117+ unsubscribe ( {
118+ topic : 'pageOrBlockInit' ,
119+ subscriber : 'preview-communication'
118120 } )
121+ hasSchemaChangeListener = false
119122}
120123
121- // 初始化消息监听
122- setupMessageListener ( )
123-
124- let schemaChangeListener = null
125124const handleSchemaChange = async ( ) => {
126- const { unsubscribe } = useMessage ( )
127125 // 如果预览窗口不存在或已关闭,则取消订阅
128126 if ( ! previewWindow || previewWindow . closed ) {
129- unsubscribe ( {
130- topic : 'schemaChange' ,
131- subscriber : 'preview-communication'
132- } )
133- unsubscribe ( {
134- topic : 'schemaImport' ,
135- subscriber : 'preview-communication'
136- } )
137- unsubscribe ( {
138- topic : 'pageOrBlockInit' ,
139- subscriber : 'preview-communication'
140- } )
141- schemaChangeListener = null
127+ cleanupSchemaChangeListener ( )
142128 return
143129 }
144130
@@ -149,13 +135,13 @@ const handleSchemaChange = async () => {
149135// 设置监听 schemaChange 事件,自动发送更新到预览页面
150136export const setupSchemaChangeListener = ( ) => {
151137 // 如果已经存在监听,则取消之前的监听
152- if ( schemaChangeListener ) {
138+ if ( hasSchemaChangeListener ) {
153139 return
154140 }
155141
156142 const { subscribe } = useMessage ( )
157143
158- schemaChangeListener = subscribe ( {
144+ subscribe ( {
159145 topic : 'schemaChange' ,
160146 subscriber : 'preview-communication' ,
161147 // 防抖更新,防止因为属性变化频繁触发
@@ -173,8 +159,39 @@ export const setupSchemaChangeListener = () => {
173159 subscriber : 'preview-communication' ,
174160 callback : handleSchemaChange
175161 } )
162+
163+ hasSchemaChangeListener = true
176164}
177165
166+ // 监听来自预览页面的消息
167+ const setupMessageListener = ( ) => {
168+ window . addEventListener ( 'message' , async ( event ) => {
169+ // 确保消息来源安全
170+ if ( event . origin === window . location . origin || event . origin . includes ( window . location . hostname ) ) {
171+ const { event : eventType , source } = event . data || { }
172+ // 通过 heartbeat 消息来重新建立连接,避免刷新页面后 previewWindow 为 null
173+ if ( source === 'preview' && eventType === 'connect' && ! previewWindow ) {
174+ previewWindow = event . source
175+ setupSchemaChangeListener ( )
176+ }
177+
178+ if ( source === 'preview' && eventType === 'onMounted' && previewWindow ) {
179+ const params = await getSchemaParams ( )
180+ sendSchemaUpdate ( params )
181+ }
182+ }
183+ } )
184+
185+ // 可能是刷新,需要重新建立连接
186+ previewChannel . postMessage ( {
187+ event : 'connect' ,
188+ source : 'designer'
189+ } )
190+ }
191+
192+ // 初始化消息监听
193+ setupMessageListener ( )
194+
178195const handleHistoryPreview = ( params , url ) => {
179196 let historyPreviewWindow = null
180197 const handlePreviewReady = ( event ) => {
@@ -241,7 +258,20 @@ const open = (params = {}, isHistory = false) => {
241258
242259 let openUrl = ''
243260
244- openUrl = isDevelopEnv ? `./preview.html?${ query } ` : `${ href . endsWith ( '/' ) ? href : `${ href } /` } preview?${ query } `
261+ // 从预览组件配置获取自定义URL
262+ const customPreviewUrl = getMergeMeta ( 'engine.toolbars.preview' ) ?. options ?. previewUrl
263+ const defaultPreviewUrl = isDevelopEnv ? `./preview.html` : `${ href . endsWith ( '/' ) ? href : `${ href } /` } preview`
264+
265+ if ( customPreviewUrl ) {
266+ // 如果配置了自定义预览URL,则使用自定义URL
267+ openUrl =
268+ typeof customPreviewUrl === 'function'
269+ ? customPreviewUrl ( defaultPreviewUrl , query )
270+ : `${ customPreviewUrl } ?${ query } `
271+ } else {
272+ // 否则使用默认生成的URL
273+ openUrl = `${ defaultPreviewUrl } ?${ query } `
274+ }
245275
246276 if ( isHistory ) {
247277 handleHistoryPreview ( { ...params , scripts, styles } , openUrl )
0 commit comments