header-bg.jpg
Vue 单页应用中中引入微信 JS-SDK,实现微信分享
发表于 2019-06-07 05:19
|
分类于 JavaScript
|
评论次数 0
|
阅读次数 1258

引入微信 JS-SDK

微信 JS-SDK 官方文档

使用 npm 安装

npm install weixin-js-sdk

使用方法

main.js

import wx from 'weixin-js-sdk'
Vue.prototype.$share = (title = '', imgUrl = 'https://img.vhiphop.top/web/logo-icon.jpg') => {
  title = `${title ? title + '-' : ''}Vhiphop 唯舞`;
  document.title = title;
  const link = window.location.href;
  api.post('sign/wx', {link}).then(e => {
    wx.config({
      debug: false, // 关闭调试模式
      appId: e.appId, // 必填,公众号的唯一标识
      timestamp: e.timestamp, // 必填,生成签名的时间戳
      nonceStr: e.nonceStr, // 必填,生成签名的随机串
      signature: e.signature,// 必填,签名
      jsApiList: [
        'updateAppMessageShareData',
        'updateTimelineShareData',
      ] // 必填,需要使用的JS接口列表
    });
    wx.ready(function () {   //需在用户可能点击分享按钮前就先调用
      wx.updateAppMessageShareData({
        title, // 分享标题
        desc: '更多精彩,尽在 Vhiphop 唯舞。', // 分享描述
        link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
        imgUrl, // 分享图标
        success: function () {
          // 设置成功
        }
      });
      wx.updateTimelineShareData({
        title, // 分享标题
        link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
        imgUrl, // 分享图标
        success: function () {
          // 设置成功
        }
      });
    });
  }, e => console.log(e));
};

如上,在 Vue 原型上声明 $share 方法,该方法接受 2 个参数:

每次调用 $share 方法都会重新设置页面的 title,并且请求服务端接口,获取微信分享需要的配置参数。

服务端生成配置参数

服务端需要返回的配置参数包含以下 4 个参数:

PHP 示例:

// get请求
protected static function get($url)
{
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 设置是否将响应结果存入变量  1 : 存入 0 : 直接echo
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 设置禁止证书校验 否则https地址无法访问
    curl_setopt($ch, CURLOPT_TIMEOUT, 20);// 设置最大响应时间
    $res = curl_exec($ch);// 存入变量
    curl_close($ch);
    return $res;
}

// 生成微信配置参数
public function wxSign(Request $r)
{
    $url = $r->get('link');
    !$url && self::error('分享URL不能为空');

    $appId = 'wx25********';// 你的appId
    if (!$ticket = Rds::get('web:ticket')) {// 直接从redis中读取
        $appSecret = 'b5a7************';// 你的appSecret

        $res = self::get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}");
        $res = json_decode($res, true);

        !isset($res['access_token']) && self::error('access_token获取失败, 请重新尝试');
        $access_token = $res['access_token'];

        $res = self::get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$access_token}&type=jsapi");
        $res = json_decode($res, true);
        !isset($res['errcode']) && self::error('ticket请求失败');
        $res['errcode'] !== 0 && self::error("ticket获取失败, 请重新尝试, 错误码: {$res['errcode']}");
        $ticket = $res['ticket'];
        Rds::setex('web:ticket', 7000, $ticket);// ticket过期时间为7200秒, 设置redis过期时间7000秒即可
    }

    $nonceStr = substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz'), mt_rand(0, 46), 16);
    $time = time();

    self::go([
        'appId' => $appId,
        'timestamp' => $time,
        'nonceStr' => $nonceStr,
        'signature' => sha1("jsapi_ticket={$ticket}&noncestr={$nonceStr}&timestamp={$time}&url={$url}")
    ]);
}

如上,在 wxSign 方法中返回了 4 个需要的参数,前端请求该接口获取参数即可。

在组件中调用

原则:URL 每次发生变化,就需要重新调用一次 $share 方法,刷新微信分享的 URL,避免路由发生改变后分享出去的依然是第一次进入的 URL。

示例:

beforeRouteUpdate(to, from, next) {// 如果使用了该钩子, 则在 next() 后调用 $share
    const {sort} = to.query;

    this.api.get('video', {sort: +sort || 0}).then(e => this.videos = e, this.err);
    next();
    this.$share('视频');// 标题, 封面都可以自定义
},
async beforeMount() {// 初次进入组件, 正常请求完毕后再调用 $share
    const {api, sort} = this;

    await Promise.all([
        api.get('home/sort').then(e => this.sorts = e),
        api.get('video', {sort}).then(e => this.videos = e),
    ]).catch(this.err);

    this.isLoading = false;
    this.$share('视频');// 标题, 封面都可以自定义
},

如上,第一次进入路由,在 beforeMount 中正常请求业务数据完毕后,再调用 $share 方法。

如果路由发生改变,并且复用该组件,则在 beforeRouteUpdate 钩子中正常请求业务数据后,重新调用 $share 方法。

完成后的效果:

share.png

发布评论
还没有评论,快来抢沙发吧!