微信开放标签-H5跳转小程序
原生H5跳转小程序
一、准备工作
1.配置JS接口安全域名
登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
2.引入JS-SDK文件
在需要调用JS接口的页面引入如下JS文件:
http://res.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)
如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:
http://res2.wx.qq.com/open/js/jweixin-1.6.0.js
3. 通过config接口注入权限验证配置并申请所需开放标签
与使用JS-SDK配置方式相同,所有需要使用开放标签的页面必须先注入配置信息,并通过openTagList字段申请所需要的开放标签,否则将无法使用(同一个url仅需调用一次)。开放标签的申请和JS接口的申请相互独立,因此是可以同时申请的。
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [], // 必填,需要使用的JS接口列表
openTagList: ['wx-open-launch-weapp']
});
以上内容摘抄自微信开放标签说明文档:传送门
4.必要的参数
公众号:AppId、Secret
小程序:原始ID(微信公众号平台登录小程序-设置-基本设置-账号信息)
小程序页面地址如:pages/index/index
二、功能实现
1.<wx-open-launch-weapp>标签
<wx-open-launch-weapp id="launch-btn" username="name" path="page/index/index">
<template>
<button style="xxx">打开小程序</button>
</template>
</wx-open-launch-weapp>
// username: 小程序原始ID
// path: 需要跳转到的小程序路径
所有开放标签都能像普通的HTML标签一样在页面中直接使用,不需要再进行额外的处理。
由于插槽中模版的样式是和页面隔离的,因此需要注意在插槽中定义模版的样式。插槽模版及样式均需要通过<template></template>或<script type=“text/wxtag-template”></script>进行包裹。
2.获取签名
// 注:签名接口又后端童学书写,参数名略有差异
axios.get(BASE_URL + '/.../getSignature', {
params: {
url: window.location.href.split('#')[0],
secret: item.appSecret,
appId: item.appId
}
}).then(res => {...})
签名所需参数:
公众号AppId
公众号Sceret
当前页面URL(可通过window.location.href.split('#')[0]获取)
JS接口签名校验工具-传送门
3.wx.config 生成注入权限申请所需开放标签
axios.get(BASE_URL + '/xxx/getSignature', {
params: {
url: window.location.href.split('#')[0],
secret: item.appSecret,
appId: item.appId
}
}).then(res => {
const signData = res.data
const launchBtn = document.getElementById(`launch-btn-${ index }`)
launchBtn.addEventListener('ready', (e) => {
console.log('开放标签 ready')
})
launchBtn.addEventListener('launch', (e) => {
console.log('开放标签 success')
})
launchBtn.addEventListener('error', (e) => {
console.log('开放标签 fail', e)
})
wx.config({
debug: false,
appId: item.appId,
timestamp: signData.timestamp,
nonceStr: signData.noncestr,
signature: signData.signature,
jsApiList: ['checkJsApi'],
openTagList: ['wx-open-launch-weapp']
})
})
}
Vue项目H5跳转小程序
一、准备工作
1.配置JS接口安全域名
登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
2.引入JS-SDK文件
安装 weixin-js-sdk npm包
npm install weixin-js-sdk -s
在 Vue 的 main.js 文件中引入
import wx from 'weixin-js-sdk'
Vue.prototype.$wx = wx
Vue.config.ignoredElements = ['wx-open-launch-weapp']
Vue.config.ignoredElements的作用,忽略 wx-open-launch-weapp 元素。否则Vue会假设你忘记注册全局组件或者拼错了组件名称,从而抛出一个关于 Unknown custom element 的警告
3. 通过config接口注入权限验证配置并申请所需开放标签
与使用JS-SDK配置方式相同,所有需要使用开放标签的页面必须先注入配置信息,并通过openTagList字段申请所需要的开放标签,否则将无法使用(同一个url仅需调用一次)。开放标签的申请和JS接口的申请相互独立,因此是可以同时申请的。
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [], // 必填,需要使用的JS接口列表
openTagList: ['wx-open-launch-weapp']
});
以上内容摘抄自微信开放标签说明文档:传送门
4.必要的参数
公众号:AppId、Secret
小程序:原始ID(微信公众号平台登录小程序-设置-基本设置-账号信息)
小程序页面地址如:pages/index/index
二.需求分析
这里以近期接到的一个H5跳转小程序需求为例
场景:“支付完成”的页面存在一个广告轮播功能,原有功能-链接其他页面,广告链接、图片在运营端后台配置,“支付完成”接口查询广告数据,动态生成轮播
需求:保证现有功能情况下,增加点击轮播跳转相应小程序的功能
需求分析,假设现有三张图片image1、image2、image3分别对应功能
image1 --> http://www.baidu.com
image2 --> 小程序a
image3 --> 小程序b
轮播实现-基于element-ui
<el-carousel v-if="bannerList.length > 0" arrow="never" :interval="2000" :loop="true" height="150px">
<el-carousel-item v-for="(item,index) in bannerList" :key="index">
<template v-if="item.channel === 1">
<generate-open-label :app-id="item.appId" :app-secret="item.appSecret" :path="item.path" :original-id="item.originalId">
<div v-html="getOpenLabelContent(item)"></div>
<div slot="loading" style="width: 100%;padding: 50px 8px;color: #666;"><span class="el-icon-loading"></span>加载中...</div>
</generate-open-label>
</template>
<template v-else>
<img class="carouselimg" :src="item.image" width="100%" @click="goAdvertLink(item)" />
</template>
</el-carousel-item>
</el-carousel>
getOpenLabelContent函数
1、不能使用<template>标签
2、需要注意<script type=“text/wxtag-template”>标签的使用方式
getOpenLabelContent (item) {
const scriptEl = document.createElement('script')
scriptEl.type = 'text/wxtag-template'
scriptEl.innerHTML = `<img class="carouselimg" src="${ item.image }" width="100%"/>`
return scriptEl.outerHTML
}
判断“channel”渠道为1时创建开发标签,否则生成链接图片
generate-open-label 组件
1、考虑到组件的可复用性,使用slot插槽来插入开放标签内部内容
2、因为开放标签未注册成功时,显示为空白,所以加入具名插槽slot='loading’占位
<div style="position: relative">
<div :style="{opacity: openLabelLoading ? 0 : 1}">
<wx-open-launch-weapp ref="launch-btn" class="launch-btn" :username="originalId" :path="path">
<slot></slot>
</wx-open-launch-weapp>
</div>
<div v-show="openLabelLoading" style="text-align: center">
<slot name="loading">
<div class="init-loading"><span class="el-icon-loading"></span>加载中...</div>
</slot>
</div>
</div>
generate-open-label 组件完整使用
html部分
<generate-open-label :app-id="item.appId" :app-secret="item.appSecret" :path="item.path" :original-id="item.originalId">
<div v-html="getOpenLabelContent(item)"></div>
<div slot="loading" style="width: 100%;padding: 50px 8px;color: #666;"><span class="el-icon-loading"></span>加载中...</div>
</generate-open-label>
script部分
getOpenLabelContent (item) {
const scriptEl = document.createElement('script')
scriptEl.type = 'text/wxtag-template'
scriptEl.innerHTML = `<img class="carouselimg" src="${ item.image }" width="100%"/>`
return scriptEl.outerHTML
}
generate-open-label完整代码
<template>
<div style="position: relative">
<div :style="{opacity: openLabelLoading ? 0 : 1}">
<wx-open-launch-weapp ref="launch-btn" class="launch-btn" :username="originalId" :path="path">
<slot></slot>
</wx-open-launch-weapp>
</div>
<div v-show="openLabelLoading" style="text-align: center">
<slot name="loading">
<div class="init-loading"><span class="el-icon-loading"></span>加载中...</div>
</slot>
</div>
</div>
</template>
<script>
import { getSignature } from '@/api/scanpayment/scanpayment'
export default {
name: 'GenerateOpenLabel',
props: {
appId: {
type: String,
default: ''
},
appSecret: {
type: String,
default: ''
},
originalId: {
type: String,
default: ''
},
path: {
type: String,
default: ''
},
debugger: {
type: Boolean,
default: false
}
},
data () {
return {
openLabelLoading: true
}
},
mounted () {
this.getSignature()
},
methods: {
getSignature () {
const params = {
url: window.location.href.split('#')[0],
secert: this.appSecret,
appId: this.appId
}
getSignature(params).then(res => {
if (res.retCode === 0) {
this.generateOpenLabel(res)
} else {
console.error('生成签名失败' + res.msg || res.message)
}
})
},
validWxConfig (signData) {
setTimeout(() => {
this.$wx.config({
debug: process.env.ENV === 'production' ? false : this.debugger,
appId: this.appId,
timestamp: signData.timestamp,
nonceStr: signData.noncestr,
signature: signData.signature,
jsApiList: ['checkJsApi'],
openTagList: ['wx-open-launch-weapp']
})
}, 500)
},
generateOpenLabel (res) {
const signData = res.data
const launchBtn = this.$refs['launch-btn']
launchBtn.addEventListener('ready', () => {
this.openLabelLoading = false
console.log('开放标签 ready')
})
launchBtn.addEventListener('launch', () => {
console.log('开放标签 success')
})
launchBtn.addEventListener('error', (e) => {
console.log('开放标签 fail', e.detail)
})
this.validWxConfig(signData)
}
}
}
</script>
<style scoped lang="scss">
.init-loading {
width: 100%;
padding: 4px 8px;
color: #666;
}
</style>
总结
现有实现方式只能通过外部getOpenLabelContent函数插入html的方式生成开放标签内容,考虑是否能够直接写内容,generate-open-label 组件内部自动添加<script type=“text/wxtag-template”>包裹slot插槽传入内容,由于现在没有不方便测试,有实现的大佬可以回来给个方案