前言

这几天在写微信 H5 的项目,有一个功能是网页跳转小程序,遇到了非常坑的问题,因此记录一下

坑点

开始使用

要跳转小程序,就要用到微信 SDK 的开放标签 wx-open-launch-weapp

我们需要在 jssdk 中注册

wx.config({
  // ... 其他配置按照需求配置
  openTagList: ["wx-open-launch-weapp"] // 填入这个玩意儿
})

正常使用下,我们就是这么用

<wx-open-launch-weapp
  id="launch-btn"
  username="gh_xxxxxxxx"
  path="pages/home/index?user=123&action=abc"
>
  <!-- script 标签不能省略 -->
  <script type="text/wxtag-template">
    <button>打开小程序</button>
  </script>
</wx-open-launch-weapp>

顺便吐槽,username 这个字段是小程序的原始ID,太蠢了…

好,按照以上操作,最简单版本的跳转可以了,但是问题来了,如果你需要非常复杂的样式呢?

踩坑

根据官方文档说明

如果所使用的标签允许提供插槽,由于插槽中模版的样式是和页面隔离的,因此需要注意在插槽中定义模版的样式。

意思是,写在这个标签里的模板样式,是引用不到外界的,你要么写内联样式,要么在 script 里写 style 标签。

所以当你需要在现成的一个按钮外加这么一个标签,那么你的样式可能就会混乱,甚至标签不见。

比如

<style>
  .btn {
    color: red;
  }
</style>

<wx-open-launch-weapp
  id="launch-btn"
  username="gh_xxxxxxxx"
  path="pages/home/index?user=123&action=abc"
>
  <!-- script 标签不能省略 -->
  <script type="text/wxtag-template">
    <style>
      .btn-inner {
        color: red;
      }
    </style>
    <button class="btn btn-inner">打开小程序</button>
    <!-- 无法引用到外界的 btn 样式但可以引用内部的 btn-inner -->
  </script>
</wx-open-launch-weapp>

React

如果你是在使用 React,那么可能会报错 not in JSX.IntrinsicElements,可以在 type.d.ts 中定义一个

declare global {
  namespace JSX {
    interface IntrinisicElements {
      'wx-open-launch-weapp': any
    }
  }
}

解决方法

因为我使用的是 React 所以就按照 React 写法来写实例

主要思路是将这个开放标签当成一层 cover 覆盖在我们需要的样式上面

const WxOpenLaunchButton: FC = ({ children }) => {
  return (
    <div
      style={{
        position: "relative",
        width: 100, // 宽高也可通过 props 传进来,这里只做演示
        height: 100, // 外层宽高必须定义,不然内部的开放标签拿不到宽高
      }}
    >
      {children}
      <wx-open-launch-weapp
        id="launch-btn"
        username="gh_xxxxxxxx"
        path="pages/home/index?user=123&action=abc"
        style={{
          width: "100%",
          height: "100%",
          position: "absolute",
          top: 0,
          left: 0,
        }}
      >
        <!-- script 标签不能省略 -->
        <script type="text/wxtag-template">
          <div 
            style={{
              width: "100%",
              height: "100%",
              position: "absolute",
              top: 0,
              left: 0,
              opacity: 0, // 透明度 0 让其不可见但能点击
            }}
          />
        </script>
      </wx-open-launch-weapp>
    </div>
  )
}

封装好之后,下次使用只需要引用这个组件就可以啦

const Page = () => {
  return (
    <WxOpenLaunchButton>
      <div className="btn">Open WeApp</div>
    </WxOpenLaunchButton>
  )
}

总结

微信这文档是真的坑,而且整这么一个玩意儿还不说清楚,还需要自己瞎摸索,不过好在摸索出来了。