这段开发小程序和微信公众号的日子

502 阅读5分钟

这段时间都在开发小程序和微信公众号,一波三折终于稍微稳定一些有空写写流水账。

基于mpvue的小程序登录流程

先上流程图,原流程图地址:https://www.processon.com/view/link/5b18ee97e4b03f9d2514771c

在开发期间,恰好碰上了wx.getUserInfo这个接口的修改,官方此接口有调整:“使用该接口将不再出现授权弹窗,请使用 <button open-type="getUserInfo"></button> 引导用户主动进行授权操作”。但截止到发文章为止,线上环境调用这个接口如果用户未授权的话仍可以弹出授权弹窗,即使到时确实不可以了,按照文档的说法,仅仅是“当用户未授权过,调用该接口将直接报错”,所以我们捕捉到这个错误就不往下执行,然后再通过 <button open-type="getUserInfo"></button>埋点到需要登录授权的地方就可以顺利兼容两种登录方式了。所以,我们需要写一个组件去处理登录授权的逻辑。

封装checkLogin组件(伪代码)

<template>
  <div :style="{position: 'relative', width: wrapWidth, height: wrapHeight}">
    <button 
            style="border:none;position: absolute;top: 0;bottom: 0;right: 0;left: 0;z-index: 10;padding: 0;"
            :style="{top: btnTop, left: btnLeft, width: btnWidth, height: btnHeight}"
            @getuserinfo="bindgetuserinfo"
            open-type="getUserInfo"
            plain='true'></button>
    <slot></slot>
  </div>
</template>

<script>
  import {mapActions} from 'vuex'
  import {STORE_PATH_GLOBAL, USERINFO_BE_AUTHORIZED, USERINFO_REFUSED_AUTHORIZED} from 'CONST'
  export default {
    props: [
      /*
       ----------------兼容slot bug begin----------------
      */
      'money',
      /*
       ----------------兼容slot bug end----------------
      */
      // 授权与登录都成功后需要执行的逻辑 Function
      'afterPassAuthorize',
      'wrapWidth',
      'wrapHeight',
      'btnTop',
      'btnLeft',
      'btnWidth',
      'btnHeight'
    ],
    methods: {
      ...mapActions(STORE_PATH_GLOBAL, ['afterWxGetUserInfo']),
      /**
       * open-type="getUserInfo"的button授权后的回调
       */
      async bindgetuserinfo (data) {
        const userInfo = data.mp.detail.userInfo
        // 如果用户授权 则会有userInfo
        const isAuthorizeUserInfo = userInfo ? USERINFO_BE_AUTHORIZED : USERINFO_REFUSED_AUTHORIZED
        // 用户授权后进行登录
        if (isAuthorizeUserInfo) {
          await this.afterWxGetUserInfo(userInfo)
          this.handleAfterPassAuthorize()
        }
      },
      /**
       * 处理授权与登录都成功后需要执行的逻辑
       */
      handleAfterPassAuthorize () {
        this.afterPassAuthorize && this.afterPassAuthorize()
      }
    }
  }
</script>

使用方法:

<template>
    <checkLogin :money="money" :afterPassAuthorize="pay">
        <div>点击支付{{money}}元</div> 
    </checkLogin>
</template>
<script>
    export default {
        data () {
            return {
                money: 10
            }
        },
        methods: {
            pay () {
                alert('登录后进行进行支付')
            }
        }
    }
</script>

这样就可以比较方便地进行登录授权埋点,需要注意的是,为什么要额外在checkLogin组件props一个money属性呢?是因为mpvue最新版本(mpvue:1.0.12;mpvue-loader:1.0.14;mpvue-template-compiler:1.0.12;)的一个Bug,这个Bug是slot的作用域是该组件,所以要想slot中的money能渲染出来,需要把money这个属性传进checkLogin组件里。虽然这样写非常冗余,但是在Bug没解决之前,似乎也没别的办法(如果有麻烦告诉我一下哈)。

微信公众号本地调试

