微信小程序webview和小程序通讯

1.背景介绍

1.1需要在小程序嵌入vr页面,同时在vr页面添加操作按钮与小程序进行通信交互

1.2开发工具:uniapp开发小程序

1.3原型图

功能:.点击体验官带看跳转小程序的体验官带看页面

功能:点击立即咨询唤起小程序弹窗打电话

2.组件及api介绍

uniapp官网:web-view | uni-app官网 (dcloud.net.cn)

web-view

web-view是一个 web 浏览器组件,可以用来承载网页的容器,会自动铺满整个页面(nvue 使用需要手动指定宽高)。

各小程序平台,web-view 加载的 url 需要在后台配置域名白名单,包括内部再次 iframe 内嵌的其他 url 。

属性说明

属性名

类型

说明

平台差异说明

src

String

webview 指向网页的链接

allow

String

用于为iframe指定其特征策略

H5

sandbox

String

该属性对呈现在iframe框架中的内容启用一些额外的限制条件。

H5

fullscreen

Boolean

是否铺满整个页面,默认值:true

H5 (HBuilder X 3.5.4+)

webview-styles

Object

webview 的样式

App-vue

update-title

Boolean

是否自动更新当前页面标题。默认值:true

App-vue (HBuilder X 3.3.8+)

@message

EventHandler

网页向应用postMessage时,会在特定时机(后退、组件销毁、分享)触发并收到消息。

