1、背景:使用vue框架的公众号网页
3、要求:所有页面隐藏除微信浏览器的其他浏览器打开功能,设置好友分享和朋友圈分享
4、处理过程:
(1)在index.html中载入jssdk:http://res.wx.qq.com/open/js/jweixin-1.4.0.js
(2)通过调用后台接口,获取微信配置所需的配置信息
注意:所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,所以对于单页面,仅需调用一次。目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
(3)微信jssdk中的error接口处理失败验证
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
(4)微信jssdk中的ready接口处理成功验证
注意:微信jssdk中的接口一定要在wx.ready接口中写
wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
5.例子:
(1)share.js:
// 获取微信配置信息
let getShareConfig = (_this) => {
let data = {
url: window.location.href.split('#')[0]
}
_this.axios({
method: 'post',
url: `api/video/shareconfig`,
data: data
})
.then((res) => {
console.log(res)
if (res.status === 200 && !res.data.status_code) {
config(_this,res.data)
} else {
_this.showToast('网络错误,请重试~')
}
})
.catch((error) => {
console.log(error)
_this.showToast('网络错误,请重试~')
})
}
// 注入配置信息
let config = (_this,shareConfig) => {
wx.config(shareConfig)
wx.error(function(res){
console.log(res)
_this.showToast('网络错误,请重试~')
});
}
// 获取分享者信息
let getSu = (_this, title, desc, imgUrl, path, pid, cid) => {
_this.axios.get('/api/video/encryptsu')
.then((res) => {
if (res.status === 200 && !res.data.status_code) {
share(_this, res.data.su, title, desc, imgUrl, path, pid, cid)
} else {
_this.showToast('网络错误,请重试~')
}
})
.catch((error) => {
console.log(error)
_this.showToast('网络错误,请重试~')
})
}
// 页面分享
let share = (_this, su, title, desc, imgUrl, path, pid, cid) => {
// 分享给朋友
let host = window.location.href.indexOf('su') > -1 ? window.location.href.split('?')[0] : window.location.href.split('#')[0]
let linkUrl = cid ? (host + '?su=' + su + '#' + path + pid + '/' + cid) : (host + '?su=' + su + '#' + path + pid);
console.log(host)
console.log(linkUrl)
wx.ready(() => {
console.log('wx.ready输出非jssdk内容')
wx.onMenuShareAppMessage({
title: title, // 分享标题
desc: desc, // 分享描述
link: linkUrl,
imgUrl: imgUrl, // 分享图标
success: function () {
_this.showToast('分享成功~')
}
})
//分享到朋友圈
wx.onMenuShareTimeline({
title: title, // 分享标题
link: linkUrl,
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户点击了分享后执行的回调函数
console.log()
_this.showToast('分享成功~')
}
})
//隐藏右上角某些功能
wx.hideMenuItems({
menuList: [
'menuItem:share:qq',
'menuItem:share:weiboApp',
'menuItem:share:facebook',
'menuItem:share:QZone',
'menuItem:copyUrl',
'menuItem:openWithQQBrowser',
'menuItem:openWithSafari',
'menuItem:originPage'
] // 要隐藏的菜单项,只能隐藏“传播类”和“保护类”按钮,所有menu项见附录3
});
})
}
export {getShareConfig, getSu}
(2)在App.vue中引入并执行getShareConfig:
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
import { getShareConfig } from './commonFunc/shareConfig'
import Toast from './components/Toast'
export default {
name: 'App',
components: {
Toast
},
created() {
getShareConfig(this)
}
}
</script>
(3)因为所有页面都需要设置分享和隐藏一些权限,
所以在入口文件main.js中将getSu设置为全局方法
注意:必须在创建vue对象前设置
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import Axios from 'axios'
import 'babel-polyfill'
import {getSu} from './commonFunc/shareConfig'
// axios使用application/x-www-form-urlencoded
import qs from 'qs'
Vue.prototype.axios = Axios
Vue.prototype.axios.defaults.timeout = 6000
Vue.prototype.axios.defaults.baseURL = (location.href.search('192.168') >= 0 || location.href.search('web.zhbx') >= 0) ? 'http://web.zhbx' : location.href.match(/^(https|http):\/\/(\w(-\w){0,1}\.){1,2}\w+\.com/)[0]
console.log(Vue.prototype.axios.defaults.baseURL)
Vue.prototype.axios.defaults.headers = {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
}
Vue.prototype.axios.interceptors.request.use((config) => {
if (config.method === 'post' || config.method === 'get') {
config.data = qs.stringify(config.data)
}
return config
}, (error) => {
return Promise.reject(error)
})
// 显示隐藏提示框
Vue.prototype.showToast = function (toastText) {
let _this = this
_this.toast = true
_this.toastText = toastText
setTimeout(() => {
_this.toast = false
}, 3000)
}
// 页面获取分享者信息
Vue.prototype.getSu = getSu
Vue.config.productionTip = false
/* eslint-disable no-new */
const vm = new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
(4)各页面中使用getSu:
created () {
this.getSu(this, '真话保险视频课程-全部课程', '真话保险视频课程', imgUrl, '/all/course')
}