Last active: 2 years ago
import { configWeixinService } from '@/store/helper';
import wx from '@tybys/jweixin';
import { useBoolean } from 'ahooks';
import { message } from 'antd';
import { useEffect, useRef, useState } from 'react';
import styled from 'styled-components';
/**
* 跳转到小程序组件
*
* 利用 absolute 定位将开放标签浮动在目标元素上,
* 以实现点击时触发开放标签。
*
* [微信开放标签文档](https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_Open_Tag.html#%E8%B7%B3%E8%BD%AC%E5%B0%8F%E7%A8%8B%E5%BA%8F%EF%BC%9Awx-open-launch-weapp)
* @returns
*/
const OpenMiniprog = ({ appId }: { appId: string | undefined }) => {
const wrapperRef = useRef<HTMLDivElement>(null);
const wxRef = useRef<HTMLDivElement>(null);
const [btnSize, setBtnSize] = useState({
width: 0,
height: 0,
});
const [loading, setLoading] = useBoolean(false);
useEffect(() => {
async function getSign() {
setLoading.setTrue();
if (!appId) return console.error(`Error miniprogram appId: ${appId}`);
const wrapper = wrapperRef.current;
const width = wrapper?.clientWidth ?? 0;
const height = wrapper?.clientHeight ?? 0;
setBtnSize({
width,
height,
});
const { appid, timestamp, nonceStr, signature } =
await configWeixinService();
/**
* wx-open-launch-weapp - 指H5跳转小程序
* wx-open-launch-app - 指H5跳转app
* wx-open-subscribe - 服务号订阅通知按钮
* wx-open-audio - 音频播放
*/
wx.config({
// debug: true, // 开启调试模式,调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印
appId: appid, // 必填,公众号的唯一标识
timestamp, // 必填,生成签名的时间戳
nonceStr, // 必填,生成签名的随机串
signature, // 必填,签名
jsApiList: [], // 必填,需要使用的 JS 接口列表
openTagList: ['wx-open-launch-weapp'], // 可选,需要使用的开放标签列表,例如['wx-open-launch-app']
});
const wxx = wxRef.current;
wxx?.addEventListener('ready', () => setLoading.setFalse());
wxx?.addEventListener('error', (e) => console.error(e));
}
getSign();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [appId]);
return (
<>
<Wrapper
ref={wrapperRef}
onClick={() => {
if (loading) message.info('小程序加载中');
}}
>
{/* @ts-ignore */}
<wx-open-launch-weapp
ref={wxRef}
id="launch-btn"
username={appId}
path="/"
>
<script type="text/wxtag-template">
<style>{`.btn {
opacity: 0;
border: none;
}`}</style>
<button
className="btn"
style={{
...btnSize,
}}
></button>
</script>
{/* @ts-ignore */}
</wx-open-launch-weapp>
</Wrapper>
</>
);
};
export default OpenMiniprog;
const Wrapper = styled.div`
display: flex;
width: 100%;
height: 100%;
flex: 1;
position: absolute;
`;