vue中与其他网页通信

vue中与其他网页通信


更新于:2023-02-17
原理:iframe+postMessage
依赖:“vue”: “^3.2.45”

需要嵌入iframe的网页

<template>
  <div>
    <button @click="sendMsg()">send message</button>

    <div class="browser-frame">
      <iframe
        ref="receiver"
        class="container"
        :src="urlAddr"
        frameborder="0"
      ></iframe>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref } from "vue";

const receiver = ref(null);
const urlAddr = "http://localhost:5174";

onMounted(() => {
  window.addEventListener("message", receiveMessage, false);
});

const sendMsg = () => {
  try {
    console.log("father send");
    if (receiver) {
      receiver.value.contentWindow.postMessage(
        JSON.stringify({ method: "sayHi", data: "hello child" }),
        urlAddr
      );
    }
  } catch (err) {
    console.log("father send-------" + err.toString());
  }
};

const receiveMessage = (event) => {
  try {
    console.log("father receive");
    if (event.origin !== urlAddr) {
      // 验证消息来源地址
      return;
    }
    console.log(event.data);
  } catch (err) {
    console.log("father receive-------" + err.toString());
  }
};
</script>
<style lang="scss" scoped>
</style>

被嵌入的网页

<script setup>
import { onMounted } from "vue";

onMounted(() => {
  window.addEventListener("message", receiveMessage, false);
});
const sendMsg = () => {
  try {
    console.log("child send");

    parent.postMessage(
      JSON.stringify({ method: "sayHi", data: "hello father" }),
      "*"
    );
  } catch (err) {
    console.log("child send-------" + err.toString());
  }
};

const receiveMessage = (event) => {
  try {
    console.log("child receive");
    console.log(event.data);
  } catch (err) {
    console.log("child receive-------" + err.toString());
  }
};
</script>

<template>
    <div>
    	<button @click="sendMsg()">send to father</button>
    </div>
</template>
<think>嗯,用户问的是关于Uniapp的Web-view通信Vue3网页的内容。我需要先回忆一下Uniapp中Web-view组件的用法,以及如何内嵌的网页进行通信。特别是用户提到Vue3,可能需要考虑Vue3的语法和响应式系统如何Uniapp结合。 首先,Web-view组件在Uniapp中用于嵌入H5页面,用户可能想知道如何在这个内嵌的页面和Uniapp的原生部分之间传递数据。通信方式主要有两种:URL传参和UniApp的API,比如uni.postMessage和onMessage。需要详细说明这两种方法的使用步骤,并给出示例代码。 然后,考虑到用户使用Vue3网页,可能需要提到Vue3的组合式API,比如setup函数,以及如何Uniapp的通信机制结合。比如在Vue3的setup中监听消息或者发送消息到Uniapp。这里要注意Vue3的生命周期钩子和Uniapp的事件监听是否兼容,比如在onMounted中初始化监听。 另外,用户可能关心通信的安全性和效率,比如URL传参的限制,postMessage的优点。需要比较两种方法的适用场景,比如URL适合简单参数,postMessage适合复杂数据交互。 还要注意提醒用户关于H5页面的部署路径问题,Uniapp的Web-view需要正确的网络地址或本地路径。可能需要检查manifest.json的配置,确保H5页面可以正确加载。 可能遗漏的点:Uniapp向Web-view发送消息的方式,除了uni.postMessage,还有没有其他方法?比如通过evalJS执行JS函数,这可能在需要即时执行某些操作时有用,但安全性较低,需要谨慎使用。 还有,Vue3中使用TypeScript的情况,是否会影响通信代码的编写?可能需要给出TypeScript的示例,或者说明如何避免类型错误。 另外,跨域问题是否会影响通信?如果H5页面部署在不同的域名下,可能需要配置服务器允许跨域访问,或者使用本地代理调试。 最后,总结部分要简明扼要,强调两种通信方式的选择依据,以及Vue3中的最佳实践,帮助用户根据具体需求选择合适的方法。</think>以下为您详细介绍Uniapp中Web-view组件Vue3网页通信方式及实现原理: ### 一、通信机制基础 1. **原生通信架构** Uniapp通过`<web-view>`组件创建原生Web容器,采用以下两种通信方式: - **URL参数传递**:通过加载URL时携带查询参数 - **UniAPP API通信**:使用`uni.postMessage`和`uni.onMessage`实现双向通信 2. **通信方向** $$双向通信 = 原生\to H5 \quad \text{&} \quad H5\to原生$$ ### 二、具体实现方式 #### (一) 原生向H5页面通信 1. **URL参数传递(简单数据)** ```html <!-- UniApp端 --> <web-view :src="`https://example.com?token=${token}&userId=${userId}`"></web-view> ``` ```javascript // Vue3 H5端 import { onMounted } from 'vue' setup() { onMounted(() => { const urlParams = new URLSearchParams(window.location.search) console.log('接收参数:', urlParams.get('token')) }) } ``` 2. **postMessage API(复杂数据)** ```javascript // UniApp端 const webViewContext = uni.createWebViewContext('webview1') webViewContext.postMessage({ action: 'UPDATE_DATA', payload: { list: [1,2,3] } }) ``` ```javascript // Vue3 H5端 import { onMounted } from 'vue' setup() { onMounted(() => { window.uni.onMessage(msg => { console.log('收到消息:', msg) }) }) } ``` #### (二) H5向原生通信 1. **Vue3发送消息** ```javascript // Vue3 H5端 const sendToNative = () => { window.uni.postMessage({ type: 'FORM_SUBMIT', data: { username: 'test', value: 100 } }) } ``` 2. **UniApp接收消息** ```javascript // pages/webview-page.vue onLoad() { uni.onMessage(msg => { if(msg.type === 'FORM_SUBMIT') { uni.showToast({ title: '收到表单数据' }) } }) } ``` ### 三、Vue3适配要点 1. **响应式集成** ```javascript // 推荐使用Composition API封装 export function useUniMessage() { const message = ref(null) onMounted(() => { window.uni?.onMessage((msg) => { message.value = msg }) }) return { message } } ``` 2. **TypeScript支持** ```typescript // types.d.ts declare interface Window { uni?: { postMessage: (data: object) => void onMessage: (callback: (msg: any) => void) => void } } ``` ### 四、注意事项 1. **安全边界** - 建议对`postMessage`数据做JSON Schema验证 - 敏感数据应通过HTTPS传输 2. **性能优化** - 控制通信频率(建议≤1次/秒) - 复杂数据使用`JSON.stringify`压缩 3. **调试技巧** ```javascript // 开启UniApp调试模式 "h5" : { "devServer" : { "proxy" : { "/api" : { "target" : "http://localhost:3000" } } } } ``` ### 五、应用场景对比 | 场景 | URL传参 | postMessage | |---------------------|--------------|----------------| | 初始化参数 | ✓ | ✗ | | 实时数据更新 | ✗ | ✓ | | 大数据量传输 | ✗ | ✓ | | 跨域通信 | ✓ | ✗ | 建议根据具体业务需求组合使用两种方式,初期推荐优先使用`postMessage`实现核心功能,配合URL参数进行初始化配置。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值