接到需求 先调查
1.链接打开小程序
百度有1种方法思路是:前端写个h5页面,拿到链接里的参数 用该参数传给服务端 服务端调用微信urlscheme接口 生成打开小程序的短链接 返给前端 h5通过location.href去跳转此短链接即可
前端h5页面代码如下:
正在打开小程序...
经过上述方法测试 该方法只适用于 短信 除微信外的浏览器 如下官网介绍
而需求是:在微信聊天内打开小程序 所以需要支持微信浏览器,查资料发现上述方法自动废弃
于是又搜到方法2:使用微信外部标签wx-open-launch-weapp
标签介绍如下:
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html#21
即写个h5页面 放入此标签 通过配置此标签的属性 包括path等 点击此标签时打开小程序指定的页面
查资料得 此标签只支持打开以下两种情形的小程序:
因为我的小程序是独立申请的 没有依赖公众号,因此,只能选择方法2 将h5页面静态网站托管在小程序云托管下面
方法和h5项目源码如下:
https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/staticstorage/jump-miniprogram.html
将源码下载下来 查找需要替换的参数替换成自己小程序的参数即可
下一步就是将这个h5项目托管起来(是需要按流量收费的,一开始免费使用一个月 不怎么贵)
步骤:在微信开发者工具中点云开发--->更多--->静态网站-->上传文件夹 选择刚刚的h5项目 再在当前页面的网站配置里 填写索引文件路径h5-open-miniprogram/h5/jump-mp.html
以上完成链接分享打开小程序
具体在小程序中需要接收参数可以在h5页面标签配置的path中传递
我是在js中配好path值 通过标签属性赋值给的path
var fid = getQueryStringAll('fromType');
var transportBulkLineId = getQueryStringAll('transportBulkLineId');
var launchBtn = document.getElementById('launch-btn')
var path = '/pages/index/index.html?fromType=' + fid + '&transportBulkLineId=' + transportBulkLineId + '&isLinkUrlCome=1';
launchBtn.setAttribute('path', path)
小程序中接收参数:
if ((JSON.stringify(options) != '{}' && options.isLinkUrlCome)) {
let _param = {
transportLineId: options.transportBulkLineId || '',
fid: options.fromType || ''
}
this.setData({
param: _param
})
}
注意:以上方法只支持发布过后的小程序代码--即打开的小程序是发布版本后的小程序
补充方法 绑定公众号 链接打开小程序
其实并不一定是将小程序绑定在微信公众号下 而是已认证的服务号,服务号绑定“JS接口安全域名”下的网页可使用此标签跳转任意合法合规的小程序
也就是只要找一个认证过的公众号 在公众号的 功能设置 界面中点击“JS接口安全域名”后面对应的“设置”按钮。把h5页面的域名配置上去即可
vue写法
点击以下按钮打开 “路歌好运宝”
请在手机打开网页链接
请使用7.0.12及以上版本的微信此链接
注意:
1.需要在index.html中引用https//res.wx.qq.com/open/js/jweixin-1.6.0.js
1.6.0版本
2.写个wxjssdk的js 调用后端接口配置wx.config
/* eslint-disable */
import Vue from 'vue'
import { getWxSignature } from '@/api/commonApi'
let JssdkObj = {
is_load_wxjssdk: false,
is_share_flag: false,
is_get_loc: false,
is_hide_wxmenu: false,
wx_share_param: {
title: '', //分享自定义标题,不传就按照
stime_title: '', //分享朋友圈标识,不传就使用title
desc: '', //分享自定义内容,限制30个字
img_url: '', //分享自定义图片
timestamp: '',
nonceStr: '',
share_uid: '-1', //分享人加密用户id
state: '', //分享模块标识
app_id: '',
share_url: '',
self_params: '', //自定义参数值
successFunc() {},
cancleFunc() {},
failFunc() {},
commFunc() {}
},
wx_auth_json: null,
wx_jsapi_list: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'updateAppMessageShareData', 'updateTimelineShareData', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'getLocalImgData', 'getNetworkType', 'openLocation', 'getLocation', 'closeWindow', 'showMenuItems', 'hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem', 'scanQRCode', 'chooseWXPay', 'hideOptionMenu'],
wx_hide_menu_list: ['menuItem:share:appMessage', 'menuItem:share:timeline', 'menuItem:share:qq', 'menuItem:share:weiboApp', 'menuItem:favorite', 'menuItem:share:facebook', 'menuItem:share:QZone', 'menuItem:copyUrl', 'menuItem:openWithQQBrowser', 'menuItem:openWithSafari', 'menuItem:share:email'],
wx_show_menu_list: ['menuItem:share:appMessage', 'menuItem:share:timeline'],
wx_open_tag_list: ['wx-open-launch-weapp'],
isWeixin() {
return navigator.userAgent.toLowerCase().indexOf('micromessenger') > -1
},
isDevEnv() {
return process.env.VUE_APP_ENV === 'development'
}
}
export default {
init() {
if (JssdkObj.isWeixin()) {
if (JssdkObj.is_load_wxjssdk) {
return false
}
var myScript = document.createElement('script')
myScript.src = '//res2.wx.qq.com/open/js/jweixin-1.6.0.js'
document.body.appendChild(myScript)
Vue.nextTick(() => {
JssdkObj.is_load_wxjssdk = true
})
}
},
initHideSharePage() {
let _this = this
JssdkObj.is_hide_wxmenu = false
if (JssdkObj.isWeixin()) {
console.log('====initHideSharePage===window.WeixinJSBridge=' + typeof window.WeixinJSBridge)
if (typeof window.WeixinJSBridge !== 'undefined') {
// window.WeixinJSBridge同一页面只能调用一次,所以使用wx接口处理下
window.WeixinJSBridge.call('hideOptionMenu')
if (typeof wx !== 'undefined') {
wx.hideMenuItems({
menuList: ['menuItem:share:appMessage', 'menuItem:share:appMessage', 'menuItem:share:timeline'] // 要隐藏的菜单项,只能隐藏“传播类”和“保护类”按钮,所有menu项见附录3
})
}
JssdkObj.is_hide_wxmenu = true
return false
}
setTimeout(() => {
_this.initHideSharePage()
}, 200)
}
},
// 展示微信分享效果
initSharePage(json) {
try {
this.setShareParam(json)
this.getWxAuthIfs()
} catch (error) {
console.log('初始化分享内容失败,原因:', error)
this.initHideSharePage()
}
},
initWxJsSdk(json, isNeedWxAuth) {
/**
* json={
* is_wx_share:0/1 // 1打开,0关闭 字符串类型,不然默认为0
* is_wx_loc:0/1 // 1打开,0关闭 字符串类型,不然默认为0
* wxLocCallback(){} // 当is_wx_loc定位标识打开,微信定位成功会回调该函数
* }
*/
let _isNeedWxAuth = isNeedWxAuth || true
JssdkObj.is_share_flag = false
try {
if (json.is_wx_share === '1') {
this.setShareParam(json)
}
if (json.is_wx_loc === '1') {
JssdkObj.is_get_loc = true
JssdkObj.wxLocCallback = typeof json.wxLocCallback === 'function' ? json.wxLocCallback : () => {}
}
if (_isNeedWxAuth) {
this.getWxAuthIfs()
}
} catch (error) {
console.log('=====initSharePage', JOSN.stringify(error))
}
},
setShareParam(json) {
/**
* json={
* state,分享模块标识
* share_uid,分享卡加用户ID
* title,分享标题,不传则以服务器配置
* stime_title,朋友圈分享标题内容,为空则直接使用title
* desc,分享内容,不传则以服务器配置
* img_url,分享图片,不传则以服务器配置
* self_params, 自定义参数值(不能带参数名称)
* success_func({share_type:'friend/time_line'}){},分享成功回调函数,friend-好友分享标识,time_line-朋友圈分享标识
* cancle_func({share_type:'friend/time_line'}){},取消分享动作回调函数,friend-好友分享标识,time_line-朋友圈分享标识
* fail_func({share_type:'friend/time_line'}){},分享失败回调函数,friend-好友分享标识,time_line-朋友圈分享标识
* comm_func({share_type:'friend/time_line'}){}分享公共(成功/失败都会调用)回调函数,friend-好友分享标识,time_line-朋友圈分享标识
* }
*/
JssdkObj.is_share_flag = true
JssdkObj.wx_share_param.state = json.state || ''
JssdkObj.wx_share_param.title = json.title || '缺少分享内容'
JssdkObj.wx_share_param.stime_title = json.stime_title || JssdkObj.wx_share_param.title
JssdkObj.wx_share_param.desc = json.desc || '缺少分享内容'
JssdkObj.wx_share_param.img_url = json.img_url || ''
JssdkObj.wx_share_param.self_params = json.self_params || ''
JssdkObj.wx_share_param.share_uid = json.share_uid || '-1'
JssdkObj.wx_share_param.successFunc = typeof json.success_func === 'function' ? json.success_func : () => {}
JssdkObj.wx_share_param.cancleFunc = typeof json.cancle_func === 'function' ? json.cancle_func : () => {}
JssdkObj.wx_share_param.failfunc = typeof json.fail_func === 'function' ? json.fail_func : () => {}
JssdkObj.wx_share_param.commFunc = typeof json.comm_func === 'function' ? json.comm_func : () => {}
},
getWxAuthIfs() {
let _this = this
let link = window.location.href
link = window.location.href.split('#')[0]
Vue.prototype.$toast.loading({
message: '加载中'
})
getWxSignature({
url: encodeURIComponent(link)
}).then(response => {
console.log('微信签名getWxSignature', response)
if (response.data.reCode === '0') {
let resJson = response.data.result
setTimeout(function() {
_this.regWxConfigIfs(resJson)
}, 200)
} else if (JssdkObj.wx_auth_json !== null) {
_this.regWxConfigIfs(JssdkObj.wx_auth_json)
}
}).catch(function(error) {
console.log('=getWxAuthIfs=catch===调用失败,' + JSON.stringify(error))
if (JssdkObj.wx_auth_json !== null) {
_this.regWxConfigIfs(JssdkObj.wx_auth_json)
}
})
},
regWxConfigIfs(json) {
var _this = this
JssdkObj.wx_auth_json = json
if (typeof window.WeixinJSBridge === 'undefined' || typeof wx === 'undefined') {
setTimeout(function() {
_this.regWxConfigIfs(json)
}, 200)
return false
}
wx.config({
debug: JssdkObj.isDevEnv(), // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: json.appId, // 必填,公众号的唯一标识
timestamp: Number(json.timeStamp), // 必填,生成签名的时间戳
nonceStr: json.nonceStr, // 必填,生成签名的随机串
signature: json.signature, // 必填,签名
jsApiList: JssdkObj.wx_jsapi_list, // 必填,需要使用的JS接口列表
openTagList: JssdkObj.wx_open_tag_list
})
this.onWxReady()
},
onWxReady() {
var _this = this
try {
wx.ready(function(res) {
// config信息验证后会执行ready方法,
// 所有接口调用都必须在config接口获得结果之后,
// config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,
// 则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,
// 则可以直接调用,不需要放在ready函数中。
console.log('wx.ready', res)
_this.checkAllJsApi()
_this.openShareConfig()
if (JssdkObj.is_get_loc) {
_this.getWxLocation()
}
})
// 验证失败
wx.error(function(res) { // 如果失败,就隐藏右上角的所有菜单
console.log('wx.error=', res)
_this.initHideSharePage()
})
} catch (err) {
_this.initHideSharePage()
}
},
onShowMenuItems() {
var _this = this
console.log('执行了onShowMenuItems')
if (typeof window.WeixinJSBridge === 'undefined' || JssdkObj.wx_share_param.app_id.length === 0) {
setTimeout(function() {
_this.onShowMenuItems()
}, 200)
} else {
console.log(
'====onShowMenuItems:' + JSON.stringify(JssdkObj.wx_show_menu_list)
)
wx.showMenuItems({
menuList: JssdkObj.wx_show_menu_list // 要显示的菜单项,所有menu项见附录3
})
}
},
checkAllJsApi() {
try {
wx.checkJsApi({
jsApiList: JssdkObj.wx_jsapi_list, // 需要检测的JS接口列表,所有JS接口列表见附录2,
success: function(res) {
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{'checkResult':{'chooseImage':true},'errMsg':'checkJsApi:ok'}
let resStr = JSON.stringify(res)
if (resStr.indexOf(':false') > -1) {
console.log('checkJsApi:' + resStr)
}
}
})
} catch (err) {
console.log('checkJsApi调用失败,原因:' + JSON.stringify(err))
}
},
updateAppMessageShareData() {
try {
//自定义“分享给朋友”的分享内容,需在用户可能点击分享按钮前就先调用
wx.updateAppMessageShareData({
title: JssdkObj.wx_share_param.title, // 分享标题
desc: JssdkObj.wx_share_param.desc, // 分享描述
link: JssdkObj.wx_share_param.share_url.replace('{WX_SHARE_TYPE}', '1'), // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: JssdkObj.wx_share_param.img_url, // 分享图标
success: function(res) {
console.log('分享到好友成功:' + JSON.stringify(res))
JssdkObj.wx_share_param.successFunc({ share_type: 'friend' })
JssdkObj.wx_share_param.commFunc({ share_type: 'friend' })
},
trigger: function() {
console.log('用户点击分享到好友')
},
fail: function(res) {
console.log('分享到好友失败' + JSON.stringify(res))
}
})
} catch (err) {
console.log(
'updateAppMessageShareData调用失败,原因:' + JSON.stringify(err)
)
}
},
updateTimelineShareData() {
try {
//自定义“分享到朋友圈”按钮的分享内容,需在用户可能点击分享按钮前就先调用
wx.updateTimelineShareData({
title: JssdkObj.wx_share_param.stime_title, // 分享标题
link: JssdkObj.wx_share_param.share_url.replace('{WX_SHARE_TYPE}', '0'), // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: JssdkObj.wx_share_param.img_url, // 分享图标
success: function(res) {
console.log('分享到朋友圈成功:' + JSON.stringify(res))
JssdkObj.wx_share_param.successFunc({ share_type: 'time_line' })
JssdkObj.wx_share_param.commFunc({ share_type: 'time_line' })
},
trigger: function() {
console.log('用户点击分享到朋友圈')
},
fail: function(res) {
console.log('分享到朋友圈失败' + JSON.stringify(res))
}
})
} catch (err) {
console.log(
'updateTimelineShareData调用失败,原因:' + JSON.stringify(err)
)
}
},
onMenuShareAppMessage() {
wx.onMenuShareAppMessage({
title: JssdkObj.wx_share_param.title,
desc: JssdkObj.wx_share_param.desc,
link: JssdkObj.wx_share_param.share_url.replace('{WX_SHARE_TYPE}', '1'),
imgUrl: JssdkObj.wx_share_param.img_url,
trigger: function(res) {
// console.log('用户点击分享到好友')
},
success: function(res) {
console.log('old分享好友成功:' + JSON.stringify(res))
JssdkObj.wx_share_param.successFunc({ share_type: 'friend' })
JssdkObj.wx_share_param.commFunc({ share_type: 'friend' })
},
cancel: function(res) {
// console.log('分享到好友操作已被取消')
JssdkObj.wx_share_param.cancelFunc({ share_type: 'friend' })
},
fail: function(res) {
// console.log('分享到好友失败')
// console.log(JSON.stringify(res))
JssdkObj.wx_share_param.failFunc({ share_type: 'friend' })
JssdkObj.wx_share_param.commFunc({ share_type: 'friend' })
}
})
},
onMenuShareTimeline() {
wx.onMenuShareTimeline({
title: JssdkObj.wx_share_param.stime_title,
link: JssdkObj.wx_share_param.share_url.replace('{WX_SHARE_TYPE}', '0'),
imgUrl: JssdkObj.wx_share_param.img_url,
trigger: function(res) {
console.log('用户点击分享到朋友圈', res)
},
success: function(res) {
console.log('old分享到朋友圈成功:' + JSON.stringify(res))
JssdkObj.wx_share_param.successFunc({ share_type: 'time_line' })
JssdkObj.wx_share_param.commFunc({ share_type: 'time_line' })
},
cancel: function(res) {
console.log('分享到朋友圈操作已被取消', res)
JssdkObj.wx_share_param.cancelFunc({ share_type: 'time_line' })
},
fail: function(res) {
console.log('分享到朋友圈失败', res)
JssdkObj.wx_share_param.failFunc({ share_type: 'time_line' })
JssdkObj.wx_share_param.commFunc({ share_type: 'time_line' })
}
})
},
getWxLocation() {
try {
wx.getLocation({
type: 'gcj02',
success: function(res) {
var latitude = res.latitude
var longitude = res.longitude
if (typeof JssdkObj.wxLocCallback === 'function') {
JssdkObj.wxLocCallback({
result: { reCode: '200', reInfo: '微信定位成功' },
latitude,
longitude
})
}
JssdkObj.wxLocCallback = null
},
fail: function(res) {
console.log('获取经纬度失败,原因:' + JSON.stringify(res))
if (typeof JssdkObj.wxLocCallback === 'function') {
JssdkObj.wxLocCallback({
result: { reCode: '1', reInfo: '获取经纬度失败' }
})
}
JssdkObj.wxLocCallback = null
}
})
} catch (err) {
console.log('getWxLocation调用失败,原因:' + JSON.stringify(err))
}
},
closeShareConfig() {
// 隐藏菜单
if (typeof wx !== 'undefined') {
wx.hideAllNonBaseMenuItem()
}
},
openShareConfig(json) {
if (!JssdkObj.is_share_flag) {
console.log('//分享开关未打开')
return false
}
if (!JssdkObj.is_hide_wxmenu) {
let _this = this
setTimeout(() => {
_this.openShareConfig(json)
}, 200)
return false
}
if (typeof json === 'object') {
this.setShareParam(json)
}
// 防止菜单没有隐藏
if (typeof wx !== 'undefined') {
wx.hideAllNonBaseMenuItem()
}
this.onShowMenuItems()
this.onMenuShareAppMessage()
this.onMenuShareTimeline()
},
openWxLocation(lat, lng, address) {
wx.openLocation({
latitude: parseFloat(lat), // 纬度,浮点数,范围为90 ~ -90
longitude: parseFloat(lng), // 经度,浮点数,范围为180 ~ -180。
name: '[商家位置]', // 位置名
address: address, // 地址详情说明
scale: 15 // 地图缩放级别,整形值,范围从1~28。默认为最大
// infoUrl: '' // 在查看位置界面底部显示的超链接,可点击跳转
})
},
showImg(imgUrl, currUrl) {
wx.previewImage({
current: currUrl, // 当前显示图片的http链接
urls: imgUrl // 需要预览的图片http链接列表
})
},
chooseImage() {
this.getWxAuthIfs()
var _this = this
wx.chooseImage({
count: 6, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function(res) {
var localIds = res.localIds // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
console.log('微信图片返回', localIds)
_this.uploadImage(localIds[0])
},
fail: function(err) {
console.log(JSON.stringify(err))
}
})
},
uploadImage(id) {
wx.uploadImage({
localId: id, // 需要上传的图片的本地ID,由chooseImage接口获得
isShowProgressTips: 1, // 默认为1,显示进度提示
success: function(res) {
const serverId = res.serverId // 返回图片的服务器端ID
console.log('serverId', serverId)
}
})
},
showShareWxGuide(shareMsg) {
const _shareMsg = shareMsg || '点击右上角可转发分享哦~'
Vue.$toast({ message: _shareMsg, position: 'middle', duration: 3000 })
}
}
以上是微信sdk常用功能包括上传图片 获取地址 分享等一系列的配置都写上了
在main.js中 引用上述js 并调用
import ShareMethods from './assets/js/wxJssdk'
Vue.config.ignoredElements = ['wx-open-launch-weapp']
Vue.use(ShareMethods)
Vue.prototype.$shareJs = ShareMethods
ShareMethods.init() // 微信分享初始化
2.扫一扫打开小程序
小程序开发管理中提供了扫一扫打开小程序的开关 这里先去开启 并配置规则
方法如下:
小程序开放平台 开发管理--开发设置--- 扫普通链接二维码打开小程序
配个h5页面(中转页)路径 通过这个路径的码可以打开小程序(其实这个h5没什么功能作用 只是在小程序平台配置个与小程序页面的一个映射)
配置完成后即可打开小程序
在小程序中取二维码中路径的参数
onLoad(options) {
if (options && options.q) {
// 扫码进来的
let url= decodeURIComponent(options.q);
this.setData({
localUrl: url
})
this.isScanComeFun();
}
isScanComeFun() {
// start扫二维码进来的
try {
let url = this.data.localUrl;
console.log('当前页url', url);
var _obj = {
transportLineId: util.getQueryVariable('transportBulkLineId',url) || '',
fid: util.getQueryVariable('fromType',url) || ''
}
console.log('参数', _obj);
} catch (error) {
}
}
注意:配置体验版的小程序 扫一扫最多只支持配置5个url即参数不可变 变了就算一个url
线上直接配h5域名即可 参数可以变