前提须知
笔者公司的项目在微信端的功能定位为基础功能交易及服务,通知用户交易提醒、交易流水等,而 APP 为主要的交易功能。之前是在多个页面有引流按钮跳转至 App,功能点比较粗暴,直接 location.href = 应用宝链接。现在产品有需求,说要用微信提供的标签来唤起 App
需求点:
所有跳转至 App 下载页面的部分,改成
Demo 先行
遇事不决,官网文档。查看后与微信 JS-SDK 功能点很像,这里我不废话,直接跳过。按照官网 demo,把示例写进业务代码中
import React, { useEffect, useRef } from 'react';
import { toDownloadApp, isWechat, getWeixinVersion } from 'utils';
const Download = () => {
const wxRef = useRef(null)
useEffect(() => {
if (wxRef.current) {
// @ts-ignore
wxRef.current?.addEventListener('launch', function (e: any) {
console.log('success');
});
// @ts-ignore
wxRef.current.addEventListener('error', function (e) {
console.log('fail', e.detail);
toDownloadApp()
});
}
}, [])
const onHandleClick = () => {
toDownloadApp()
}
return (
{/* @ts-ignore */}
{/* @ts-ignore */}
)
}
export default React.memo(Download);
测试成功,demo 能跑通
组件试点
现在搞业务,以这个组件(Download)为试点展开,我要点击页面顶部的卡片(多个地方使用,抽离成 Download 组件),让其唤起 App,但是要判断其版本,如果版本过低,让其跳转至应用宝
import React, { useState, useEffect, useRef } from 'react';
import LogoImg from '@/assets/images/logo.png';
import { toDownloadApp, isWechat, getWeixinVersion } from 'utils';
const Download = () => {
const wxRef = useRef(null)
const [enableLaunchWeapp, setEnableLaunchWeapp] = useState(false);
useEffect(() => {
const wxVersion = isWechat() && getWeixinVersion() || ''
if (wxVersion) {
let v = wxVersion.split('.')
if (Number(v[0]) >= 7) {
if (Number(v[1]) >= 0) {
if (Number(v[2]) >= 12) {
setEnableLaunchWeapp(true)
}
}
}
}
if (wxRef.current) {
// @ts-ignore
wxRef.current?.addEventListener('launch', function (e: any) {
console.log('success');
});
// @ts-ignore
wxRef.current.addEventListener('error', function (e) {
console.log('fail', e.detail);
toDownloadApp()
});
}
}, [])
const onHandleClick = () => {
if (!enableLaunchWeapp) {
toDownloadApp()
}
}
return (
雅美App
长泽雅美服务专区
{/* 1 */}
立即打开
{/* @ts-ignore */}
{/* @ts-ignore */}
)
}
export default React.memo(Download);
效果如下所示:
思路逻辑参考:wx-open-launch-weapp 样式问题,我也给它配上颜色,方便后续观察
测试同步,能点击卡片跳转,好,下一步,在所有需要点击跳转页面的地方加入类似这样的代码
{/* @ts-ignore */}
封装组件 WxOpenLaunchApp
如果是这样,就可以将其封装成一个组件了,起个名吧: WxOpenLaunchApp
将唤起 App 的内容包装成一个组件,暴雷 children 和 style 两个 props,代码如下:
import React, { useEffect, useRef, forwardRef } from 'react';
import { toDownloadApp } from 'utils';
export interface WxOpenLaunchAppProps {
children: React.ReactNode;
style?: React.CSSProperties;
}
const WxOpenLaunchApp: React.FC = props => {
const { style, children } = props;
const wxRef = useRef(null)
useEffect(() => {
if (wxRef.current) {
// @ts-ignore
wxRef.current?.addEventListener('launch', function (e: any) {
console.log('success');
});
// @ts-ignore
wxRef.current.addEventListener('error', function (e) {
console.log('fail', e.detail);
toDownloadApp()
});
}
}, [])
return (
{/* @ts-ignore */}
{/* @ts-ignore */}
)
}
export default React.memo(WxOpenLaunchApp);
那么 Download 组件也就可以干净很多
...
const Download = () => {
...
return (
...
立即打开
{/* @ts-ignore */}
...
)
}
...
业务组件 OpenAppPopup
回到需求点,每个点击的地方都要弹出弹出框,点击 打开 App ,再唤起 App,这样的话,弹出框 + WxOpenLaunchApp 就可以结合成一个组件,放出来供页面调用,名字就叫 OpenAppPopup ,代码如下:
import React, { FC } from 'react';
import { Popup, WxOpenLaunchApp, Toast } from 'components'; // 此乃公司自研组件库
export interface OpenAppPopupProps {
show: boolean;
onCancel: () => void;
onSubmit: () => void;
}
const OpenAppPopup: FC = (props) => {
const { show, onCancel, onSubmit } = props;
return (
打开App