“基于微信小程序平台运营规范,除小游戏类目的安卓内购功能,小程序暂不支持虚拟支付。请开发者们对当前小程序内含有虚拟支付的内容或服务进行排查并整改。如在5月8日前未完成整改,平台将对账号屏蔽iOS系统的支付接口调用。”无奈之下,只好再开发一个微信公众号进行支付。

公众号开发基本可以从mpvue那边复用过来,所以页面和逻辑基本不用动,烦人的是公众号的SDK调试。因为要调试SDK,需要“先登录微信公众平台进入'公众号设置'的'功能设置'里填写'JS接口安全域名'。”比如你填的域名是“juejin.im”,那调试的时候需要访问“juejin.im/yourpath”,但是本地开发的时候,都是访问“localhost:8080/yourpath”,总不能本地开发好了部署上去然后进行调试吧?所以我们的需求是:

在PC本地开发,不需要部署,立马就可以在开发者工具中调试

步骤一:在“C:\Windows\System32\drivers\etc”修改hosts文件

这样一来,当我们在地址栏里访问“juejin.im”时,就会变成访问127.0.0.1(即localhost)

步骤二:用nginx,使得通过域名“juejin.im”访问(域名访问默认访问80端口)时转发到本地开发时起的web服务器127.0.0.1:8080。nginx配置:

http {
    upstream juejin.im {
     server 127.0.0.1:8080; 
    }
    server {
        listen 80;
        server_name juejin.im ;
        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass https://juejin.cn;   
        }
    }
}

至此,当我们在微信开发者工具中访问juejin.im/yourpath就是访问你本地的localhost:8080/yourpath,这样就可以愉快地进行本地调试啦。

手机能调试PC本地开发的代码

当然,只是PC能调试还不够,如果真机也需要调试的话,只需要:

步骤一:下载一个Charles作为代理 Charles中的Help/Local IP Address可以查看到本机的IP地址,然后看看代理的端口号,默认就是8888

步骤二:保证手机与PC处于同一网段 步骤三:需要把PC的防火墙关闭,不然手机访问不到PC。这里我遇到了一个坑,我已经关了windows的防火墙了,但是还是访问不了,原来还需要把这个也关了:
步骤四:将手机的代理服务器主机名填上你PC的IP地址,代理服务器端口填上8888,这时Charles会弹出询问是否允许xxxIp访问,点击允许即可。 最后,手机访问juejin.im/yourpath就可以访问到PC本地的开发代码了。

同时使用flexible和vux

做移动端开发肯定对这两个库不陌生,flexible做移动端适配,vux是基于微信ui的vue ui库,但flexible会依赖px2rem-loader进行px转rem,但是微信ui也是使用px的,这样一来当px2rem-loader进行px转rem,会把vux依赖的微信ui也转成rem,这是我们不希望的。所以我们需要在build/webpack.base.conf.js配置一下:

module.exports = vuxLoader.merge(webpackConfig, {
  options: {},
  plugins: [
    {
      name: 'vux-ui'
    },
    {
      name: 'after-less-parser',
      fn: function (source) {
        // 需要注意vux的版本,我使用的是2.9.1
        if (this.resourcePath.replace(/\\/g, '/').indexOf('/_vux@2.9.1@vux/src/components') > -1) {
          source = source.replace(/px/g, 'PX')
        }
        // 自定义的全局样式大部分不需要转换
        if (this.resourcePath.replace(/\\/g, '/').indexOf('App.vue') > -1) {
          source = source.replace(/px/g, 'PX').replace(/-1PX/g, '-1px')
        }
        return source
      }
    },
    {
      name: 'style-parser',
      fn: function (source) {
        if (this.resourcePath.replace(/\\/g, '/').indexOf('/_vux@2.9.1@vux/src/components') > -1) {
          source = source.replace(/px/g, 'PX')
        }
        // 避免转换1PX.less文件路径
        if (source.indexOf('1PX.less') > -1) {
          source = source.replace(/1PX.less/g, '1px.less')
        }
        return source
      }
    }
  ]
})

这样你在写样式的时候,直接写px,就只会将你的样式转成rem,不会影响到vux。

以上就是我在这段时间开发小程序和公众号时遇到的注意点,如果对大家有一点帮助,就非常开心啦~