preface

Wechat sharing is mainly to share the web pages we do to friends or to share to the circle of friends. When sending to friends, the message displayed is not a very ugly WEBSITE, but a special template message with graphic description. Many pages with strong communication nature will use this feature to enhance communication. To achieve this function, we need to access the Js-SDK of wechat. What is jS-SDK? The official documentation is as follows:

Wechat JS-SDK is a web development kit provided by wechat public platform for web developers based on wechat. Through the use of wechat JS-SDK, web developers can take advantage of wechat’s ability to efficiently use mobile phone systems such as photo taking, photo selection, voice, location, and other capabilities. Meanwhile, they can directly use wechat’s unique capabilities such as sharing, scanning, card coupons, and payment to provide better web experience for wechat users.

As you can see, JS-SDK can do a lot of things, so today, we first discuss the details about wechat sharing. If you also need to achieve wechat authorized login related functions, then you can view the author of this share: Vue wechat development authorized login elegant implementation

To prepare

The first step, needless to say, is also to peruse the official document, the document address is as follows:

Wechat development JS-SDK usage instructions document

What needs special note here is that before development, it is necessary to log in to the wechat public platform and enter the “function setting” of the “public account setting” and fill in the “JS interface security domain name”. This job must not forget, keep it in mind. There is also a key step to use JS-SDK, that is to verify the configuration through the config interface injection permission, and there is a signature parameter in the configuration that needs to be obtained by the server, so we still need to licking a wave of backend partners to support the development. After reading the document, the readers should be able to sort out the specific process of our access to wechat sharing. The author combs it as follows:

  1. Introduction of JS – SDK;
  2. Obtain the signature by invoking the back-end interface. For the signature algorithm, see this page.
  3. Call the wx.config method to inject the relevant configuration;
  4. Call the relevant sharing API and pass in the corresponding sharing information;

implementation

Here, the author takes the realization of a wechat drifting bottle function as an example to share the coding process; The tech stack is Vue3+typescript, developers of Vue2 should adjust accordingly.

Introduction of JS – SDK

The official documentation describes the introduction of JS-SDK files, i.e. through script mode, but we are now Vue application, so can we use NPM repository installation through ESModule mode? Of course it can, the installation command is as follows:

// JS version YARN add weixin-js-sdk // TS version yarn add weixin-js-sdK-tsCopy the code

The author installed the TS version here, and after the installation, the package.json shows the installed version

Encapsulated module

In line with the principle of functional decoupling and convenient reuse, the author decided to create a separate file to specifically encapsulate jS-SDK-related functions. In VUE3, of course, it is packaged as hooks. So, in the hooks directory, create a new usewxsdK. ts file. Then, start encapsulating the first method, wx.config

/** * Initialize the Settings */
function initConfig(configInfo) {
  return new Promise((resolve) = > {
    wx.config({
      debug: false.appId: configInfo.appId,
      timestamp: configInfo.timestamp,
      nonceStr: configInfo.nonceStr,
      signature: configInfo.signature,
      jsApiList: configInfo.jsApiList ?? [
        'chooseImage'.'uploadImage'.'previewImage'.'onMenuShareTimeline'.'onMenuShareAppMessage'.'chooseWXPay',].openTagList: [],
    })
    wx.ready(() = > {
      resolve(true)})})}Copy the code

The wx.config method is encapsulated as a Promise. In fact, the API design of JS-SDK is relatively primitive. We need to register the callback function with wx.ready, which is wrapped with Promise. In the ready callback function, we call Promise. You can use elegant then syntax to implement successful configuration operations.

Next, encapsulate the method of sharing friends and wechat circle of friends:

/** Set wechat sharing */
function setShareInfo(ShareInfo, onSuccess and onCancel) {
  wx.onMenuShareTimeline({
    title: shareInfo.title, // Share the title
    link: shareInfo.link, // Share link, can not be the current page, the link domain name or path must be the same as the current page corresponding public number JS security domain name
    imgUrl: shareInfo.imgUrl,
    success: function () {
      // The callback function executed after the user confirms the share
      onSuccess()
    },
    cancel: function () {
      onCancel()
      // The callback function executed after the user cancels the share
    },
  })
  wx.onMenuShareAppMessage({
    title: shareInfo.title, // Share the title
    desc: shareInfo.desc,
    link: shareInfo.link, // Share link, can not be the current page, the link domain name or path must be the same as the current page corresponding public number JS security domain name
    imgUrl: shareInfo.imgUrl,
    type: 'link'.// Share type: music, video, or link. The default value is link
    success: function () {
      // The callback function executed after the user confirms the share
      onSuccess()
    },
    cancel: function () {
      // The callback function executed after the user cancels the share
      onCancel()
    },
  })
}
Copy the code

Next, start building blocks. Considering that the operation of sharing will be reused in multiple pages, it is necessary to abstract a method of sharing, so that the method can be directly called where wechat sharing is needed. Therefore, I created a new usewxshare.ts file

import { getJsSDKConfigApi } from "@/api/wechat";
import { useWxSDK } from "@/hooks/useWxSDK";

export function useWxShare(shareConfig: {
  title: string;
  imgUrl: string;
  desc: string;
}) {
  const { initConfig, setShareInfo } = useWxSDK();

  const shareUrl = window.location.href.split("#") [0];

  getJsSDKConfigApi(shareUrl).then((config) = > {
    // Call the backend interface to obtain config information
    initConfig(config).then(() = > {
      // After wx.config is successfully injected, wechat share is setsetShareInfo({ ... shareConfig,link: shareUrl,
      });
    });
  });
}
Copy the code

Mounted (); / / Mounted (); / / Mounted (); / / Mounted (); / / Mounted (

<script> import { useWxShare } from '@/hooks/useWxShare' export default defineComponent({ setup() { }, Mounted () {useWxShare({title: 'this is the caption ', imgUrl: 'http://yourimg.com/share-pic.png',})},}) </script>Copy the code

patching

Is that the end of it? Of course not, there is a big problem, which I shared in my previous blog, that sharing will not work on iOS devices in some cases if our pages are routed using Vue Router history mode. Here’s an example. Assuming that we enter through http://domain.com and then jump to the page whose route is /share, JSSDK is needed, then the actual url of the current page obtained by JS-SDK during signature verification is different on ios and Android, and there is no problem on Android. The URL of jS-SDK verification is the URL of the current page, that is, http://domain.com/share. However, on iOS, the URL of JS-SDK verification is the URL when we just enter the page, that is, http://domain.com. However, we use the URL of the current page to sign on the back end, which leads to the failure of signature verification on iOS. So how to deal with it? The method adopted by the author is to record the current page URL in the entry file or root component. After the page component is created, ios obtains the recorded URL for signature, and Android obtains the current route. So the pit filling is as follows:

App.vue

import { defineComponent } from 'vue'
import { useWxSDK } from '@/common/hooks/useWxSDK'
import { commonStore } from '@/store/modules/common'

export default defineComponent({
  name: 'App'.setup() {
    const { isiOSWechat } = useWxSDK()
    // If ios wechat is detected, the address of the entry page will be recorded in store
    if (isiOSWechat()) {
      const url = window.location.href.split(The '#') [0]
      commonStore.saveVisitUrl(url)
    }
  },
})
</script>
Copy the code

@/hooks/useWxSDK.ts

  /** Whether is ios wechat */
  function isiOSWechat() {
    return (window as any).__wxjs_is_wkwebview
  }
Copy the code

@/hooks/useWxShare.ts

import { getJsSDKConfigApi } from '@/api/wechat'
import { useWxSDK } from '@/common/hooks/useWxSDK'
import { commonStore } from '@/store/modules/common'

export function useWxShare(shareConfig: { title: string; imgUrl: string; desc: string }) {
  const { initConfig, setShareInfo, isiOSWechat } = useWxSDK()

  const shareUrl = window.location.href.split(The '#') [0]
  // Make a special judgment on the signed URL
  const signatureUrl = isiOSWechat() ? commonStore.commonState.visitUrl : shareUrl

  getJsSDKConfigApi(signatureUrl).then((config) = > {
    initConfig(config).then(() = >{ setShareInfo({ ... shareConfig,link: shareUrl,
      })
    })
  })
}
Copy the code

@/store/modules/common.ts

import { Module, VuexModule, Mutation, getModule } from 'vuex-module-decorators'
import store from '@/store'
import { initialUnencryptedStorage } from '.. /globals'

interface CommonState {
  /** ios wechat account, record the page URL */
  visitUrl: string
}

const NAME = 'common'

@Module({
  namespaced: true.name: NAME,
  dynamic: true,
  store,
  preserveState: Boolean(initialUnencryptedStorage[NAME]),
})
export class Common extends VuexModule {
  commonState: CommonState = {
    visitUrl: ' ',}@Mutation
  saveVisitUrl(url: string) :void {
    this.commonState.visitUrl = url
  }
}

export const commonStore = getModule<Common>(Common)
Copy the code

See the effect

First of all, let’s use wechat development tools to see the effect. First, enter the address of our projectOnce opened, you can see that the request for config information was successfully sent and returned, and then look at the consoleThe console shows the wx.config configuration log and the log setting sharing, which indicates that our sharing configuration was successful. Click share in the upper right corner, if you can display the share title we configured, that is no problem.

Finally, try it on the real machine. After sharing it on the real machine, the effect is as follows:

If you need to experience it, you can scan the qr code in wechat

At the same time, the author has hosted the code of the project on Github, and you are welcome to click the link to help yourself

conclusion

In fact, wechat sharing relatively speaking, the function is not complex, the difficulty lies in how to properly deal with jS-SDK in the single page application of some pits. In addition, it is also the problem of code organization and encapsulation. I have seen many projects, but they do not pay much attention to code reuse and abstraction, resulting in the whole project is full of duplicate code copy and paste, which is very bloated. After the decoupling of the authors, the call layer only needs a simple function, isn’t it particularly elegant?

Write in the last

Recently, my work is a little bit idle. I plan to use Vue3+ TS +vant to complete a public account application from 0 and share the development process, which is also a way to motivate myself to continue learning. If you have any ideas or suggestions, please contact me. At the same time, in order to facilitate us to better discuss the development of wechat public number related technologies, the author also built a wechat group, welcome to join us to learn and grow together.