vue内使用window.open疑问

思否 问答 👍 2 含 AI 优化版

问题

vue内使用window.open疑问

在 SegmentFault 查看原问题 →

由大模型辅助整理,保留原意,优化结构与可读性。

问题概述

在 Vue 项目里用 window.open 打开一个新窗口/标签页后,如何在两个窗口之间进行通信?window.openerwindow.open 返回值各自指向谁?

涉及技术

window.openwindow.openerpostMessagelocalStorage

期望结果

理清两个窗口引用关系,并得到可行的跨窗口通信方案。

回答

原始回答

2021-12-10 window.opener 是指向打开者。frame = window.open , frame 是指向被打开者。通信可以 stroage 、 postMessage 。方案一:

AI 优化 · 回答整理

解答思路

先理清引用关系:const frame = window.open(url) 中,frame打开者(原窗口)持有的新窗口的引用;而在新窗口内部,window.opener 则是指向打开它的那个原窗口的引用。有了双向引用后,就可以通过 postMessage 或共享的 storage 事件进行通信。

示例代码

方案一:postMessage(推荐,双向、实时)

// 原窗口打开新窗口
const frame = window.open('https://example.com');
frame.postMessage({ type: 'hello' }, 'https://example.com');

// 新窗口监听消息,并可以回传给 opener
window.addEventListener('message', (e) => {
  console.log('收到消息:', e.data);
  window.opener?.postMessage({ type: 'reply' }, e.origin);
});

方案二:localStorage + storage 事件(适合同源、简单状态同步)

// 任一窗口写入
localStorage.setItem('sync-key', JSON.stringify({ value: 1 }));

// 另一个窗口监听变化
window.addEventListener('storage', (e) => {
  if (e.key === 'sync-key') {
    console.log('数据变化:', JSON.parse(e.newValue));
  }
});

详细说明

  • postMessage 的优势是不要求同源,且事件驱动、实时,通信双方都可以互相发送消息,是跨窗口/跨域通信的标准方式;使用时务必校验 event.origin,避免被恶意页面利用。
  • storage 事件只有在同源下才生效,并且只会在“其他”窗口触发(当前窗口自己写入不会触发自身的 storage 事件),适合做简单的状态广播。
  • 在 Vue 组件中使用时,记得在组件销毁时移除事件监听,避免内存泄漏。

小结

window.open 返回值指向新窗口,window.opener 指向打开者;两者之间的通信推荐用 postMessage,同源场景下也可以用 localStorage + storage 事件做简单同步。

由大模型辅助整理,保留原意,补充结构与代码格式。

回答转载自 SegmentFault

评论

评论功能即将开放。你也可以通过 邮件GitHub Issue 反馈。