Vue开发公众号踩坑记录及打包部署总结

流氓凡 技术分享 2020-11-05 7.06 K 0

本文篇幅应该很长,但是应该能解决大部分新手遇到的坑吧

准备工作

首先使用Vue开发微信公众号肯定需要 JSSDK ,否则将无法使用分享、支付等功能。(微信授权登录不需要)

npm install weixin-js-sdk

这里我查看很多很多教程,没有找到一个让我满意的封装方法,所以接下来就是踩坑第一坑:封装wx.方法后续可以复用更加方便

在main.js中引入 JSSDK,然后在Vue的原型链上挂载一个全局方法,利用回调使其wx方法复用性更高:

import wx from 'weixin-js-sdk'

// 微信工具类初始化
Vue.prototype.wechatUtil = function (resolve, reject) {
    let _this = this
    _this._get('wxapp/wechatUtil', {
        url: window.location.href
    }, res => {
        if (res.data.appId) {
            wx.config({
                debug: false,
                appId: res.data.appId,
                timestamp: res.data.timestamp,
                nonceStr: res.data.nonceStr,
                signature: res.data.signature,
                jsApiList: res.data.jsApiList
            })
            wx.ready(res => {
                // 微信SDK准备就绪后执行的回调。
                resolve && resolve(wx, res);
            })
        } else {
            reject && reject(res)
        }
    })
}

方法中有_this._get() 没必要去管,意思就是请求我后端的接口返回的 wx.config()所需要的数据,如何获取wx.config()所需要的数据请看官方文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62

在页面调起分享例子,这里将所有的分享封装一个方法,需要注意的是,我这边测试 “wx.updateAppMessageShareData”和“wx.updateTimelineShareData”是无法自定义标题和描述(仅测试了ios端)

        // 初始化分享
        shareInit() {
            let _this = this;
            _this.wechatUtil((wx, res) => {
                // 这里就可以直接使用wx.方法了  就是这么简单
                let shareData = {
                    title: _this.shareTitle, // 分享标题
                    desc: _this.shareContent, // 分享描述
                    link: _this.copyUrl, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                    imgUrl: _this.promoteImg, // 分享图标
                };
                // 分享到朋友
                wx.onMenuShareAppMessage(shareData);
                // 分享到朋友圈
                wx.onMenuShareTimeline(shareData)
                // 分享到qq
                wx.onMenuShareQQ(shareData);
                // 分享到qq空间
                wx.onMenuShareQZone(shareData);
                // 分享到新浪微博
                wx.onMenuShareWeibo(shareData);
            });
        },


在页面调起支付例子:同样支付我也是在main.js中封装公共方法,同样挂载到Vue原型链上提供全局调用

// 构建微信支付请求
Vue.prototype.wxPayment = function (option) {
    let _this = this;
    // 整理请求参数
    let options = Object.assign({
        payment: {},
        success: () => {
        },
        fail: () => {
        },
        complete: () => {
        },
    }, option);
    
    // 调起微信支付方法
    _this.wechatUtil((wx, res) => {
        wx.chooseWXPay({
            timestamp: options.payment.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
            nonceStr: options.payment.nonceStr, // 支付签名随机串,不长于 32 位
            package: 'prepay_id=' + options.payment.prepay_id, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
            signType: 'MD5', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
            paySign: options.payment.paySign, // 支付签名
            success: function (res) {
                options.success(res);
            },
            fail(res) {
                options.fail(res);
            },
            complete(res) {
                options.complete(res);
            }
        });
    });
}

// 页面中调起微信支付
pay(){
    _this.wxPayment({
      payment: result.data.payment,
      success() {
         _this.$toast.success('支付成功', {
             onClose: _this.onClose()
         });
      },
      fail(res) {
         _this.$toast.fail(result.msg.error);
      },
      complete(res) {
      }
    });
},

需要注意此是,微信支付无法在微信开发者工具上调起,因此必须上传到线上开发环境进行手机端测试。

既然是上传就涉及到了打包绑定的问题,接下来说下打包后自动上传到服务器上

在 package.json 文件中添加一个 push  使用scp -r 进行打包上传,比如说我的根目录是/www,将127.0.0.1换成自己的服务器ip

"scripts": {
        "serve": "vue-cli-service serve",
        "build": "vue-cli-service build",
        "lint": "vue-cli-service lint",
        "push": "npm run build && scp -r dist/* root@127.0.0.1:/www"
    },

每次打包后会自动请求上传的到服务器中,但是每次都是需要输入密码的,接下来使用git bash或者powershell执行ssh-keygen可以生成ssh key。会询问生成的key存放地址,直接回车就行,如果已经存在,则会询问是否覆盖:

ssh-keygen

如果你配置了git仓库就不要执行了  可以直接进行下一步了,否则git仓库存储的key会失效,后续要 重新生产才可以继续push项目到仓库了

接下来同步ssh key到远程服务器,使用ssh-copy-id指令同步, 还是一样替换127.0.0.1为你的服务器ip然后进行输入密码

ssh-copy-id -i ~/.ssh/id_rsa.pub root@127.0.0.1

输入密码后,之后再次同步就不需要输入密码了。其实ssh_key是同步到了服务器(此处是root用户家目录)~/.ssh/authorized_keys文件里:


基本告一段了,接下来说下登陆授权。这一般是开发刚刚开始的时候,我们关注一个自己的测试号然后搭建一个内网的本地开发环境进行微信授权登录的调试吧。

https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

image.png

image.png

image.png

这是我的测试号信息配置,可以参考下。

登录就比较简单了,这里新建一个login.vue页面进行登陆授权跳转,需要用到的是Vue-ls缓存插件用来缓存用户的登陆token,下面是安装方法和简单的使用方法

npm install vue-ls --save
import Storage from 'vue-ls'

new Vue({
    el: '#app',
    mounted: function() {
        Vue.ls.set('foo', 'boo');
        // 设置有效期
        Vue.ls.set('foo', 'boo', 60 * 60 * 1000); //有效1小时
        Vue.ls.get('foo');
        Vue.ls.get('boo', 10); // 如果没有设置boo返回默认值10 
        
        let callback = (val, oldVal, uri) => {
          console.log('localStorage change', val);
        } 
        
        Vue.ls.on('foo', callback) //侦查改变foo键并触发回调 
        Vue.ls.off('foo', callback) //不侦查
        
        Vue.ls.remove('foo'); // 移除
    }
});
// login.vue 登陆流程开始

created() { //视图加载前执行
  let _this = this
  if (_this.$ls.get('token')) {
      _this.$router.push('/')
      return false
  }
  let code = _this.getUrlKey('code')
      code ? _this.doLogin(code) : _this.getLoginCode()
},


  // 请求接口取得用户登陆要授权跳转的地址,后端api接口回调地址还是回到这个页面的路由
  getLoginCode: function () {
    let _this = this
    _this._post_form('user/getCode', {}, res => {
        window.location.href = res.data.url
    })
  },
  
  // 根据授权后取得的code进行授权登录
  doLogin: function (code) {
    let _this = this
    _this._post_form('user/userLogin', {
        code: code
    }, result => {
        console.log(result);
    });
},

    // 格式化code 在main.js挂载到Vue原型上
    Vue.prototype.getUrlKey = function (string) {
        return decodeURIComponent((new RegExp('[?|&]'+string+'='+'([^&;]+?)(&|#|;|$)').exec(location.href)||[,""])[1].replace(/\+/g,'%20'))||null;
    }

到这里登陆就完成了

本篇完全没有后端代码,因为后端代码基本都是工厂模式,所以单独拆分出来也是比较看所以有机会在说吧。

评论