乐趣区

关于vue.js:Vue微信开发中微信分享的优雅实现

前言

微信分享次要是能够把咱们做的网页分享给好友或者分享到朋友圈,在发送给好友时,展现进去的音讯不是一段很丑的网址,而是带着图文形容的非凡模板音讯,很多流传性质比拟强的网页都会借助这个个性晋升流传性。要实现这个性能,须要咱们接入微信的 JS-SDK,JS-SDK 是什么呢?官网文档介绍如下:

微信 JS-SDK 是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。
通过应用微信 JS-SDK,网页开发者可借助微信高效地应用拍照、选图、语音、地位等手机零碎的能力,同时能够间接应用微信分享、扫一扫、卡券、领取等微信特有的能力,为微信用户提供更优质的网页体验。

能够看到,JS-SDK 能做很多事件,那么明天,咱们先探讨对于微信分享的细节。如果你还须要实现微信受权登录相干的性能,那么能够查看笔者的这篇分享:
Vue 微信开发中受权登录的优雅实现

筹备

第一步,不必多说,同样是先熟读一遍官网文档,文档地址如下:
微信开发 JS-SDK 应用阐明文档
这里须要非凡阐明的是,在开发之前,须要先登录微信公众平台进入“公众号设置”的“性能设置”里填写“JS 接口平安域名”。
这个工作肯定不能忘,切记切记。
应用 JS-SDK 还有一个要害的环节,那就是通过 config 接口注入权限验证配置,而配置中有个 signature 参数是须要借助服务端获取的,所以咱们开发时仍然须要跪舔一波后端搭档给予反对(全栈的看官就当我没说)。
看完文档的看官们,应该都能梳理进去咱们接入微信分享的具体流程了,笔者梳理如下:

  1. 引入 JS-SDK;
  2. 通过调用后端接口获取签名,签名算法见该页;
  3. 调用 wx.config 办法注入相干配置;
  4. 调用相干的分享的 api,传入对应的分享信息;

    实现

    这里笔者以实现一个微信漂流瓶性能为例,分享一下编码过程;技术栈采纳的是 Vue3+typescript,Vue2 的开发者还请依据状况做适当调整。

    引入 JS-SDK

    官网文档的形容是引入 js-sdk 文件,即通过 script 形式引入,但咱们当初是 Vue 利用,那么能不能通过 npm 仓库装置通过 ESModule 形式引入呢?当然是能够的,装置命令如下:

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

笔者这里装置的是 ts 版本,装置完后,package.json 中显示了装置的版本

封装模块

本着性能解耦准则和不便复用,笔者决定独自新建一个文件,专门封装 js-sdk 相干的性能。在 vue3 中,当然是封装成 hook 啦。所以,咱们在 hooks 目录下,新建了一个 useWxSDK.ts 文件;
而后,开始封装第一个办法,即 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)
    })
  })
}

这里阐明一下 wx.config 办法,为啥要封装为 Promise 呢? 其实能够看到 JS-SDK 的 API 设计是比拟原始的,咱们须要通过 wx.ready 去注册配置胜利后的回调函数,笔者在这里用 Promise 封装,在 ready 回调函数里调用 Promise.resolve,那么咱们在用的时候,就能够通过优雅的 then 语法来实现配置胜利后的操作啦!

接下来封装分享好友和微信朋友圈的办法:

/** 设置微信分享 */
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()},
  })
}

接下来,开始搭积木。因为思考到分享这个操作,也是会在多个页面复用,那么有必要再形象一个分享的办法,这样在须要用到微信分享的中央间接调用该办法就行。因而,笔者又新建了一个 useWxShare.ts 文件

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,
      });
    });
  });
}

至此,封装结束,而后,咱们到页面组件到 mounted 函数里调用该办法,即可

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

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

补坑

这样就完结了吗?当然不是,这里边有个大坑,笔者在之前的博客中也分享过,就是如果咱们的页面是采纳的 Vue Router 的 history 模式的路由的话,在某些状况下,会呈现 iOS 设施上分享生效的问题。举个栗子。假如咱们都通过 http://domain.com 进入,而后跳转到路由为 /share 的页面须要用到 jssdk,那么理论 js-sdk 进行签名校验时所获取的以后页面 url 在 ios 和 andrioid 是不同的,在安卓上没有任何问题,js-sdk 校验的 url 就是以后页面的 url,也就是 http://domain.com/share。而在 iOS 上,js-sdk 校验的 url 是咱们刚进入页面时候的 url,也就是 http://domain.com,然而咱们后端那边签名用的是以后页面的 url,这就导致 iOS 上,签名校验不胜利。
那么该如何解决呢?笔者这边采取的方法是在入口文件或者根组件中记录以后页面 URL,在页面组件创立实现后,ios 获取记录的 url 进行签名,android 获取以后路由。所以填坑如下:
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)

看成果

首先咱们还是应用微信开发工具上看看成果
先,输出咱我的项目的地址

关上后,能够看到,获取 config 信息的申请已胜利发送和返回,再看控制台

控制台显示了 wx.config 的配置日志以及设置分享的日志,这个示意咱们的分享配置胜利了。点右上角分享,如果能显示咱们配置的分享题目,那就没问题啦。

最初,还是要在真机上试试看,真机上分享进去后,成果如下:

须要体验的小伙伴,能够在微信中扫下边二维码

同时,笔者曾经把我的项目的代码托管到了 Github 上,欢送有须要的小伙伴点击该链接自取

总结

其实微信分享相对来说,性能并不简单,难点在于如何得当的解决 JS-SDK 在单页利用上的一些坑。另外,也就是代码组织和封装的问题了,笔者看过很多我的项目,在代码复用和形象上没有多花心思,导致整个我的项目到处都是复制粘贴的反复代码,显得很臃肿。通过笔者这样解耦形象后,在调用层只须要简略的一个函数即可,是不是就显得分外的优雅呢?

写在最初

最近工作略微闲了些,笔者打算用 Vue3+ts+vant 从 0 开始实现一个公众号利用并将开发过程分享进去,也算是激励本人继续学习的一个形式吧。如果有想法和倡议,欢送找我探讨哦。
同时,为不便大家更好的探讨微信公众号开发相干技术,笔者也建了一个微信群,欢送退出和大家一起学习成长。

退出移动版