当前位置: 首页 > 工具软件 > open-qq > 使用案例 >

VUE使用 wx-open-launch-app 组件开发微信打开APP功能

卜鹏
2023-12-01

移动端打开app方式:

普通浏览器用第三方 openinstall

微信环境用微信开放标签 wx-open-launch-app

使用说明

所有开放标签都能像普通的HTML标签一样在页面中直接使用,不需要再进行额外的处理。

如果所使用的标签允许提供插槽,由于插槽中模版的样式是和页面隔离的,因此需要注意在插槽中定义模版的样式。插槽模版及样式均需要通过<template></template>进行包裹。对于Vue等视图框架,为了避免template标签冲突的问题,可使用<script type="text/wxtag-template"><script>进行代替,来包裹插槽模版和样式。另外,对于具名插槽还需要通过slot属性声明插槽名称,下文标签插槽中的default插槽为默认插槽,可不声明插槽名称。

对于标签事件,均可通过event.detail获得详细信息。如果无特殊说明,下文标签事件说明中的返回值均指代event.detail中的内容。

另外,需要注意以下几点:

  1. 页面中与布局和定位相关的样式,如position: fixed; top -100;等,尽量不要写在插槽模版的节点中,请声明在标签或其父节点上;
  2. 对于有CSP要求的页面,需要添加白名单frame-src https://*.qq.com webcompt:,才能在页面中正常使用开放标签。

template.vue:

<template>
  <div class="page">
    <div class="container">
      <div class="btn-group" @click="launch" v-if="wechatState">
        <wx-open-launch-app
          id="launch-btn"
          @error="handleError"
          @launch="handleLaunch"
          :extinfo="dataStr"
          appid="wx1111111111111111111111111"
        >
          <script type="text/wxtag-template">
            <style>
              .btn {
                padding: 12px;
              }
              .download {
                color: #ffffff;
                background: #2b303c;
                width:100%;
                height:100%;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 16px;
                font-family: PingFangSC-Medium, PingFang SC;
                font-weight: 500;
                border-radius: 2px;
              }
            </style>
            <button class="download btn" style="height:50px;width:100%;border:none;">广新App唤起测试</button>
          </script>
        </wx-open-launch-app>
      </div>
    </div>
  </div>
</template>
<script>
import { Dialog } from "vant";
import openApp from "~/components/open-app.vue";

