Vue 应用中使用微信 jssdk

关于微信jssdk

通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。

如:微信分享

  • 原始分享效果


    image.png
  • 使用微信JS-SDK的分享效果

image.png
准备工作

1. 拥有一个微信公众平台的账号

2. 绑定域名
微信公众平台管理界面左侧-公众号设置

image.png

3. 开发相关配置信息获取
微信公众平台管理界面左侧-开发-基本配置
image.png

image.png

拿到appId和appsecreat以及配置ip白名单。这主要是作用于后端,访问微信接口生成JS-SDK配置相关信息传回给前端。

文档地址

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432

image.png

熟悉微信相关api

  • 通过wx.config接口注入权限验证
    所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用.
wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名
    jsApiList: [] // 必填,需要使用的JS接口列表
});

config里所需的appId,timestamp,nonceStr ,signature 需要后端人员提供;

交互过程如下:
我们提供当前网页的URL,不包含#及其后面部分给后端 ->后端通过公众号的appID和appsecret获取access_token,再通过access_token获取jsapi_ticket-> 生成JS-SDK权限验证的签名了。

image.png

  • 通过ready接口处理成功验证
  // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中
wx.ready(function(){
});
  • 通过error接口处理失败验证
wx.error(function(res){
    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
vue项目接入微信jssdk

还记得在之前的准备工作中,我们就已经配置了js安全域名。所以现在只要关心如何在程序中接入jssdk。我着重介绍以vue应用中,如何引入jssdk。

这里我们可以使用vux中的wechatPlugin。不使用vux也没关系。其实原理很简单,这个插件的作用主要是提供了commonJS的引入方式,所以我们不需要在 index.html 引入文件。并且将wx对象绑定在了vue原型上和对象属性上。那么之后任何组件中都可以通过 this.$wechat 访问到 wx 对象。源码如下:

const wx = require('./1.3.2.js').wx

const plugin = {
  install (Vue) {
    Vue.prototype.$wechat = wx
    Vue.wechat = wx
  },
  $wechat: wx
}

export default plugin
export const install = plugin.install

下面正式介绍如何使用

  • 在 main.js 中全局引入:
import { WechatPlugin } from 'vux'
Vue.use(WechatPlugin)
console.log(Vue.wechat) // 可以直接访问 wx 对象。
  • 注入相关配置信息

main.js

import {wechatUtil} from '@/util'
wechatUtil.setWechatConfig(window.location.href.split('#')[0])
  • 组件中使用
 <template>
     <div>测试微信</div>
</template>

<script>
import {wechatMixin} from '@/mixins'
import {urlUtil} from '@/util'
export default {
  name: '',

  mixins: [wechatMixin],

  components: {},

  props: {},

  data () {
    return {

    }
  },

  computed: {},

  watch: {},

  created () {},

  mounted () {
    this.bindShareTimeLine()
    this.bindShareAppMessage()
  },

  destroyed () {},

  methods: {
    // 微信朋友圈
    bindShareTimeLine () {
      this.onMenuShareTimeline({
        title: '发送到朋友圈', // 分享标题
        link: location.href.split('#')[0], // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
        imgUrl: `${urlUtil.getProjectPath()}/static/img/share.jpg`, // 分享图标
        success: function () {
    // 用户点击了分享后执行的回调函数
        }
      })
    },
    // 发送给朋友
    bindShareAppMessage () {
      this.onMenuShareAppMessage({
        title: '发送给朋友', // 分享标题
        desc: '这里是描述信息', // 分享描述
        link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
        imgUrl: `${urlUtil.getProjectPath()}/static/img/share.jpg`, // 分享图标
        type: '', // 分享类型,music、video或link,不填默认为link
        dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
        success: function () {
// 用户点击了分享后执行的回调函数
        }
      })
    }
  }
}
</script>

<style scoped>

</style>

wechatMixin

// 定义一个混入对象
import {wechatUtil} from '@/util'

export let wechatMixin = {
 methods: {
   onMenuShareTimeline: function (config) {
     wechatUtil.shareTimeline(config)
   },
   onMenuShareAppMessage: function (config) {
     wechatUtil.shareAppMessage(config)
   }

 }
}

wechatUtil.js


import * as api from '@/api'
import Vue from 'vue'

export default {
  isReady: false,
  /** 注册微信jssdk ready和error事件 */
  bindWechatEvent (readyEvent, errorEvent) {
    this.registerReadyEvent(readyEvent)
    this.registerErrorEvent(errorEvent)
  },
  /** ready事件 */
  registerReadyEvent (fn) {
    let _this = this
    Vue.wechat.ready(function () {
      _this.isReady = true
      fn()
    })
  },
  /** error事件 */
  registerErrorEvent (fn) {
    Vue.wechat.error(fn)
  },
  /** wechat jssdk接入配置 */
  setWechatConfig (url, apiList) {
    api.getSignature(url).then(({data}) => {
      Vue.wechat.config({...data, ...{jsApiList: apiList}})
    }).catch(err => {
      console.log(err)
    })
  },
     /** ready事件前置处理判断,确保函数都在ready中执行 */
  readyPreProcess: function (fn) {
    if (this.isReady) {
      fn()
    } else {
        // 等ready方法执行后再执行这个函数
      Vue.wechat.ready(function () {
        fn()
      })
    }
  },
  // 发送给朋友圈
  shareTimeline (config) {
    this.readyPreProcess(() => {
      Vue.wechat.onMenuShareTimeline(config)
    })
  },
  // 发送给朋友
  shareAppMessage (config) {
    this.readyPreProcess(() => {
      Vue.wechat.onMenuShareAppMessage(config)
    })
  }

}

urlUtil


export default {
  // 得到当前项目的访问路径
  getProjectPath () {
    var url = window.self.location.toString()
    return url.substring(0, url.indexOf('/', url.indexOf('://', 0) + 3))
  }
}

  • 常见问题解决方法
    1、下图所示问题需要检查config中的jsApiListt参数中是否配置了此api。
{errMsg: "onMenuShareAppMessage:fail, the permission value is offline verifying"}。

2、如果发现只生效了部分参数,如分享给朋友时,分享的标题和描述都生效了,只是缩略图未正常显示,需要配置的imgUrl地址是否是网络图片。
3、安卓端不支持透明的分享图标,会将图片透明背景变成黑色,注意检查图片。
4、其他错误可根据error中的报错信息根据公众平台帮助文档按顺序检查解决。

调试技巧
  • 通过微信提供的测试号中的appid和appsecret进行接口获取。
    如果在项目开发调试阶段,自己注册了微信公众平台进行调试,账户主体信息是个人的话,账号没法进行认证,有很多接口都没有权限。


    image.png
image.png
  • 内网穿透
    因为微信js安全域名需要能够外网访问的域名或者ip。所以我们需要将外网域名地址映射到本地,随时修改代码看效果。这类的工具很多,网速不一定。如:sunny-ngrok,想要网速快一点可以找运维把公司的某个域名请求转发到你本机。

  • 微信开发者工具
    公众号网页调试,开发者可以调试微信网页授权和微信JS-SDK


    image.png
  • 移动端调试工具
    由于在移动端无法打开控制台,所以没办法打印调试console的数据和查看网络请求。可以在index.html中引入vconsole。

<script src="path/to/vconsole.min.js"></script>
<script>
  // init vConsole
  var vConsole = new VConsole();
</script> 

如果有eslint红线报错,可以.eslintignore文件中忽略检查,配置如下。

/build/
/config/
/dist/
/static/
/*.js
/*.html

vconsole效果如下

image.png

源码

服务器端 (node):https://github.com/tangyuhui/wechat-node-jssdk
前端(vue):https://github.com/tangyuhui/wechat-vue-hash-demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352