H5 暂不支持(可以直接使用window.postMessage

@onPostMessage

EventHandler

网页向应用实时postMessage

App-nvue

@load

EventHandler

网页加载成功时候触发此事件。

微信小程序、支付宝小程序、抖音小程序、QQ小程序

@error

EventHandler

网页加载失败的时候触发此事件。

微信小程序、支付宝小程序、抖音小程序、QQ小程序

在小程序端,用法和iframe类似,直接在src赋值在线地址

<web-view src="https://uniapp.dcloud.io/static/web-view.html"></web-view>

注意:

  • 小程序仅支持加载网络网页,不支持本地html
  • 小程序端 web-view 组件一定有原生导航栏,下面一定是全屏的 web-view 组件,navigationStyle: custom 对 web-view 组件无效。
  • 小程序平台,src指向的链接需登录小程序管理后台配置域名白名单。
  • 小程序平台,个人类型与海外类型的小程序使用web-view组件,提交审核时注意微信等平台是否允许使用
  • 小程序的web-view使用的是小程序自带的浏览器内核,不同厂商不一样,详见
  • 各小程序平台,web-view 加载的 url 需要在后台配置域名白名单,包括内部再次 iframe 内嵌的其他 url 。

<web-view>加载的网页中支持调用部分 uni 接口:

方法名

说明

平台差异说明

uni.navigateTo

navigateTo

uni.redirectTo

redirectTo

uni.reLaunch

reLaunch

uni.switchTab

switchTab

uni.navigateBack

navigateBack

uni.postMessage

向应用发送消息

抖音小程序不支持、H5 暂不支持(可以直接使用window.postMessage

uni.getEnv

获取当前环境

抖音小程序与飞书小程序不支持

uni.postMessage(OBJECT)

网页向应用发送消息,在<web-view>message事件回调event.detail.data中接收消息。

Tips

  • 传递的消息信息,必须写在 data 对象中。
  • event.detail.data中的数据,以数组的形式接收每次 post 的消息。(注:支付宝小程序除外,支付宝小程序中以对象形式接受)
#uni.getEnv(CALLBACK)

callback 返回的对象

属性

类型

说明

plus

Boolean

App

nvue

Boolean

App-nvue, uni.webview.1.5.4.js+ 支持

miniprogram

Boolean

微信小程序

smartprogram

Boolean

百度小程序

miniprogram

Boolean

支付宝小程序

3.实际操作

下面直接来看示例

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>测试</title>
  <!-- 引入ui库vant的样式 -->
  <link rel="stylesheet" href="./vant.css">
  <!-- 引入自定义的全局样式 -->
  <link rel="stylesheet" href="./global.css">
  <!-- 引入页面样式文件 -->
  <link rel="stylesheet" href="./index.css">

</head>

<body>
  <div id="app">
    <div class="flex-1">
      <!-- 嵌入iframe展示vr页面 -->
      <iframe class="iframe" src="https://www.realsee.com/website/customer/dataSpace/vr/kPJJK5rx" allowfullscreen="true"
        frameborder="0"></iframe>
    </div>
    <main>
      <!-- 底部操作按钮 -->
      <div class="ptb-10 flex-vcenter flex-between">
        <van-button type="info" @click="handleLook">体验馆带看</van-button>
        <van-button type="info" @click="handleRoom">看房型</van-button>
        <van-button type="info" @click="handleAsk">立即咨询</van-button>
      </div>
      <!-- 看房型的弹窗 -->
      <van-popup v-model="showRoomPopup" round position="bottom" :overlay="false"
        :style="{ minHeight: '10%',padding: '15px 10px 10px',background: 'rgba(0,0,0,.7)' }">
        <div class="co-white pb-15" style="position: relative;">
          <p class="text-center">房型预览</p>
          <div @click="showRoomPopup = false" class="arrow-down-wrap flex-vcenter">
            <span class="fs-12 mr-5">收起</span>
            <van-icon name="arrow-down" />
          </div>
        </div>
        <van-grid class="rooms-wrap" :column-num="3">
          <van-grid-item v-for="(item,index) in urlParams.rooms" :key="index">

            <div class="co-white rooms-item" @click="goRoom(item.url)">
              <p class="rooms-content">{{item.name}}</p>
              <van-image width="100%" height="100%" fit="cover" src="https://img01.yzcdn.cn/vant/cat.jpeg" />
            </div>
          </van-grid-item>
        </van-grid>
      </van-popup>
    </main>
  </div>

  <!-- 需要引入的文件 -->
  <!-- vue -->
  <script type="text/javascript" src="./vue.min.js"></script>
  <!-- vant ui库 -->
  <script type="text/javascript" src="./vant.min.js"></script>
  <!--  微信小程序 JS-SDK  -->
  <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
  <!-- 与uniapp建立连接 -->
  <script type="text/javascript" src="./uni.webview.1.5.5.js"></script>
  <!-- 页面的js文件 -->
  <script type="text/javascript" src="./index.js"></script>
</body>

</html>
调用api与小程序通信
new Vue({
  el: '#app',
  components: {
  },
  data () {
    return {
      urlParams: {
        rooms: []
      },
      showRoomPopup: false
    }
  },
  computed: {
  },
  created () {
  },
  watch: {
  },
  mounted () {
    const { params } = this.urlToObj(location.href)
    if (params) {
      this.urlParams = JSON.parse(decodeURI(params))
    }
    document.addEventListener('UniAppJSBridgeReady', () => {
      uni.getEnv((res) => {
        console.log('当前环境:' + JSON.stringify(res));
      });
    })
  },
  methods: {
    // url参数转对象
    urlToObj (url) {
      let obj = {};
      if (url.indexOf('?') >= 0) {
        let str = url.slice(url.indexOf('?') + 1);
        let arr = str.split('&');
        console.log(str, arr)

        for (let j = arr.length, i = 0; i < j; i++) {
          let arr_temp = arr[i].split('=');
          obj[arr_temp[0]] = arr_temp[1];
        }
      }
      return obj;
    },

    // 点击体验官带看
    handleLook () {
      // 跳转到小程序的某个页面
      uni.navigateTo({
        url: '/pages/vr/look'
      });
    },
    // 点击看房型
    handleRoom () {
      console.log(this.urlParams)
      this.showRoomPopup = true;
    },
    goRoom (url) {
      // 跳转到小程序的某个页面
      uni.navigateTo({
        url: `/pages/vr/room?url=${url}`
      });
    },
    // 点击咨询
    handleAsk () {
      // 发送消息给小程序
      uni.postMessage({
        data: {
          action: '咨询'
        }
      });
      // 因为网页向应用?postMessage?时,会在特定时机(后退、组件销毁、分享)触发并收到消息。 所以用uni.redirectTo触发小程序的重新加载实时接收消息
      uni.redirectTo({
        url: '/pages/vr/vr'
      });
    }
  }
})

页面预览效果:

小提示:如何在开发者工具查看webiew页面的信息
小程序端代码参考
<template>
  <web-view :src="vrUrl" @message="onMessage"></web-view>
</template>

<script>
import { callPhone } from '@/utils';
export default {
  data() {
    return {
      vrUrl:
        // 这里要换成你的在线网页地址,我这里写的是本地的
        `http://127.0.0.1:5500/vr-demo/index.html?params=` +
        encodeURI(
          JSON.stringify({
            rooms: [
              {
                name: '房间1',
                url: 'https://www.realsee.com/website/customer/dataSpace/vr/kPJJK5rx',
              },
              {
                name: '房间2',
                url: 'https://www.realsee.com/website/customer/dataSpace/vr/kPJJK5rx',
              },
            ],
          })
        ),
    };
  },
  onLoad(props) {
    console.log(props);
  },
  methods: {
    // 接收webview传来的消息
    onMessage(e) {
      const { data } = e.detail;
      console.log(
        data,
        'web-view传来的信息,在小程序后退、组件销毁、分享会触发'
      );
      console.log(data.at(-1));
      if (data?.at(-1)?.action === '咨询') {
        callPhone('18205236589');
      }
    },
  },
};
</script>
相关推荐
!win !13 分钟前
WebP图片使用踩坑
小程序·uniapp·webp
橘子海全栈攻城狮30 分钟前
[源码+调试+讲解]微信小程序的成都美食分享系统springboot
开发语言·spring boot·后端·微信小程序·小程序·美食
HDdgut33 分钟前
微信小程序base64图片与临时路径互相转换
微信小程序·小程序·base64·临时路径·filepath
Jiaberrr38 分钟前
微信小程序中 Echarts 的巧妙运用
前端·javascript·vue.js·微信小程序·echarts
雯0609~4 小时前
微信小程序:实现节点进度条的效果;正在完成的节点有动态循环效果;横向,纵向排列
微信小程序·小程序·notepad++
懒洋洋大魔王4 小时前
uni-app创建微信小程序
微信小程序·小程序·uni-app
我是唐赢4 小时前
微信小程序显示进度条showLoading,关闭进度条hideLoading,消息提示showToast,弹出窗showModal
微信小程序·小程序
我是唐赢4 小时前
微信小程序混入Behavior,实现Vue mixins同样功能
javascript·vue.js·微信小程序
尘浮生6 小时前
Java项目实战II基于Java+Spring Boot+MySQL的社区帮扶对象管理系统的设计与实现(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·mysql·微信小程序·小程序