export default {
  components: {
    openApp,
  },
  head() {
    return {
      title: "",
    };
  },
  data() {
    return {
      wechatState: false, // 是否显示微信打开app功能按钮
      openAppState: false, //  显示打开app 的按钮
      dataStr:'',
    };
  },
  methods: {
    closeTip() {},
    openUrl() {
      this.judgePhoneType();
    },
    judgePhoneType() {
      var u = navigator.userAgent;
      var isWeixin = u.toLowerCase().indexOf("micromessenger") !== -1; // 微信内
      var isAndroid = u.indexOf("Android") > -1 || u.indexOf("Linux") > -1; //android终端
      var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
      // 微信内
      if (isWeixin) {
        Dialog.alert({ message: "微信浏览器" });
      } else {
        if (isAndroid) this.openInstallHandle("android"); //android端
        if (isIOS) this.openInstallHandle("ios"); //ios端
      }
    },

    launch() {
      if (!this.wechatState) {
        Dialog.alert({ message: "不支持标签降级处理" });
        return;
      }
    },

    openInstallHandle(type) {
      var data = OpenInstall.parseUrlParams();
      ///openinstall.js中提供的工具函数,解析url中的所有查询参数
      new OpenInstall(
        {
          appKey: "rk4qiw",
          onready: function () {
            /*在app已安装的情况尝试拉起app*/
            this.schemeWakeup();
            var m = this;
            if (type == "ios") {
              m.wakeupOrInstall();
              return false;
            }
          },
        },
        data
      );
    },

    judgeNavigator() {
      // 微信版本号大于 7.0.12 开放标签才可进行 唤醒 app 跳转
      const wechatInfo = window.navigator.userAgent.match(
        /MicroMessenger\/([\d\.]+)/i
      );
      if (!wechatInfo) return;
      let judgewechat = wechatInfo[1].split(".");
      let flag = false;
      //   Dialog.alert({ message: "调用结果" + JSON.stringify(wechatInfo) });
      if (judgewechat[0] >= 7&&judgewechat[1] >= 0&&judgewechat[2] >= 12) {
            this.wechatState = true;
            console.log("当前符合 h5 打开指定app");
            flag = true;
      }
      if (!flag) Dialog.alert({ message: "请升级当前微信版本" });
    },

    handleError(e) {
      console.log("error", e, e.detail);
      // 跳到下载download.html页面
      // Dialog.alert({ message: "error:" + JSON.stringify(e.detail) });
    },

    handleLaunch(e) {
      console.log("success", e, e.detail);
      // Dialog.alert({ message: "success:" + JSON.stringify(e) });
    },

    launchBtnInit() {
      // 获取 homelist 组件传递过来的打开app的 显示状态
      var btn = document.getElementById("launch-btn");
      if (!btn) return;
      btn.addEventListener("launch", function (e) {
        console.log("success",e,e.detail);
        Dialog.alert({ message: "success:" + JSON.stringify(e.detail) });
      });
      btn.addEventListener("error", function (e) {
        console.log("error",e,e.detail);
        if (e.isTrusted == false) {
					// alert("跳转失败")
					window.open("https://www.baidu.com")
				}
        Dialog.alert({ message: "error:" + JSON.stringify(e.detail) });
      });
    },

    wechatInit() {
      this.$axios
        .get(
          `/napi/wechat/get-signature?url=${window.encodeURIComponent(
            window.location.href
          )}`
        )
        .then((res) => {
          if (res.success && res.data) {
            this.wechatConfig(res.data);
          } else {
            console.log("获取微信签名失败");
          }
        });
    },

    wechatConfig(config) {
      let that = this;
      wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: config.appId, // 必填,公众号的唯一标识
        timestamp: config.timestamp, // 必填,生成签名的时间戳
        nonceStr: config.nonceStr, // 必填,生成签名的随机串
        signature: config.signature, // 必填,签名,见附录1
        jsApiList: ["onMenuShareAppMessage", "onMenuShareTimeline"], // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
        openTagList: ["wx-open-launch-app"], // 获取开放标签权限
      });
      wx.error(function (err) {
        console.log("错误:", err);
        Dialog.alert({ message: "错误:" + JSON.stringify(err) });
      });
      wx.ready(function () {
        // 分享朋友圈
        console.log("微信签名成功");
        Dialog.alert({ message: "微信签名成功" });
        // that.launchBtnInit(); // 外部浏览器唤起app
        that.wechatState = true;
        wx.onMenuShareTimeline({
          title: "xxxx", // 分享标题
          link: "", // 分享链接
          imgUrl: window.location.origin + "/static/img/appLogo.jpg", // 分享图标
          success: () => {
            // 用户确认分享后执行的回调函数
            console.log("分享成功");
            Dialog.alert({ message: "分享成功" });
          },
          cancel: () => {},
        });
        let appLogo = window.location.origin + "/static/img/appLogo.jpg"; // app图标
        // 分享朋友
        wx.onMenuShareAppMessage({
          title: "xxxxx", // 分享标题
          desc: "分享内容", // 分享描述
          link: "", // 分享链接
          imgUrl: window.location.origin + "/static/img/appLogo.jpg", // 分享图标
          type: "", // 分享类型,music、video或link,不填默认为link
          dataUrl: "", // 如果type是music或video,则要提供数据链接,默认为空
          success: () => {
            // 用户确认分享后执行的回调函数
            Dialog.alert({ message: "分享成功" });
          },
          cancel: function cancel() {
            // 用户取消分享后执行的回调函数
          },
        });
      });
    },
  },

  computed: {},

  mounted() {
    this.judgeNavigator();
    this.wechatInit(); // 微信标签唤起app
    let data = {
      uri: `http://www.xxx.com/common/webview?url=${encodeURIComponent(
        window.location.origin+'/info/detail?id=48&goindex=1'
      )}`
    };
    this.dataStr=JSON.stringify(data);
    // this.$nextTick(() => {
    //   this.$refs.openaRef.commitChildHandle({
    //     title: "", // 分享标题
    //     desc: "分享内容~~~~~", // 分享描述
    //     link: "", // 分享链接
    //     imgUrl: "", // 分享图标
    //   });
    // });
  },
  created() {},
  onShow() {},
};
</script>

