如何在vue项目中跳转微信小程序

857 阅读5分钟

前言

最近开发停车场相关业务,需要在手机h5中,调起微信支付分停车服务,这里就从配置环境到开发调试整个流程和踩的坑分享记录一下。

1、前提

微信版本要求为:7.0.12及以上。 系统版本要求为:iOS 10.3及以上、Android 5.0及以上。

2、绑定域名

如果是公众号身份的网页,需要绑定安全域名(这里因为在已有的基础上开发,已经配置好了,没有配置的可以在微信后台->公众号设置->功能设置)

3、引入weixin-js-sdk插件

首先我们在项目依赖中引入 weixin-js-sdk,建议使用 1.6.0版本

(微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包),通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验

npm install weixin-js-sdk

4、引入

import weixin from 'weixin-js-sdk'
const wx = window.wx || weixin

5、通过config接口注入权限验证配置

这里我们封了个全局方法,方便界面任何地方需要用微信相关功能,直接调用方法注入权限验证

import weixin from 'weixin-js-sdk'
const wx = window.wx || weixin
// 这里我是调一个后端接口 获取微信扫描优惠券时前端调用微信原生js时的签名
export async function weChatSign() {
	const {
		data
	} = await api.getJsSign()
	await weChatSignInner(data)
}
function weChatSignInner(data) {
	return new Promise((resolve, reject) => {
		wx.config({
			debug: true,```// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。```
			appId: data.appId,```// 必填,公众号的唯一标识```
			timestamp: data.timestamp,```// 必填,生成签名的时间戳```
			nonceStr: data.nonceStr,```// 必填,生成签名的随机串```
			signature: data.signature,```// 必填,签名```
			jsApiList: [ ```// 必填,需要使用的JS接口列表```
				'updateAppMessageShareData',
				'updateTimelineShareData',
				// 即将废弃
				'onMenuShareTimeline',
				// 即将废弃
				'onMenuShareAppMessage',
				// 即将废弃
				'onMenuShareQQ',
				'onMenuShareWeibo',
				'onMenuShareQZone',
				'startRecord',
				'stopRecord',
				'onVoiceRecordEnd',
				'playVoice',
				'pauseVoice',
				'stopVoice',
				'onVoicePlayEnd',
				'uploadVoice',
				'downloadVoice',
				'chooseImage',
				'previewImage',
				'uploadImage',
				'downloadImage',
				'translateVoice',
				'getNetworkType',
				'openLocation',
				'getLocation',
				'hideOptionMenu',
				'showOptionMenu',
				'hideMenuItems',
				'showMenuItems',
				'hideAllNonBaseMenuItem',
				'showAllNonBaseMenuItem',
				'closeWindow',
				'scanQRCode',
				'chooseWXPay',
				'openProductSpecificView',
				'addCard',
				'chooseCard',
				'openCard',
				'openEnterpriseRedPacket',
				'startSearchBeacons',
				'stopSearchBeacons',
				'onSearchBeacons',
				'consumeAndShareCard',
				'openAddress'
			],
			openTagList: ['wx-open-launch-weapp']```// 可选,需要使用的开放标签列表```
		})
		wx.ready(() => {  ```//通过ready接口处理成功验证```
			resolve(data)
		})
		wx.error((res) => { ```//通过error接口处理失败验证```
			reject(res)
		})
	})
}

这里我们需要跳转微信小程序,所以需要配开发标签## 开放标签wx-open-launch-weapp

  • 开放标签列表
<wx-open-launch-weapp> // 跳转小程序
<wx-open-launch-app>  // 跳转APP
<wx-open-subscribe> // 服务号订阅通知按钮
<wx-open-audio> // 音频播放

6、使用标签

首先我们在created周期中注入权限验证配置


created () {
   weChatSign()
},

按照官网,我们引入标签 wx-open-launch-weapp

<template>
   <div>
        <wx-open-launch-weapp
            id="launch-btn"
            username="小程序原始id"
            path="/pages/index/index.html"
            @launch="launchHandle"
            @error="errorHandle"
        >
            <script type="text/wxtag-template">
                <style>.btn { padding: 12px; border: 1px solid red; }</style>
                <button class="btn">打开小程序</button>
            </script>
        </wx-open-launch-weapp>
    </div>
</template>

发现vue会有一个警告,并且标签也出不来

image.png

我们需要在main.js中配置一下,须使 Vue 忽略在 Vue 之外的自定义元素

import Vue from 'vue'
Vue.config.ignoredElements = ['wx-open-launch-weapp']

这里我们需要调起微信支付分停车服务开通页API

**微信支付分停车服务小程序appid为:** wxbcad394b3d99dac9
**微信支付分停车服务小程序路径为:** /pages/auth-creditpay/auth-creditpay
**微信支付分停车服务小程序username为:** gh_518c42c65952

image.png

eg:

<div style="text-align: center;" v-if="isWeChat">
        <wx-open-launch-weapp
            id="launch-btn"
            username="gh_518c42c65952"
            path="/pages/auth-creditpay/auth-creditpay.html?mchid=1230000100&sub_mchid=1900000109&openid=wxbcad394b3d99dac9&plate_number=粤B888888&plate_color=BLUE&trade_scene=PARKING"
            @launch="launchHandle"
            @error="errorHandle"
        >
            <script type="text/wxtag-template">
                <style>.btn { margin-top: 12px;margin-bottom: 18px;color: #36f; }</style>
                <button class="btn">打开小程序</button>
            </script>
        </wx-open-launch-weapp>
    </div>

具体需要调什么应用,对应参数和路径可参考官网

这里标签使用不当,就会是标签出不来,这里根据不同场景整理了几种写法

  • 1、使用的前端框架和template标签不冲突的
<wx-open-launch-weapp
          id="launch-btn"
          :username="gh_xxxxx"
          :path="pages/index.html"
          @launch="handleLaunchFn"
          @error="handleErrorFn"
  >
      <template>
          <style>.btn { display: flex;align-items: center;width: 100px;height: 100px }</style>
          <button class="btn">跳转小程序</button>
      </template>
  </wx-open-launch-weapp>
  • 2、使用的前端框架和template标签冲突的,例如VUE框架(就是把标签换一种写法,避免冲突)。
<wx-open-launch-weapp
          id="launch-btn"
          :username="gh_xxxxx"
          :path="pages/index.html"
          @launch="handleLaunchFn"
          @error="handleErrorFn"
  >
      <script type="text/wxtag-template">
          <style>.btn { display: flex;align-items: center;width: 100px;height: 100px }</style>
          <button class="btn">跳转小程序</button>
      </script>
  </wx-open-launch-weapp>
  • 3、不管冲突不冲突都能用的(就是动态的生成标签内容,下面的例子是在vue中用v-html实现的,也可以用docment对象来动态的生成节点在加到页面)。
<template>
    <div v-html="html"></div>
</template>
<script>
 export default {
        data () {
            return {
               html:'<wx-open-launch-weapp id="launch-btn" username="gh_xxxx" path="/pages/index.html" @launch="handleLaunchFn" @error="handleErrorFn"><template><style>.btn { display: flex;align-items: center; }</style><button class="btn">跳转小程序</button></template></wx-open-launch-weapp>' 
            }
        },
        created() {
        },
        mounted() {
        },
        methods: {
          handleLaunchFn (e) {
              console.log(e)
          },
          handleErrorFn(e){
              console.log('fail', e.detail);
          },                                            
        }               
       }                
</script>

7、获取浏览器环境

在使用微信相关方法时,我们最好先判断下是否在微信环境,避免不必要的报错,这里我们通过navigator.userAgent来进行浏览器类型判断 eg:

const ua = navigator.userAgent.toLowerCase();
export const isWeChat = ua.includes("micromessenger"); // 是否为微信环境
export const isAlipay = ua.includes("alipay");  // 是否为支付宝环境

isWeChat为true时,为微信环境,我们再进行权限验证配置注入和标签的引入。

注意:

  • 1.wx.config接口中配置openTagList项,不然标签出不了

  • 2.需要真机调试,开发者工具无效

  • 3.标签中的path再设置小程序路径时必须加上“.html”

  • 4.跳转小程序按钮在vue项目中需要放在内,样式也要写在该标签内。如下:

<script type="text/wxtag-template">
       <style>.btn { padding: 12px; border: 1px solid red; }</style>
       <button class="btn">打开小程序</button>
</script>
  • 5.当vue路由为history模式时,ios手机上兼容问题(这个是和微信缓存机制相关)

原因:ios下微信会缓存第一次进入的页面地址,如果从微信一级页面跳转到二级页面,
由于vue是单页应用,不会刷新页面,vue路由地址变了,和微信缓存的地址不一致,
所以在进行wxConfig时传入的url和微信缓存的url不一致会导致jsdk调起失败,进而导致无法生效

解决办法:

// 刷新一下当前页面
reloadPage() {
      if (!this.$utils.isIOS()) {
        return;
      } else {
        const currUrl = location.href;
        const isReload = currUrl.indexOf("?reload=1") > -1 ? true : false;
        if (!isReload) {
          location.replace(currUrl + "?reload=1");
        }
      }
    },

参考文档:

pay.weixin.qq.com/wiki/doc/ap… developers.weixin.qq.com/doc/offiacc… developers.weixin.qq.com/community/d…