Two methods of using WX-JSSDK in vue

The company has recently had the demand for WeChat public address, so WeChat's login authorization and how to use WX-JSSDk to share are all the most troublesome problems. I also developed the WeChat public number for the first time. I read a lot of blogs on the Internet. Finally, I selected two methods and tested them effectively.

1, Through global, defined in router.afterEach

1. First, through yarn add Weixin JS SDK / NPM I Weixin JS SDK
2. Mount the wechat jsdk to the global
Create WechatPlugin.js in utils directory
WechatPlugin.js

import wx from 'weixin-js-sdk'

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

export default plugin
export const install = plugin.install

main.js medium

import WechatPlugin from './utils/WechatPlugin'
// Register wechat jsdk globally
Vue.use(WechatPlugin)

3. In router.aftereach

import wechatUtil from '@/utils/wechatUtil' // Some ways to define wechat in this file
router.afterEach((to, from) => {
 let path = to.fullPath.slice(1) // Remove '/'
    let url
    const jsApiList = [
      'onMenuShareAppMessage',
      'onMenuShareTimeline',
      'chooseWXPay',
      'showOptionMenu',
      "updateAppMessageShareData",
      "hideMenuItems",
      "showMenuItems"
    ]

    if (!sessionStorage.getItem('initLink')) {
      // Solve the problem of unsuccessful sharing signature under ios wechat, and cache the first entered url.
      sessionStorage.setItem('initLink', document.URL)
    }
    if (!!window.__wxjs_is_wkwebview) {
      // ios
      url = sessionStorage.getItem('initLink')
      wechatUtil.setWeChatConfig(url, jsApiList)
    } else {
      // Android
      url = location.origin + process.env.BASE_URL + path
      // setTimeout(() => {
      wechatUtil.setWeChatConfig(url, jsApiList)
      // }, 0)
    }
})
 

3. In wechatutil.js

import Vue from 'vue'
export default {
  appid: process.env.VUE_APP_WECHAT_APPID, // You can configure appid according to different environments
  setWeChatConfig(url, jsApiList) {
    getSignature(decodeURIComponent(url)) // getSignature needs your own interface when requesting signature with backend contract
      .then(data => {
        Vue.wechat.config({
          debug: false,
          signature: data.signature,
          nonceStr: data.nonceStr,
          timestamp: data.timestamp,
          appId: data.appId,
          jsApiList
        })
      })
      .catch(err => {
        console.log(err)
      })
  }
 }

Although the above method can be used globally, there will be a problem. When a single page calls the updateapmessagesharedata method or other methods in the wechat jsddk, sometimes it succeeds and sometimes fails. This may be the asynchronous problem of the wechat jsdk. Therefore, you need to add setTimeout (() = > {"call wechat interface here"}, 500) when you use it in a single page.

The second method below I think is the most convenient and customized one, which can be accessed on the required page.

Two. Method two is encapsulated into a unified entry through new promise, and is invoked in a single page.

We still need to record the entered url in router.afterEach. I put it on the vuex (pay special attention to the difference between Apple phone and Android phone here, and I won't explain it much here, because the url in Apple browser is the first url coming in)
1. In router.afterEach

import store from '@/store'
router.afterEach((to, from) => {
  let path = to.fullPath.slice(1) // Remove '/'
  if (!sessionStorage.getItem('initLink')) {
    // Solve the problem of unsuccessful sharing signature under ios wechat, and cache the first entered url.
    sessionStorage.setItem('initLink', document.URL)
  }
  let url
  if (!!window.__wxjs_is_wkwebview) {
    // ios
    url = sessionStorage.getItem('initLink')
  } else {
    // Android process.env.base? URL defines the domain name variables in each environment
    url = location.origin + process.env.BASE_URL + path
  }
    store.commit('page/setInitLink', url)
})

2. In store/page.js

const state = {
  initLink: ''
}
const mutations = {
 setInitLink (state, initLink) {
    state.initLink = initLink
  }
}

export default {
  namespaced: true,
  state,
  mutations
}

3. Define initialization method in utils/wechatUtil.js

import wx from 'weixin-js-sdk'
import store from '@/store'

export default {
  /* Initializing various interfaces of wxjsdk */
  init(apiList = [], url) {
    //List of APIs to use
    return new Promise((resolve, reject) => {
      getSignature(store.state.page.initLink).then(res => {
        if (res.appId) {
          wx.config({
            // debug: true, 
            appId: res.appId,
            timestamp: res.timestamp, 
            nonceStr: res.nonceStr, 
            signature: res.signature,
            jsApiList: apiList
          })
          wx.ready(res => {
            // Callback executed after wechat SDK is ready.
            resolve(wx, res)
          })
        } else {
          reject(res)
        }
      })
    })
  }
}

4. Use in page

import wechatUtil from '@/utils/wechatUtil'
  wechatUtil
        .init([
          'updateAppMessageShareData',
          'onMenuShareAppMessage',
          'onMenuShareTimeline',
          'updateTimelineShareData'
        ])
        .then((wx, res) => {
         	// Wechat interface here
        })

Conclusion: at last, I recommend the second method. Although the first method is very convenient, it calls wechat to obtain the signature initialization method for each route jump. Moreover, the user-defined scalability is not very strong, and there will be problems of asynchronous wechat interface, which requires debu: true debugging in wechat. The second method is relatively simple to use and define.

33 original articles published, praised 23, visited 100000+
Private letter follow

Keywords: Vue SDK iOS Android

Added by ignorant on Fri, 17 Jan 2020 10:33:40 +0200