style.css

<style lang="scss" scoped>
.page {
  overflow: auto;
  height: 100vh;
  background: #fff;
  .container {
    padding-top: 80px;
    .result-status {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      margin-bottom: 128px;
      margin-top: 113px;
      .status-icon {
        height: 50px;
        width: 50px;
        margin-bottom: 10px;
      }
      span {
        font-size: 16px;
        font-family: PingFangSC-Medium, PingFang SC;
        font-weight: 500;
        color: #2b303c;
      }
    }
    .btn-group {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
      margin: 0 auto;
      width: 320px;
      height: 44px;
      border: 1px solid #eee;
      position: relative;
      .search {
        color: #2b303c;
      }
    }
  }
}
#launch-btn {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
</style>

关键点:

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

2:登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”,(如果点击弹出loading弹窗一闪而过,说明开发标签触发成功安全域名没有配置)

3:在需要调用JS接口的页面引入如下JS文件:http://res.wx.qq.com/open/js/jweixin-1.6.0.js (支持https),记得使用Https://

4:对于Vue等视图框架,为了避免template标签冲突的问题,可使用<script type="text/wxtag-template"><script>进行代替,来包裹插槽模版和样式

5:经过测试发现标签内定义的样式真的很尴尬,且不受控制,所以我们直接将标签用 CSS 绝对定位并设透明度为 opacity: 0, 盖在了我们原本的设计图上

6:透明度为 opacity: 0 的标签 <script type="text/wxtag-template"> 不能为空,否则宽高会被解析为0,也就是按钮根本点击不到

7:标签内 appid 填写的是 微信公众号内填写的你们 app 的 appid

8:extinfo 内填的是传递给唤起 app 的数据,而我们发现微信7.0.15版本在ios上,有概率会接收数据失败,不知道是微信的问题还是我们IOS的写法问题

9:在 VUE 的 mounted 生命周期回调函数内侦听开放标签的回调事件

      注意:直接在标签内绑定函数@launch="" @error="",效果会更好

mounted(){
    var btn = document.getElementById(this.id)
    btn.addEventListener('launch', e => {
        // 在此处可设置粘贴板内数据,数据是传递给 app 的参数进,
        console.log('success');
    });
    btn.addEventListener('error', e => {
        // 在此处可设置粘贴板内数据,数据是传递给 app 的参数进,
        console.log('fail', e.detail);
        // 唤醒失败的情况下,可用于降级处理比如在此处跳转到应用宝
    });
}

如何动态生成开发标签:vue的话用v-html可以实现

let script = document.createElement('script')  
script.type = 'text/wxtag-template' let { image = '' } = item.material && item.material[0];     
script.text = `<div style="height:70px;width:100%; background:red"> <img src="${image}" width="100%" height="70px" /></div>` 
let html = `<wx-open-launch-weapp style="width:100%;display:block;height:70px;" username="${item.appid}"path="${item.url}">${script.outerHTML}</wx-open-launch-weapp>`
let id = "launch_" + index
document.getElementsByClassName(id)[0].innerHTML = html;

 类似资料: