vue 实现微信公众号 h5 跳转小程序

2,467 阅读4分钟

项目概述

WechatIMG79.png

实现类似图中红色框框选中可以左右滑动的组件,点击可以跳转到对应的小程序页面。

涉及知识点

  • computed 实现分页
  • 开放标签 wx-open-launch-weapp 使用

实现

实现容器

首先我们来实现两行可以左右滑动的容器。

这边为了省事,我是选择了 vue-awesome-swiper@2.6.7

  • npm i vue-awesome-swiper@2.6.7 -S
  • main.js 引入
    • import VueAwesomeSwiper from 'vue-awesome-swiper'
    • Vue.use(VueAwesomeSwiper)
  • 文件中直接使用
    • Snipaste_2022-08-06_15-19-50.png

当然了现在我们的页面并不会非常好看,不过容器部分第一步是实现了。如下所示

Snipaste_2022-08-06_15-21-25.png

computed 实现分页

接着就是用 computed 来实现分页,代码入下

data() {
  return {
    iconList: [
        { iconPcurl: 'http://img1.qunarzz.com/piao/fusion/1611/54/ace00878a52d9702.png', nameApp: '应用名称', id: 1 },
        { iconPcurl: 'http://img1.qunarzz.com/piao/fusion/1611/54/ace00878a52d9702.png', nameApp: '应用名称', id: 2 },
        { iconPcurl: 'http://img1.qunarzz.com/piao/fusion/1611/54/ace00878a52d9702.png', nameApp: '应用名称', id: 3 },
        { iconPcurl: 'http://img1.qunarzz.com/piao/fusion/1611/54/ace00878a52d9702.png', nameApp: '应用名称', id: 4 },
        { iconPcurl: 'http://img1.qunarzz.com/piao/fusion/1611/54/ace00878a52d9702.png', nameApp: '应用名称', id: 5 },
        { iconPcurl: 'http://img1.qunarzz.com/piao/fusion/1611/54/ace00878a52d9702.png', nameApp: '应用名称', id: 6 },
        { iconPcurl: 'http://img1.qunarzz.com/piao/fusion/1611/54/ace00878a52d9702.png', nameApp: '应用名称', id: 7 },
        { iconPcurl: 'http://img1.qunarzz.com/piao/fusion/1611/54/ace00878a52d9702.png', nameApp: '应用名称', id: 8 },
        { iconPcurl: 'http://img1.qunarzz.com/piao/fusion/1611/54/ace00878a52d9702.png', nameApp: '应用名称', id: 9 },
      ]
  }
}

computed: {
  pages () {
      const pages = []
      this.iconList.forEach((item, index) => {
        const page = Math.floor(index / 8)
        if (!pages[page]) {
          pages[page] = []
        }
        pages[page].push(item)
      })
      return pages
    }
}

因为我们默认是4个一行,一页8个,所以我们将原来的数组列表稍微更改一下数据结构,将其变为数组套数组的套娃模式,根据 innerArray 的个数来判断需要分几页。有兴趣的朋友可以自己 cv 一下代码看看实现效果。

computed 中的 pages 写好之后我们需要将原来遍历的 iconList 修改为 pages。

这样就实现了可以左右滚动的容器了。

开放标签 wx-open-launch-weapp 使用

接下来是使用微信给我们提供的标签来实现跳转微信小程序

前置准备 - 引入 js

在我们使用之前,需要在温馨公众平台里填写必要的 js接口安全域名,这里不详细说明,有需要的话可以点这里移步查看一下.

如果想在我们的项目中使用微信开放标签的话需要引入相关 js 文件。

我们打开 index.html,引入相关 js 文件。

<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

配置 config

所有需要使用开放标签的页面必须先注入配置信息,并通过openTagList字段申请所需要的开放标签。

这一步需要我们调用接口,把当前页面的 url 地址传给后端然后拿到 appId、timestamp、nonceStr 和 signature。然后进行相对应的配置。

这里不得不吐槽一下,由于后端和我都没有写过 h5 跳转小程序相关内容,公司里也是第一次遇到这种需求,一开始就产生了各种非常奇葩的情况。

当时情况是我先给后端把 openId 传过去,他给我返对应的 ticket。接着我把 ticket 传给后端,他给我返我需要的东西。。。反正最后写的两个人都懵了,还是另一个还算清醒的后端过来看了下,给我们重新整理了思路,只需要我把 url 给后端就可以了,其余的我不用管,拿值就完事了。

大致代码如下

let url = window.location.href.slice(0, window.location.href.indexOf('#'))
const res = await getSignatureInfo({ url })
wx.config({
debug: false,
appId: res.appId,
timestamp: res.timestamp,
nonceStr: res.nonceStr,
signature: res.signature,
jsApiList: ['closeWindow'],
openTagList: ['wx-open-launch-weapp']
})

配置完成之后可以通过 ready 接口处理成功验证

wx.ready(() => {
    console.log('success')
})

当控制台输出了 success 之后,我们配置这一块就成功了

wx-open-launch-weapp 使用

wx-open-launch-weapp 标签用起来其实很简单

<wx-open-launch-weapp
    :username="item.originalId"
    :path="`${item.pageUrl}?phone=${user.phone}`"
  >
    <script type="text/wxtag-template">
      code...
    </script>
  </wx-open-launch-weapp>

将需要跳转小程序的原始 id 和需要跳转到哪个路径写一下就完事了。这里比较坑的是样式问题。

处理样式

我们这里的跳转需要根据后端传的一个 appType 判断是跳转到另外的 h5 或者 公众号 或者 小程序。

本来我的思路是直接循环,判断当前 app 是否是跳转小程序,如果是就渲染 wx-open-launch-weapp,否则渲染普通的 div 标签。

但是这里有个大坑,wx-open-launch-weapp 这个鬼东西里面 script 写的 dom 元素是没办法使用 rem 的。等于说只要是小程序跳转类型的 icon 大小都会和另外两个类型的大小有一些细微的差别。这种差别在正常手机上看倒是还好,但是只要用 pad 打开那直接爆炸。而且这个标签还必须在真机上用微信打开才能调试,等于只要我有一些改动,不论大小都要先上传测试环境然后再尝试效果,总之就是极其之坑。

花了一点功夫网上冲浪寻找办法最终找到一个我个人认为最好的办法 -- 蒙层。

Snipaste_2022-08-06_16-15-30.png

.icon {
    width: 25%;
    float: left;
    overflow: hidden;
    text-align: center;
    margin-bottom: .22rem;
}

通过浮动 + 相对定位的方法把所有 icon 在 .common_component 元素中渲染出来,然后还是通过 v-if 来判断当前 icon 是否是需要跳转小程序的,如果是就展示。和之前唯一的区别就是我们将开放标签中的内容提了出来,标签中只有一对 div 元素,样式就是绝对定位,宽高 100%并提高一下 z-index 的值。

这样就可以完美实现我们需要的功能了。