• 小程序的一些坑


    概述

    最近项目使用小程序的web-view把现有项目迁移到小程序里面去。有一些心得,记录下来供以后开发时参考,相信对其他人也有用。

    通用

    1.企业小程序需要把接口域名填入服务器域名,把web-view的网址域名填入业务域名,把小程序和运营的公众号绑定。

    2.授权。

    根据授权接口升级公告,无法使用 wx.getUserInfo 接口直接弹出授权框,但是wx.getUserInfo 接口仍旧可以使用。目前微信上的授权和登录一般有2种方式:

    1. 比较通用,具有独立的个人中心页,每次打开个人中心页都会向开发者服务器发送http请求,请求中有code,开发者服务器利用这个code向微信服务器获取用户数据来确定用户是否已经授权,如果没有授权就需要用户点击授权按钮,如果已经授权就顺便传回用户头像等信息。(这个方法适用于需要传回用户头像等信息的场合)
    2. 没有独立的个人中心页,也不需要开发者服务器传回用户头像等信息,直接用 wx.getSetting 接口判断用户是否已经授权,没授权则跳转授权页让用户点击授权按钮,已授权则走正常流程,示例代码如下:
    wx.getSetting({
      success: (settingRes) => {
        if (settingRes.authSetting['scope.userInfo']) {
          wx.showLoading({ title: 'Loading!' });
          wx.getUserInfo({
            success: (res) => {
              that.globalData.encryptedData = res.encryptedData;
              that.globalData.iv = res.iv;
              resolve(res);
            },
            fail: err => reject(err),
          })
        } else {
          // 未授权,跳转授权页
          wx.reLaunch({
            url: '../auth/index',
          });
        }
      },
      fail: err => reject(err),
    })
    

    3.接口封装

    因为小程序使用的微信api都是回调形式的,并且很容易嵌套,引起回调地狱。所以一般需要使用promise进行封装(如果要使用await的话,需要引入regenerator-runtime库)。使用promise进行封装还能利用catch很简便的处理error信息。示例代码如下:

    wxLogin: function () {
      const that = this;
      return new Promise((resolve, reject) => {
        wx.login({
          success: (res) => {
            that.globalData.loginCode = res.code;
            resolve(res);
          },
          fail: err => reject(err),
        });
      });
    },
    wxGetSetting: function () {
      const that = this;
      return new Promise((resolve, reject) => {
        wx.getSetting({
          success: (settingRes) => {
            if (settingRes.authSetting['scope.userInfo']) {
              wx.showLoading({ title: 'Loading!' });
              wx.getUserInfo({
                success: (res) => {
                  that.globalData.encryptedData = res.encryptedData;
                  that.globalData.iv = res.iv;
                  resolve(res);
                },
                fail: err => reject(err),
              })
            } else {
              // 未授权,跳转授权页
              wx.reLaunch({
                url: '../auth/index',
              });
            }
          },
          fail: err => reject(err),
        })
      });
    },
    onLoad(options) {
      const that = this;
      this.handleUrlFromShare(options);
      app.wxLogin()
        .then(res => app.wxGetSetting())
        .then(res => that.requestCodeApi())
        .catch((err) => {
          wx.hideLoading();
          this.setData({
            isFirstLogin: true,
          });
    
          // 正常登陆
          if (err.hideToast) return;
          // 登陆失败
          that.showErrorToast(err, 'Login Again Please!');
          console.log('Login failed-------', err);
        });
    },
    

    web-view组件的使用

    小程序的web-view是承载网页的容器,相当于iframe。它会自动铺满整个小程序页面,个人类型与海外类型的小程序暂不支持使用,并且 navigationStyle: custom 对 组件无效

    1.web-view 里面的项目可以通过判断 userAgent 中包含 miniProgram 字样来判断小程序 web-view 环境(微信7.0.0以上)。示例代码如下:

    export function isMiniProgram() {
      return !!navigator.userAgent.match(/miniProgram/i);
    }
    

    2.不能在web-view里面打开新窗口,所以在项目上需要判断小程序环境,在需要新窗口打开的时候变成本窗口打开。

    3.分享

    在有 web-view 的小程序页面可以利用 options.webViewUrl 拿到 web-view 里面的网址,然后在分享的时候带上这个网址,在跳转页面判断是否有url参数来接收这个网址。

    需要注意的是,

    1. 如果网址中有token等信息,需要先去掉这个信息。
    2. 如果网址中有汉字等符号,就需要使用encodeURIComponent转义一下。
    3. 有些时候,可能需要双重转义才能拿到想要的url。

    示例如下:

    deleteTkAndRtk: function(url) {
      const host = url.slice(0, url.indexOf('?'));
      let queryArr = url.slice(url.indexOf('?') + 1, url.length).split('&');
    
      queryArr = queryArr.filter(
        query => query.indexOf('tk=') === -1 && query.indexOf('rtk=') === -1);
    
      if (queryArr.length !== 0) {
        return host + '?' + queryArr.join('');
      }
    
      return host;
    },
    onShareAppMessage: function (options) {
      const url = options.webViewUrl;
      const filteredUrl = this.deleteTkAndRtk(url);
      return {
        path: `pages/index/index?url=${encodeURIComponent(filteredUrl)}`,
        title: 'YiDrone',
      }
    },
    onLoad: function (options) {
      if (options.url) {
        this.setData({
          // 这里的encodeURI必不可少。。。
          yidroneUrl: encodeURI(decodeURIComponent(options.url)),
        })
      }
    },
    

    4.jssdk

    web-view中的项目可以给小程序发送信息,还可以控制小程序的页面跳转,方法如下:

    // 首先在项目内引入 weixin-js-sdk 库
    npm install weixin-js-sdk --save
    
    // 然后在plugin文件夹建立 wx-sdk.js
    import Vue from 'vue';
    import wx from 'weixin-js-sdk';
    
    Vue.prototype.$wx = wx;
    
    // 然后在main.js里面判断小程序环境按需引入 wx-sdk.js
    // weixin-js-sdk
    try {
      if (isMiniProgram()) {
        import('./plugins/wx-sdk').then(() => {});
      }
    } catch (err) {
      console.error('>>>wx-sdk', err);
    }
    
    // 最后在需要的地方进行操作
    if (isMiniProgram() && this.$wx) {
      // 不能使用这个格式:this.$wx.miniProgram.postMessage({ data: 'bar' });
      this.$wx.miniProgram.postMessage({ data: { foo: 'bar' } });
      this.$wx.miniProgram.navigateTo({ url: '../auth/index' });
    }
    
    // 在小程序的web-view组件加入 handleBindmessage 事件
    <web-view src="{{ url }}" bindmessage="handleBindmessage"></web-view>
    
  • 相关阅读:
    .NET Tools...
    函数重载
    友元课后题
    怎么防止用户输入错误信息
    C#动态求圆的面积
    重载自增
    C++数学应用
    位运算符
    MSDN放出了VS2010简体中文正式版(附下载地址)
    字符串复制
  • 原文地址:https://www.cnblogs.com/yangzhou33/p/10723134.html
Copyright © 2020-2023  润新知