8

Preface

Wechat sharing is mainly to share the webpage we made to friends or to the circle of friends. When sending to friends, the displayed message is not a very ugly URL, but a special template message with graphic descriptions. Many spreads Web pages with a strong nature will use this feature to improve dissemination. To realize this function, we need to access WeChat's JS-SDK. What is JS-SDK? The official documents are as follows:

WeChat JS-SDK is a -based web development kit provided by the public platform 1614af55daf7ef for web developers.
By using WeChat JS-SDK, web developers can use WeChat to efficiently use mobile phone systems such as taking pictures, selecting pictures, voice, location, etc., and can directly use WeChat's unique capabilities such as sharing, scanning, card coupons, and payment. , To provide a better web experience for WeChat users.

As you can see, JS-SDK can do a lot of things, so today, let's discuss the details of sharing on WeChat. If you still need to implement the functions related to WeChat authorized login, then you can check this author's share:
Elegant implementation of authorized login in Vue WeChat development

Prepare

The first step, needless to say, is also to familiarize yourself with the official document first. The document address is as follows:
WeChat development JS-SDK instruction document
What needs special explanation here is that before development, you need to log in to the WeChat public platform and enter the "Function Settings" of the "Official Account Settings" to fill in the "JS Interface Security Domain Name".
This job must not be forgotten, remember to remember.
There is another key link in using JS-SDK, which is to inject permissions to verify the configuration through the config interface, and there is a signature parameter in the configuration that needs to be obtained with the help of the server, so we still need to kneel and lick a wave of back-end partners when we develop Support (the full-stack judge just assumed that I didn't say it).
After reading the document, the reviewers should be able to sort out the specific process of accessing WeChat to share. The author sorts out as follows:

  1. Introduce JS-SDK;
  2. Obtain the signature by calling 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 related sharing api and pass in the corresponding sharing information;

    accomplish

    Here the author takes the implementation of a WeChat drift bottle function as an example to share the coding process; the technology stack uses Vue3+typescript, and Vue2 developers should also make appropriate adjustments according to the situation.

    Introduce JS-SDK

    The description of the official document is to introduce js-sdk files, that is, through script, but we are now a Vue application, so can it be introduced through ESModule through npm warehouse installation? Of course it is possible, the installation command is as follows:

// js版本
yarn add weixin-js-sdk
// ts版本
yarn add weixin-js-sdk-ts

The author here installs the ts version. After installation, the installed version is displayed in package.json
image.png

Package module

Based on the principle of functional decoupling and convenient reuse, the author decided to create a new file to encapsulate js-sdk related functions. In vue3, of course, it is packaged as a hook. Therefore, we created a useWxSDK.ts file 0614af55dafad5 in the hooks directory;
Then, start to package the first method, which is wx.config

/**
 * 初始化设置
 */
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)
    })
  })
}

Here is an explanation of the wx.config method, why should it be encapsulated as a Promise? In fact, we can see that the API design of JS-SDK is relatively primitive. We need to register the callback function after successful configuration through wx.ready. The author uses it here Promise encapsulation, call Promise.resolve in the ready callback function, then when we use it, we can implement the operation after the configuration is successful through the elegant then syntax!

Next, encapsulate the method of sharing friends and WeChat Moments:

/** 设置微信分享 */
function setShareInfo(shareInfo,onSuccess, onCancel) {
  wx.onMenuShareTimeline({
    title: shareInfo.title, // 分享标题
    link: shareInfo.link, // 分享链接,可以不是当前页面,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
    imgUrl: shareInfo.imgUrl,
    success: function () {
      // 用户确认分享后执行的回调函数
      onSuccess()
    },
    cancel: function () {
      onCancel()
      // 用户取消分享后执行的回调函数
    },
  })
  wx.onMenuShareAppMessage({
    title: shareInfo.title, // 分享标题
    desc: shareInfo.desc,
    link: shareInfo.link, // 分享链接,可以不是当前页面,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
    imgUrl: shareInfo.imgUrl,
    type: 'link', // 分享类型,music、video或link,不填默认为link
    success: function () {
      // 用户确认分享后执行的回调函数
      onSuccess()
    },
    cancel: function () {
      // 用户取消分享后执行的回调函数
      onCancel()
    },
  })
}

Next, start building blocks. Because the sharing operation is considered to be reused on multiple pages, it is necessary to abstract another sharing method, so that it can be called directly wherever WeChat sharing is needed. Therefore, the author created a useWxShare.ts file 0614af55dafb52

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) => {
    // 调用后端接口获取config相关信息
    initConfig(config).then(() => {
      // 注入wx.config成功后,设置微信分享相关
      setShareInfo({
        ...shareConfig,
        link: shareUrl,
      });
    });
  });
}

At this point, the encapsulation is complete, and then we go to the page component to call this method in the mounted function, and you can

<script>
import { useWxShare } from '@/hooks/useWxShare'

export default defineComponent({
  setup() {
  },
  mounted() {
    useWxShare({
      title: '这是标题',
      desc: '这是描述',
      imgUrl: 'http://yourimg.com/share-pic.png',
    })
  },
})
</script>

Patch the pit

Is this the end? Of course not. There is a big pit here. I also shared it in my previous blog. If our page is routed using the history mode of Vue Router, in some cases, sharing on iOS devices will fail. The problem. Give a chestnut. Suppose we all http://domain.com, and then jump to the page routed as /share need to use jssdk, then the current page url obtained when the actual js-sdk performs signature verification is in ios and andrioid Different, there is no problem on Android. The url verified by js-sdk is the url of the current page, which is http://domain.com/share. On iOS, the url verified by js-sdk is the url when we first entered the page, which is http://domain.com, but our back-end signature uses the url of the current page, which leads to iOS On the above, the signature verification was unsuccessful.
So how to deal with it? The method I took here 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 fill the pit 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()
    // 检测到是ios微信,则把入口页地址记录到store中
    if (isiOSWechat()) {
      const url = window.location.href.split('#')[0]
      commonStore.saveVisitUrl(url)
    }
  },
})
</script>

@/hooks/useWxSDK.ts

  /** 是否是ios微信 */
  function isiOSWechat() {
    return (window as any).__wxjs_is_wkwebview
  }

@/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('#')[0]
  // 对签名url做特殊判断处理
  const signatureUrl = isiOSWechat() ? commonStore.commonState.visitUrl : shareUrl

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

@/store/modules/common.ts

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

interface CommonState {
  /** ios微信用,记录访问时候页面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)

See effect

First of all, let's use the WeChat development tool to see the effect
First, enter the address of our project
image.png
After opening, you can see that the request to obtain config information has been successfully sent and returned, and then look at the console
image.png
The console shows the configuration log of wx.config and the log of setting sharing. This indicates that our sharing configuration is successful. Click on the upper right corner to share, if the share title we configured can be displayed, then there is no problem.
image.png
Finally, you still have to try it on the real device. After sharing it on the real device, the effect is as follows:
image.png
For those who need experience, you can scan the QR code in WeChat
image.png
At the same time, the author has hosted the code of the project on Github, welcome friends in need click on the link

Summarize

In fact, WeChat sharing is relatively uncomplicated. The difficulty lies in how to properly handle some pitfalls of JS-SDK in single-page applications. In addition, it is the problem of code organization and encapsulation. The author has seen many projects and did not pay much attention to code reuse and abstraction. As a result, the entire project is full of duplicate code copied and pasted, which is very bloated. After the author's decoupling and abstraction like this, only a simple function is needed at the call layer. Does it seem extraordinarily elegant?

Write at the end

Recently, I have been a little idle. I plan to use Vue3+ts+vant to complete an official account application from 0 and share the development process. It can be regarded as a way to motivate myself to continue learning. If you have ideas and suggestions, please come to me for discussion.
At the same time, in order to facilitate everyone to better discuss the related technology of WeChat official account development, the author has also established a WeChat group, welcome to join and learn and grow together. Scan the QR code below in WeChat to apply to join the group.
image.png


imwty
1.1k 声望99 粉丝

Enjoy creating rather than coding!