Skip to content

Instantly share code, notes, and snippets.

@lllyin
Last active July 2, 2019 09:55
Show Gist options
  • Save lllyin/e4d6c6567c9e7014079f4b46596cd1d5 to your computer and use it in GitHub Desktop.
Save lllyin/e4d6c6567c9e7014079f4b46596cd1d5 to your computer and use it in GitHub Desktop.
miniHistory
import React, { Component } from 'react';
import wxUtils from 'utils/wxUtils';
import history from './history';
const { push, ...rest } = history;
/**
* 用于兼容在小程序内跳转的一套API
* 接口参数与history API一致
*/
// tslint:disable-next-line: no-any
declare var window: Window & { wx: any; __wxjs_environment: string };
const TABS = ['home', 'product/category', 'order/list', 'shopCart', 'profile'];
export const miniHistory = {
...rest,
// tslint:disable-next-line: no-any
push: function(path: any, state?: any) {
if (typeof path === 'string' && window.__wxjs_environment === 'miniprogram') {
// 如果是小程序环境
const isToTab = TABS.some(tab => path.indexOf(tab) > -1);
const pathname = encodeURIComponent(path);
// 如果是回到tab页
if (isToTab) {
// var backlen = history.length;
// history.go(-backlen); // Return at the beginning
// wxUtils.router.redirectTo({
// url: `/pages/redirect/redirect?webUrl=${pathname}`,
// })
history.replace(path, state);
} else {
const url = new URL(path, 'https://suite-miniapp.dinghuo123.com');
const localPathKey = `${url.pathname}${url.search}${url.hash}`;
if (localStorage && state) {
localStorage.setItem(`locationState-${localPathKey}`, JSON.stringify(state));
}
wxUtils.router.navigateTo({
url: `/pages/redirect/redirect?webUrl=${pathname}`,
success: function() {
const localStateStr = localStorage.getItem(`locationState-${localPathKey}`);
if (localStorage && localStateStr) {
history.location.state = JSON.parse(localStateStr);
}
},
fail: function() {
localStorage.removeItem(`locationState-${localPathKey}`);
},
});
}
} else {
push(path, state);
}
},
};
/**
* 当从H5跳转到微信小程序页面时候,如果有pushState,state会丢失,所以需要将state暂存在localStorage中
* 后面再取出
* 此组件需要配合miniHistory API使用(上面的那个)
*
* miniHistory 用于把state存到缓存
* useMiniHistorysState 用于从缓存中取出
*
* @param Target 被包裹的目标组件
*/
// tslint:disable-next-line: no-any
export function useMiniHistorysState(Target: React.ComponentClass<any, any>) {
return class UseMiniHistoryProvider extends Component {
// tslint:disable-next-line: no-any
constructor(props: any) {
super(props);
const { location } = history;
const localPathKey = `${location.pathname}${location.search}${location.hash}`;
const pathLocalState = localStorage.getItem(`locationState-${localPathKey}`);
if (pathLocalState) {
try {
history.location.state = JSON.parse(pathLocalState);
} catch (e) {
console.error(e);
}
}
}
render() {
return <Target {...this.props} />;
}
};
}
import { NavigateParams } from './Types';
// tslint:disable-next-line: no-any
declare var window: Window & { wx: any; __wxjs_environment: string };
// 动态引入js文件
const importScript = (sSrc: string) => {
return new Promise((resolve, reject) => {
const oJsSDK = document.querySelector('#jsSDK');
if (oJsSDK && oJsSDK.getAttribute('src') === sSrc) {
// js-sdk已经存在了
resolve(window.wx);
return;
}
const oScript = document.createElement('script');
const oHead = document.head || document.getElementsByTagName('head')[0];
oScript.type = 'text/javascript';
oScript.setAttribute('id', 'jsSDK');
oScript.async = true;
oScript.onerror = e => {
reject(`The script ${sSrc} is not accessible.`);
};
oScript.onload = () => {
resolve(window.wx);
};
oHead.appendChild(oScript);
oScript.src = sSrc;
});
};
/**
* 这里主要处理重复点击然后会多次调用 wx 的路由方法的问题
* difftime: 时间差ms,做一个限制,1s以内只有一次跳转
*/
const difftime = 1000;
let startDate = Number(new Date()) - difftime;
function handleNavigate(funcName: string, params: NavigateParams) {
const miniProgram = wxUtils.getMiniProgram() || {};
const func = miniProgram[funcName];
if (!func || window.__wxjs_environment !== 'miniprogram') {
console.error('不在微信环境中。');
return;
}
if (Number(new Date()) - startDate > difftime) {
func({
...params,
complete() {
params.complete && params.complete();
},
fail() {
params.fail && params.fail();
},
});
startDate = Number(new Date());
}
}
export const wxUtils = {
// 初始化微信JS-SDK
init: function() {
const wxJsSDK = 'https://res.wx.qq.com/open/js/jweixin-1.4.0.js';
return importScript(wxJsSDK);
},
getWx() {
return window.wx ? window.wx : {};
},
getMiniProgram() {
return this.getWx().miniProgram;
},
isMiniProgram() {
return window.__wxjs_environment === 'miniprogram';
},
router: {
navigateTo(params: NavigateParams) {
handleNavigate('navigateTo', params);
},
switchTab(params: NavigateParams) {
handleNavigate('switchTab', params);
},
reLaunch(params: NavigateParams) {
handleNavigate('reLaunch', params);
},
redirectTo(params: NavigateParams) {
handleNavigate('redirectTo', params);
},
navigateBack(params: NavigateParams) {
handleNavigate('navigateBack', params);
},
},
};
wxUtils.init();
export default wxUtils;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment