最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 微信小程序开发与踩坑记录

    正文概述 掘金(智云健康大前端团队)   2021-07-14   1063

    作者: qiuwww

    1. 大家业务可能需要 h5 嵌入到小程序中,以及设置分享等,以及一些注意点;
    2. 个人的小程序的开发经验总结;

    ? 开发相关

    1、使用 web-view 加载 h5 与设置当前页面的小程序分享

    web-view 文档

    小程序的 web-view 与一般的 iframe 异同

    相似的地方

    1. 都用来加载在线的动态资源,如 html,pdf 之类的,web-view 是网页的原生载体,用于在原生环境中加载一个页面,iframe 是网页的 html 载体,用于在网页中加载一个新的动态资源。

    差异的地方

    1. 小程序内的 web-view 限制很严格:
      1. web-view 加载的 url 需要在后台配置域名白名单,包括内部再次 iframe 内嵌的其他 url;
        1. 小程序限制加载的资源都是 https 请求的,所以有时候出现加载不出来的问题,很可能就是接口或者页面地址有问题;
        2. 另外一个问题就是,进行真机测试的时候最好不要开开发调试模式,可能就会漏掉一些问题;
    2. web-view 会自动铺满整个小程序页面,且默认展示到最上边一层,不能被覆盖;
    3. 小程序端 web-view 组件一定有原生导航栏,下面一定是全屏的 web-view 组件,navigationStyle: customweb-view 组件无效。
    4. 小程序不能获取 web-view 对象,也就是内外完全隔离,不能通过获取组件引用来操作;
      1. 嵌入的 web-view 网页只能 postMessage 给小程序,且小程序只能在特定时机(小程序后退、组件销毁、分享)触发并收到消息。也就是说,消息不是实时的,会存储到一个数组中在以上时机一起被拿到,web-view 发送的消息会一直累加,这个数组长度一直变大;
      2. bindload,这个方法开发者工具无效,测试的时候发现,只要地址格式正确就认为是成功了,就会被触发,并不是页面加载完整才触发;
      3. binderror,这个方法开发者工具无效,地址格式出错就认为加载失败,真正没加载出来也不会触发;

    web-view 加载 h5 页面

    1. 需要在 url 获取到的时候再渲染web-view组件,否则可能出现空白页;
    <template>
      <view class="common-webview">
        <web-view v-if="url" class="web" :src="url" @message="onWebMessage" />
      </view>
    </template>
    
    1. @message接受页面发出的消息,需要内嵌小程序引入微信的 sdk,然后使用wx.miniProgram.postMessage({ data: 'foo' })来发消息;
    2. web-view,内嵌 h5 需要打开小程序页面可以调用小程序的跳转方法进行跳转,这里注意 tab 页面只能使用wx.miniProgram.switchTab,来跳转。
    (window as any).wx.miniProgram.navigateTo({
      url: `/pages/common/webview?url=${encodeURIComponent(resolveH5Url)}`
    });
    

    web-view页面的分享设置

    1. 最直观的方式,就是打开小程序页面的时候,同时传递分享的标题和图片,如下:
      1. 这样做主要是针对一些 h5 代码不能修改的情况,或者加载的一组 h5 页面分享的标题不改变的情况,对于需要不断切换分享内容的情况,是不能实现的;
    // 在h5中使用 wx.miniProgram.navigateTo
    wx.navigateTo({
      url: `/pages/common/webview?url=${encodeURIComponent(jumpUrl)}&imageUrl=${imageUrl}&title=${title}`
    });
    
    1. 对于自己可控的 h5 页面,可以使用postMessage的方式,将需要分享的参数动态的发给小程序页面,这样让小程序页面通过当前的 url 来匹配这里的 message 对象,从而拿到分享的信息,具体操作如下:
    // h5操作
    if (env.inWechatMiniProgram) {
      (window as any).wx.miniProgram.postMessage({
        data: {
          title: title || '', // 分享的title
          imageUrl: imageUrl || '', // 分享的展示图片
          pageUrl: window.location.href, // 当前页面的url,需要作为key来识别消息
        }
      });
    }
    
    // 小程序端
    // 点击分享的时候,会调用两个函数,一个是onShareAppMessage,一个是onWebMessage(前)
    // 接受postMsg的消息列表,进入页面或者点击操作的时候会发送消息,在小程序的分享按钮被点击的时候这里会被调用,调用在onShareAppMessage前
    async onWebMessage({ detail: message }) {
      this.messageList = message.data || [];
    }
    
    // 点击分享按钮,当前函数会被调用
    async onShareAppMessage(options = {}) {
      const { webViewUrl } = options;
      const searchCurOptions = this.messageList.reverse().find(item => item.pageUrl === webViewUrl) || {};
      console.log("这里就是当前分享的信息", searchCurOptions)
    }
    

    需要更多的配置,也是可以添加参数来实现的。

    2、页面模式及标题栏返回

    页面模式

    页面开发模式

    可以通过设置 pages.json 中的页面的 navigationStyle 为 custom 来自定义导航栏。

    1. default,不设置的默认模式,常规页面操作流程;
    2. custom,自定义导航栏,通常用于首页展示或者自定义标题栏,但是对于web-view页面无效;

    标题栏的返回问题

    由于小程序只会在小程序页面间跳转的时候,默认标题栏出现返回按钮,所以如果在 tabbar 页面嵌入 h5,h5 内部的跳转是不能出现返回按钮的,所以需要特殊处理:

    1. 如果第一个打开的是一个内嵌 h5 的页面,则当前页面的跳转,都需要调用小程序接口来进行跳转
    2. 出现返回按钮之后的页面,则不需要使用了;
    wx.miniProgram.navigateTo({
      url: `/pages/common/webview?url=${encodeURIComponent(jumpUrl)}&imageUrl=${imageUrl}&title=${title}`
    });
    

    3、分包的问题

    微信小程序分包

    为什么需要分包

    微信客户端在打开小程序之前,会把整个小程序的代码包下载到本地的,这种策略可以缓解页面跳转时白屏的问题。同时微信还对小程序代码包大小设置了 2M (最初只有 1M)的上限来确保小程序能有还不错的启动速度。

    分包应该注意的地方

    1. 微信小程序每个分包的大小是 2M,总体积一共不能超过 20M;
    2. 需要尽量保持主包只加载必须的内容,主要包括一些必须公共资源/JS 脚本,tabBar 页面,最好只包括这些页面;
    3. 分包越早越好,如果后期进行分包,不然后期进行分包,就要处理前期被内部及外部调用的地址;
      1. 对于已经对外放出的页面就更没法修改了;
      2. 页面不能通过路由进行重定向,也就是路由与页面位置是绝对对应的;
    4. 主包不可以引用子包内容,子包只可以引用自己包内和主包内的内容,子包内不能嵌套子包;
      1. 独立分包是小程序中一种特殊类型的分包,可以独立于主包和其他分包运行。从独立分包中页面进入小程序时,不需要下载主包。当用户进入普通分包或主包内页面时,主包才会被下载,这个我们通常不会用到。
    5. 子包预下载:开发者可以通过配置,在进入小程序某个页面时,由框架自动预下载可能需要的分包,提升进入后续分包页面时的启动速度。对于独立分包,也可以预下载主包。

    4、小程序开发配置 condition

    uni-app 设置 condition

    可以在不必将要开发的页面每次写到 pages.json 的 pages 下的第一个,也可以保证小程序每次刷新的时候,选择的编译模式能用。

    {
      "condition": {
        "current": 0,
        "list": [
          {
            "name": "index",
            "path": "pages/index/index",
            "query": "isShowHelp=1"
          }
        ]
      }
    }
    

    5、小程序与 h5 及小程序之间的跳转的一些规则

    1. 小程序的分享,只能是小程序打开;
    2. 公众号的分享只能是公众号打开;
    3. 小程序内通过web-view,可以打开 h5;
    4. 小程序跳转小程序是没什么限制的,只要知道对方的 appid 以及跳转的目标页面就可以了,也可以设置跳转的是体验版/开发版/正式版本
      1. 正式版本只能跳转正式版本;
    5. h5 打开小程序,h5 需要引入微信的 sdk,设置调用的功能,然后通过开放标签跳转;
    6. 小程序不能跳转公众号,但是可以使用 official-account 组件关注关联的公众号;
    7. 打开 App,当小程序从 APP 打开的场景打开时(场景值 1069),小程序会获得返回 APP 的能力,此时用户点击按钮可以打开拉起该小程序的 APP。即小程序不能打开任意 APP,只能 跳回 APP。
    <script>
      // 小程序跳转小程序
      wx.navigateToMiniProgram({
        appId: appid, // 对方小程序的appid
        path: path, // 目标页面的地址,需要的参数可以直接拼写到后边,path 中 ? 后面的部分会成为 query
        extraData: {
          // 需要传递给目标小程序的数据
          foo: 'bar'
        },
        envVersion: 'release', // 要打开的小程序版本。仅在当前小程序为开发版或体验版时此参数有效。如果当前小程序是正式版,则打开的小程序必定是正式版。
        success(res) {
          // 打开成功的后续操作,比如埋点什么的
          // wxTelescope(baseKey + '-skip');
        }
      });
    </script>
    
    <!-- h5跳转小程序 -->
    <script>
      // 需要配置
      wx.config({
        openTagList: ['wx-open-launch-weapp']
      });
    </script>
    <!-- 跳转按钮 -->
    <wx-open-launch-weapp
      class="launch-btn"
      :username="tagUsername"
      :path="tagPath"
      @error="handleErrorFn"
      @launch="handleLaunchFn"
    >
      <script type="text/wxtag-template">
        <div style="padding: 10000px">
          跳转按钮
        </div>
      </script>
    </wx-open-launch-weapp>
    

    ? 踩坑

    1、渠道参数处理

    小程序生命周期-热启动/冷启动及其相关参数获取

    小程序的运行机制

    • 冷启动:如果用户首次打开,或小程序销毁后被用户再次打开,此时小程序需要重新加载启动,即冷启动。
    • 热启动:如果用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时小程序并未被销毁,只是从后台状态进入前台状态,这个过程就是热启动。
      • 常见如,启动后,扫码重新打开某个页面,或者点击配置的公众号导航等;

    参数获取方式的区别

    1. wx.getLaunchOptionsSync
      1. 获取小程序启动时的参数。与 App.onLaunch 的回调参数一致。
      2. 拿到的参数是冷启动的时候拿到的。无论从哪里进来,在没有杀死进程的时候,该方法拿到的数据就是一样的。
    2. wx.getEnterOptionsSync,获取本次小程序启动时的参数。
      1. 如果当前是冷启动,则返回值与 App.onLaunch 的回调参数一致,也就是与 wx.getLaunchOptionsSync 一致;
      2. 如果当前是热启动,则返回值与 App.onShow 一致
      3. 所以这里可以保持每次获取的参数与当前的启动参数是保持一致的,热启动的参数可以覆盖同名参数。
    3. 当小程序被销毁的时候,两个参数都是获取不到想要的值的,所以对于进入后台的小程序,如果没必要就要主动关闭,避免放置一段时间后,再次打开造成参数错误;
      1. 当小程序进入后台,可以维持一小段时间的运行状态,如果这段时间内都未进入前台,小程序会被销毁。
      2. 当小程序占用系统资源过高,可能会被系统销毁或被微信客户端主动回收。

    渠道设置与获取

    // 设置channel,与一般的参数类似,可以通过修改小程序后台体验码来控制打开的参数,模拟渠道投放
    
    // pages/index/index?channel=3UAKHCEV
    
    // 获取当前的channel,可以针对不同的参数,做一些屏蔽或者替换操作
    export const getChannel = () => {
      const { query } = wx.getEnterOptionsSync();
      const { channel } = query;
      return channel;
    };
    

    2、微信生成小程序二维码 scene 参数过长的方法

    小程序二维码 scene 参数限定长度为 32 位字符,但是实际开发中可能有很多的参数需要传递,比如pages/common/webview?url=https%3A%2F%2Fstatic.qa.91jkys.com%2Ff2e%2Fcustomer-h5-im%2F%23%2Fquick-ask%3FcurChannelInDisableList%3D0%26channel%3D27,这个时候就需要通过特殊处理之后才能使用,常见方式如下:

    1. 中间页 + 短参数;
      1. 会多出来一次跳转;
    2. 短参数(当前选择的方案);
      1. 目前在进入页面时先判断是否有 scene 的值,如果有再请求接口获取完整的参数(json 格式),然后再使用这个参数去调真正的业务接口;
      2. 这种方式要确认好,会被打开的页面;
    // 调用
    let options = wx.getEnterOptionsSync();
    options = await queryLaunchParams(options);
    
    // 方法定义:这里处理扫面二维码的时候,通过二维码的短参数获取存在数据库中的全部参数的操作
    export const queryLaunchParams = async (options = {}) => {
      if (options.scene) {
        const { qrScene } = await store.dispatch('global/getParams', { destScene: options.scene });
        return { ...options, ...queryString.parse(qrScene) };
      } else {
        return options;
      }
    };
    

    3、web-view 打开 pdf 文件

    不能直接打开线上的 pdf,具体的步骤如下

    1. 线上文件下载到本地,uni.downloadFile;
    2. 本地打开所下载的 pdf,uni.openDocument

    具体代码:

    // 1. 这里要通过线上的地址去下载pdf,然后获取本地地址,之后再使用web-view打开
    export const getDocumentLocalPath = (url = '') => {
      const types = ['.pdf'];
      const filterArr = types.filter(item => {
        return url.includes(item);
      });
    
      if (filterArr.length < 1) {
        return;
      }
      const fileType = filterArr[0];
    
      return new Promise((resolve, reject) => {
        wx.downloadFile({
          url,
          success: function(res) {
            const filePath = res.tempFilePath;
            console.log('getDocumentLocalPath', url, filePath);
            wx.openDocument({
              filePath: filePath,
              fileType: fileType.slice(1),
              success: function(res) {
                // 使用pdf本地地址作为webview的地址,需要回退一下,不然就会有一个白页
                uni.navigateBack({
                  delta: 1
                });
                resolve(filePath);
              }
            });
          },
          fail: function(e) {
            reject(e);
          }
        });
      });
    };
    
    // 2. 使用
    const url = await getDocumentLocalPath(url);
    // webview是可以打开本地生成的地址的
    this.url = url;
    

    起源地下载网 » 微信小程序开发与踩坑记录

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元