Prerequisites
The function positioning of the author's project on WeChat is the basic function transaction and service, notifying users of transaction reminders, transaction flow, etc., and the APP is the main transaction function. Previously, there were drainage buttons on multiple pages to jump to the App, and the function points were relatively crude, directly location.href = 应用宝链接
. Now there is demand for the product, and it is said that the label provided by WeChat should be used to evoke the App
Requirements:
All the parts that jump to the app download page, change to
Demo first
In case of indecision, the official website document . After viewing it, it is very similar to the WeChat JS-SDK function. I will skip it without nonsense here. According to the official website demo, write the example into the business code
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 (
<div className="Download" onClick={onHandleClick}>
{/* @ts-ignore */}
<wx-open-launch-app
ref={wxRef}
appid="XXXX"
>
<script type='text/wxtag-template'>
<button>App内查看</button>
</script>
{/* @ts-ignore */}
</wx-open-launch-app>
</div>
)
}
export default React.memo(Download);
The test is successful, the demo can run through
Component Pilot
Now I'm doing business, using this component (Download) as a pilot to expand, I want to click on the card at the top of the page (used in multiple places, extract it into a Download component), let it evoke the App, but I have to judge its version, if the version is too low, Let it jump to the app treasure
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 (
<div className="Download" onClick={onHandleClick}>
<div className="Download__logo">
<img src={LogoImg} alt="logo" />
</div>
<div className="Download__content">
<div className="Download__content-title">雅美App</div>
<div className="Download__content-desc">长泽雅美服务专区</div>
</div>
{/* <div>1</div> */}
<div className="Download__btn">立即打开</div>
{/* @ts-ignore */}
<wx-open-launch-app
ref={wxRef}
appid="XXXXX"
style={{ position: 'fixed', top: 0, left: 0, width: '100%', height: '60px', opacity: 0.3, background: 'blue' }}
>
<script type='text/wxtag-template'>
<div style={{ position: 'fixed', top: 0, left: 0, width: '90%', height: '100%', opacity: 0.3, background: 'red' }} />
</script>
{/* @ts-ignore */}
</wx-open-launch-app>
</div>
)
}
export default React.memo(Download);
The effect is as follows:
Idea logic reference: wx-open-launch-weapp style problem , I also color it for follow-up observation
Test synchronization, you can click on the card to jump, OK, next step, add code like this to all the places where you need to click to jump to the page
<wx-open-launch-app
ref={wxRef}
appid="XXXX"
style={{ position: 'fixed', top: 0, left: 0, width: '100%', height: '60px', opacity: 0.3, background: 'blue' }}
>
<script type='text/wxtag-template'>
<div style={{ position: 'fixed', top: 0, left: 0, width: '90%', height: '100%', opacity: 0.3, background: 'red' }} />
</script>
{/* @ts-ignore */}
</wx-open-launch-app>
Package component WxOpenLaunchApp
If so, you can package it into a component, give it a name: WxOpenLaunchApp
Wrap the content that evokes the App into a component, thunder children and style two props, the code is as follows:
import React, { useEffect, useRef, forwardRef } from 'react';
import { toDownloadApp } from 'utils';
export interface WxOpenLaunchAppProps {
children: React.ReactNode;
style?: React.CSSProperties;
}
const WxOpenLaunchApp: React.FC<WxOpenLaunchAppProps> = 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 (
<div className="wx-open-launch-app">
{/* @ts-ignore */}
<wx-open-launch-app
ref={wxRef}
appid="XXXX"
style={style}
>
<script type='text/wxtag-template'>
{children}
</script>
{/* @ts-ignore */}
</wx-open-launch-app>
</div>
)
}
export default React.memo(WxOpenLaunchApp);
Then the Download component can be much cleaner
...
const Download = () => {
...
return (
...
<div className="Download__btn">立即打开</div>
{/* @ts-ignore */}
<WxOpenLaunchApp style={{ position: 'fixed', top: 0, left: 0, width: '100%', height: '60px', opacity: 0.3, background: 'blue' }}>
<div style={{ position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', opacity: 0.3, background: 'red' }} />
</WxOpenLaunchApp>
...
)
}
...
Business ComponentOpenAppPopup
Back to the demand point, a pop-up box will pop up every clicked place, click 打开 App
, and then call up the App, in this case, the pop-up box + WxOpenLaunchApp can be combined into a component, which is released for the page to call, the name It is called OpenAppPopup
, the code is as follows:
import React, { FC } from 'react';
import { Popup, WxOpenLaunchApp, Toast } from 'components'; // 此乃公司自研组件库
export interface OpenAppPopupProps {
show: boolean;
onCancel: () => void;
onSubmit: () => void;
}
const OpenAppPopup: FC<OpenAppPopupProps> = (props) => {
const { show, onCancel, onSubmit } = props;
return (
<Popup.Group show={show}>
<Popup.Confirm
title="抱歉,此功能需在雅美App中使用"
btnSubmitText={
<div style={{ position: 'relative' }}>
打开App
<WxOpenLaunchApp style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', opacity: 0.3, background: 'blue' }}>
<div style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', opacity: 0.6, background: 'red' }} />
</WxOpenLaunchApp>
</div>
}
onCancel={onCancel}
onSubmit={onSubmit}
/>
</Popup.Group>
)
}
export default React.memo(OpenAppPopup);
The schematic diagram is as follows:
Then you can use this logic on all pages with jump apps
Encapsulation HOOK
When you click a button similar to 下载App
on each page, it will pop up OpenAppPopup
, click 打开App
, you need to judge whether your WeChat version reaches 7.0.12, if each The page should add this
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)
}
}
}
}
It's really disgusting, so I decided to pull it off into a hook. code show as below:
import { useState, useEffect } from 'react';
import { isWechat, getWeixinVersion } from 'utils';
const useEnableLaunchWeapp = () => {
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)
}
}
}
}
}, [])
return enableLaunchWeapp
}
export default useEnableLaunchWeapp;
The logic is also very simple. To judge whether it can be clicked and clickable when it is just loaded, set enableLaunchWeapp
to true. It is also very simple to use
import React, { useState, useEffect } from 'react';
import { Dispatch, History } from 'umi';
import { OpenAppPopup } from 'components';
+import { useEnableLaunchWeapp } from 'hooks';
import { toDownloadApp } from 'utils';
interface KVProps {
history: History;
}
const KV: React.FC<KVProps> = (props) => {
const { history } = props;
const [isShow, setIsShow] = useState(false);
+const enableLaunchWeapp = useEnableLaunchWeapp();
const onHandleClickToBuy = () => {
setIsShow(true);
};
const onHandleClickToSubmit = () => {
+if (!enableLaunchWeapp) {
+ toDownloadApp()
+}
}
return (
<div className="KV" style={{ background: kvBgColor }}>
<div className="KV__content">
<img src={img} alt="" />
</div>
<OpenAppPopup
show={isShow}
onCancel={() => {
setIsShow(false);
}}
onSubmit={onHandleClickToSubmit}
/>
</div>
);
};
export default React.memo(KV);
Interact with the App
The demand point says: To jump to the relative page of the App on the page where you are located, it is clearly written in the document, you can pass the parameters extinfo="your-extinfo"
, just write a random one for the client colleagues to test first
App not awakened
My mobile phone is IOS and can be evoked, but when my Android colleague was debugging, they said that when running in the background, the app can be evoked, but there is no switching action; if the process is killed, it cannot be evoked. And this problem is most likely a problem with the SDK configuration. My colleague didn't solve it after reading it for a long time, and threw him the Android access guide . I can't read Android anymore, I can only watch him
If the test is successful and you can jump over, then pass the link of this page as extinfo. After receiving the extinfo, he can make a mapping table and jump to its own page, so WxOpenLaunchApp needs to be modified, and one more extinfo parameter. . .
postscript
Because we are using flutter, my colleague said that because the imported third-party library does not support it, it cannot be skipped, so this function needs to be set later, and I will update it when he is done.
error handling
In addition to adding monitoring error to the WxOpenLaunchApp component, and making it jump to the App if the error occurs, it is also necessary to monitor and perform fallback compatibility when WeChat or the system version does not support WeChat tags. The code is as follows:
document.addEventListener('WeixinOpenTagsError', function (e: any) {
console.error(e.detail.errMsg) // 无法使用开放标签的错误原因,需回退兼容。仅无法使用开发标签,JS-SDK其他功能不受影响
toDownloadApp()
})
Summarize
After reuse, it can be extracted into components
The production environment must be used, so it is best to have a pre-production environment
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。