返回

历经坎坷终解决 —— Vue2.0(history模式)下微信自定义分享

前端

前言

某日,笔者需要在Vue2.0项目(history模式)中实现微信自定义分享功能,然而,在开发过程中却遇到了一个又一个坑,经过两天的努力,终于成功解决了问题。现将踩坑经历和解决方案整理成文,希望能给其他开发者一些参考和借鉴。

正文

踩坑历程

坑一:公众号安全域名配置不当

在进行微信自定义分享之前,需要先配置公众号安全域名。笔者一开始没有仔细阅读微信官方文档,直接将项目域名填入安全域名中,导致微信JS-SDK无法正常工作。后来仔细阅读文档后,发现需要将项目域名下的所有二级域名都填入安全域名中,问题才得以解决。

坑二:没有注入配置信息

根据微信官方文档,所有需要使用JS-SDK的页面必须先注入配置信息。笔者一开始没有理解这句话的含义,以为只要在项目中引入微信JS-SDK库就可以使用JS-SDK了。后来才发现,需要在每个需要使用JS-SDK的页面中手动注入配置信息,包括appId、timestamp、nonceStr、signature等参数。

坑三:没有正确使用ready方法

微信JS-SDK提供了ready方法,用于监听微信JS-SDK的加载状态。笔者一开始没有使用ready方法,导致在微信中分享时,提示“微信JS-SDK未加载”。后来按照官方文档的说明,在页面中添加了ready方法,问题才得以解决。

解决方案

解决方案一:正确配置公众号安全域名

在配置公众号安全域名时,需要将项目域名下的所有二级域名都填入安全域名中。否则,微信JS-SDK无法正常工作。

解决方案二:注入配置信息

在每个需要使用JS-SDK的页面中,需要手动注入配置信息,包括appId、timestamp、nonceStr、signature等参数。否则,微信JS-SDK无法正常工作。

解决方案三:正确使用ready方法

在页面中添加ready方法,用于监听微信JS-SDK的加载状态。只有当ready方法被触发后,才能正常使用微信JS-SDK。

总结

通过这次踩坑经历,笔者深刻地认识到了认真阅读官方文档的重要性。同时,也意识到了在开发过程中,需要不断地学习和探索,才能避免遇到同样的问题。希望这篇文章能给其他开发者一些参考和借鉴,避免在微信自定义分享开发中遇到同样的坑。

附录

微信官方文档链接:

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

微信JS-SDK使用说明:

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

Vue2.0项目中使用微信JS-SDK的示例代码:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  routes: [
    {
      path: '/',
      component: () => import('./views/Home.vue')
    },
    {
      path: '/about',
      component: () => import('./views/About.vue')
    }
  ]
})

// 注入配置信息
router.beforeEach((to, from, next) => {
  const { appId, timestamp, nonceStr, signature } = getJsConfig()
  Vue.prototype.$wxConfig = {
    appId,
    timestamp,
    nonceStr,
    signature
  }
  next()
})

// 监听ready方法
router.onReady(() => {
  wx.ready(() => {
    // 注册分享功能
    wx.onMenuShareTimeline({
      title: '分享标题',
      link: '分享链接',
      imgUrl: '分享图片地址'
    })

    wx.onMenuShareAppMessage({
      title: '分享标题',
      desc: '分享',
      link: '分享链接',
      imgUrl: '分享图片地址'
    })
  })
})

// 获取配置信息
function getJsConfig() {
  const url = window.location.href
  const timestamp = Date.now()
  const nonceStr = generateNonceStr()
  const signature = generateSignature(url, timestamp, nonceStr)
  return {
    appId: '你的appId',
    timestamp,
    nonceStr,
    signature
  }
}

// 生成随机字符串
function generateNonceStr() {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  let str = ''
  for (let i = 0; i < 16; i++) {
    str += chars[Math.floor(Math.random() * chars.length)]
  }
  return str
}

// 生成签名
function generateSignature(url, timestamp, nonceStr) {
  const str = `jsapi_ticket=${getJsTicket()}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`
  const sha1 = CryptoJS.SHA1(str)
  return sha1.toString(CryptoJS.enc.Hex)
}

// 获取jsapi_ticket
function getJsTicket() {
  // 通过ajax请求从服务器获取jsapi_ticket
}