评论

小程序webview使用

由于小程序包大小的限制, 把小程序改造成webview嵌套方式。

一、使用原因

  1. 由于小程序包大小8M的限制 (之前版本)
  2. 我们组做的是公共活动、工具,业务方会拉取我们的代码, 新活动会不断添加
  3. H5小程序都做,维护成本会比较高

二、webview引入思路

  1. webview 安全域名申请
  2. 访问原先小程序活动重定向到webview容器页面并且在url后面追加一些参数(h5页面需要)
  3. 实现公共的webview页面,需要功能:分享回调、h5路径转发、身份token透传、刷新H5页面
  4. H5页面实现功能兼容, 一些活动配置项、分享标题、分享图片、打点(跟小程序和h5环境相关)

三、代码实现

原小程序页面重定向webview页面方法包装

小程序webview代码实现

Page({
  /**
   * 页面的初始数据
   */
  data: {
    url: ''// webview 地址
    shareData: {}, // 分享参数
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options{
      // TODO 登录信息获取
  },
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function (options{
    // 这里把网址编码了下,用户分享的卡片进去的时候会在onload中得到webview的网址,解码后赋值给src属性就行了
    let that = this
    const shareInfo = {
      title: that.data.shareData.title,
      path: `/pages/hudong/common/pages/hdview/index?url=${encodeURIComponent(that.data.shareData.url)}`,
      imageUrl: that.data.shareData.imgUrl
    }
    return shareInfo
  },
  /**
  * 分享回调
  */
  onShareback() {
    let that = this
    // 分享成功后 通知h5页面(h5有配置xxxback的话), 调用之后需要手动删除 xxxback
    that.refreshH5(that.data.shareData.xxxback)
    delete that.data.shareData.xxxback
  },
  /**
  * 初始化信息
  */
  initData(options, userInfo = {}) {
    let url = decodeURIComponent(options.url);
    const { openid, appid, token } = userInfo;
    let statType = ''
    // 记录当前options的链接
    this.data.shareData.url = url
    // h5链接xxxxxxx=xxxxxxxxx 标识
    const navUrl = `${url}${url.indexOf('?') > -1 ? '&' : '?'}xxxxxxx=${token}&dotStatType=${statType}`
    this.setData({
      url: navUrl
    })
  },
  // 接收h5发送的数据
  getMessage(e) {
    const that = this
    const data = e.detail.data
    let action = ''
    // 注意:每次发送数据后数据会添加到e.detail.data中的数组,
    // 并不会清除掉上一次传递的数据,所以我们取数组的最后一位 
    if(data.length > 0) {
      let item = data[data.length - 1]
      action = item.action
      switch(action) {
        case 'share':
          that.dealH5Share(item)
          break
        case 'saveFormId': // TODO 
          that.dealSaveFormId(item)
          break
      }
    }
  },
  // 处理接收到h5数据 分享操作 
  dealH5Share(data) {
    const that = this
    if(data) {
      that.data.shareData = data
    }
  },
  // 处理接收到h5数据 保存formId操作 (待拓展)
  dealSaveFormId() {
    // TODO
    debugger
  },
  // 刷新H5页面当前
  refreshH5(xxxback) {
    if(typeof xxxback != 'object') {
      return false
    }
    const oldUrl = this.data.url
    let newUrl = oldUrl
    const oldParams = ParseURL(oldUrl)
    // 删除历史
    oldParams.xxxback && (newUrl = newUrl.replace(`xxxback=${oldParams.xxxback}```))
    newUrl += `&xxxback=${(JSON.stringify(xxxback))}`
    this.setData({
      url: newUrl
    })
  }

H5分享相关改造

  /** 
  * 获取指定的URL参数值 
  * 参数:paramName URL参数 
  * 调用方法:getQueryParam("name") 
  * 返回值:tyler 
  */
  function _getQueryParam(paramName) {
    paramValue = "", isFound = !1;
    if (window.location.search.indexOf("?") == 0 && window.location.search.indexOf("=") > 1) {
      arrSource = decodeURIComponent(window.location.search).substring(1, window.location.search.length).split("&"), i = 0;
      while (i < arrSource.length && !isFound) arrSource[i].indexOf("=") > 0 && arrSource[i].split("=")[0].toLowerCase() == paramName.toLowerCase() && (paramValue = arrSource[i].split("=")[1], isFound = !0), i++
    }
    return paramValue == "" && (paramValue = null), paramValue
  }
  // 判断是否是小程序环境
  function IsMiniProgramEnv(fun) {
    // 通过navigator.userAgent 判断
    var bl = navigator.userAgent && navigator.userAgent.indexOf('miniProgram') > -1
    if (typeof fun == 'function') {
      fun(bl)
    }
  }
  // 初始化执行
  IsMiniProgramEnv(function (bl) {
    if (bl) {
      IsInMiniProgram = true
      // 判断是否是小程序环境
      _initMiniData()
    }
  })
  // 设置小程序分享
  function SetMiniProgramShare(url, title, imgUrl, fun) {
    if (title && url && imgUrl) {
      IsMiniProgramEnv(function (bl) {
        if (bl) {
          // 向小程序发送消息
          var data = {
            action: 'share'// 触发修改分享参数动作
            url: url,
            title: title,
            imgUrl: imgUrl
          }
          if(typeof fun === 'function') {
            data.xxxback = fun() || {}
          }
          wx.miniProgram.postMessage({ datadata })
        }
      })
    }
  }
  // H5跳转小程序路径
  function _NavigateToMiniProgram(url) {
    var newUrl = '/pages/hudong/common/pages/bridge/index?url=' + encodeURIComponent(url)
    wx.miniProgram.navigateTo({
      url: newUrl
    })
  }
  function _initMiniData() {
    
  }
  // 重新包装链接跳转, 用于跳转业务方的小程序地址或者h5页面地址
  function HrefToBusiness(url) {
    if(!url) {
      return false;
    }
    // 是小程序环境, 并且不是h5链接
    if(IsInMiniProgram && url.split("?")[0].indexOf('http') == -1) {
      _NavigateToMiniProgram(url)
    } else {
      window.location.href = url
    }
  }


webview改造原有小程序项目利弊

优点

  1. 减少小程序包大小
  2. 提升开发、迭代效率
  3. 大多数需求可省去审核流程,h5最新的功能就是小程序功能

缺点

  1. 用户体验不如原生小程序
  2. 不能用复杂的动画交互,简单页面还可以
  3. 权限限制比较多,例如不能 埋点弹起授权手机号授权等
  4. h5、小程序通讯限制太多,具体可参考微信文档


点赞 7
收藏
评论

4 个评论

  • 장수연.(七七)
    장수연.(七七)
    2020-07-06

    有人遇到过打开web-view先显示空白后来又正常出现页面的情况吗,间隔3-5s

    2020-07-06
    赞同
    回复 3
    • K&K
      K&K
      2020-07-29
      你好,遇到了相同的问题,想问下现在知道是什么原因造成的吗
      2020-07-29
      回复
    • 장수연.(七七)
      장수연.(七七)
      2020-07-29回复K&K
      不知道
      2020-07-29
      回复
    • K&K
      K&K
      2020-07-29回复장수연.(七七)
      好的,谢谢
      2020-07-29
      回复
  • Amy
    Amy
    2020-06-03

    你好,请问这个小程序里面是只有一个用web-view加载的页面吗?这个样子审核能通过吗?

    2020-06-03
    赞同
    回复
  • 微盟小程序-温如邦13691728173
    微盟小程序-温如邦13691728173
    2020-03-14

    666

    2020-03-14
    赞同
    回复
  • 探索者
    探索者
    2020-03-09

    小程序已经授权登录了,点击进入内嵌的关联公众号H5,是否会自动关联到该用户呢?

    2020-03-09
    赞同
    回复 1
    • RM317.com
      RM317.com
      2020-03-19
      关联到用户,需要把公众号+小程序创建关联 这样可以获取的同一个unionId,用unionid同步用户信息
      2020-03-19
      回复
登录 后发表内容