封装 withRouter

This commit is contained in:
Wang Kejun 2022-07-04 12:16:32 +08:00
parent c47153fb5f
commit eb2a6cc022
9 changed files with 46 additions and 79 deletions

4
lib/page.web.d.ts vendored
View File

@ -6,7 +6,7 @@ import { BasicFeatures } from './features';
import { ExceptionHandler } from './types/ExceptionRoute';
import { Feature } from './types/Feature';
import { OakComponentOption, OakPageOption } from './types/Page';
export declare function createPage<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, Proj extends ED[T]['Selection']['data'], FormedData extends WechatMiniprogram.Component.DataOption, IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption = {}, TProperty extends WechatMiniprogram.Component.PropertyOption = {}, TMethod extends WechatMiniprogram.Component.MethodOption = {}>(options: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData, IsList, TData, TProperty, TMethod>, features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD, exceptionRouterDict: Record<string, ExceptionHandler>, context: Cxt): () => JSX.Element;
export declare function createComponent<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, FormedData extends WechatMiniprogram.Component.DataOption, IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption = {}, TProperty extends WechatMiniprogram.Component.PropertyOption = {}, TMethod extends WechatMiniprogram.Component.MethodOption = {}>(options: OakComponentOption<ED, T, Cxt, AD, FD, FormedData, IsList, TData, TProperty, TMethod>, features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD, exceptionRouterDict: Record<string, ExceptionHandler>, context: Cxt): () => JSX.Element;
export declare function createPage<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, Proj extends ED[T]['Selection']['data'], FormedData extends WechatMiniprogram.Component.DataOption, IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption = {}, TProperty extends WechatMiniprogram.Component.PropertyOption = {}, TMethod extends WechatMiniprogram.Component.MethodOption = {}>(options: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData, IsList, TData, TProperty, TMethod>, features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD, exceptionRouterDict: Record<string, ExceptionHandler>, context: Cxt): (props: any) => JSX.Element;
export declare function createComponent<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>, FormedData extends WechatMiniprogram.Component.DataOption, IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption = {}, TProperty extends WechatMiniprogram.Component.PropertyOption = {}, TMethod extends WechatMiniprogram.Component.MethodOption = {}>(options: OakComponentOption<ED, T, Cxt, AD, FD, FormedData, IsList, TData, TProperty, TMethod>, features: BasicFeatures<ED, Cxt, AD & CommonAspectDict<ED, Cxt>> & FD, exceptionRouterDict: Record<string, ExceptionHandler>, context: Cxt): (props: any) => JSX.Element;
export declare type MakeOakPage<ED extends EntityDict, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>> = <T extends keyof ED, Proj extends ED[T]['Selection']['data'], FormedData extends WechatMiniprogram.Component.DataOption, IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption, TProperty extends WechatMiniprogram.Component.PropertyOption, TMethod extends WechatMiniprogram.Component.MethodOption>(options: OakPageOption<ED, T, Cxt, AD, FD, Proj, FormedData, IsList, TData, TProperty, TMethod>) => JSX.Element;
export declare type MakeOakComponent<ED extends EntityDict, Cxt extends Context<ED>, AD extends Record<string, Aspect<ED, Cxt>>, FD extends Record<string, Feature<ED, Cxt, AD & CommonAspectDict<ED, Cxt>>>> = <T extends keyof ED, FormedData extends WechatMiniprogram.Component.DataOption, IsList extends boolean, TData extends WechatMiniprogram.Component.DataOption, TProperty extends WechatMiniprogram.Component.PropertyOption, TMethod extends WechatMiniprogram.Component.MethodOption>(options: OakComponentOption<ED, T, Cxt, AD, FD, FormedData, IsList, TData, TProperty, TMethod>) => JSX.Element;

View File

@ -29,22 +29,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.createComponent = exports.createPage = void 0;
const React = __importStar(require("react"));
const PullToRefresh_1 = __importDefault(require("./platforms/web/PullToRefresh"));
const Wrapper_1 = __importDefault(require("./platforms/web/Wrapper"));
const router_1 = __importDefault(require("./platforms/web/router"));
const lodash_1 = require("lodash");
const page_common_1 = require("./page.common");
function makeCommonComponentMethods(features, exceptionRouterDict, formData) {
return {
resolveInput: (input, keys) => {
const { currentTarget, detail } = input;
const { dataset } = currentTarget;
const { value } = detail;
const { currentTarget, target } = input;
const { value, dataset } = target;
const result = {
dataset,
value,
};
if (keys) {
keys.forEach((k) => (0, lodash_1.assign)(result, {
[k]: detail[k],
[k]: target[k],
}));
}
return result;
@ -114,7 +113,7 @@ function createPage(options, features, exceptionRouterDict, context) {
});
}
if (methods) {
const { onLoad, onPullDownRefresh, onReachBottom, ...restMethods } = methods;
const { onPullDownRefresh, onReachBottom, ...restMethods } = methods;
for (const m in restMethods) {
(0, lodash_1.assign)(this, {
[m]: restMethods[m].bind(this),
@ -125,7 +124,6 @@ function createPage(options, features, exceptionRouterDict, context) {
lifetimes?.created && lifetimes.created.call(this);
hiddenMethods.subscribe.call(this);
lifetimes?.attached && lifetimes.attached.call(this);
onLoad.call(this, this.props);
}
features = features;
isReachBottom = false;
@ -153,8 +151,10 @@ function createPage(options, features, exceptionRouterDict, context) {
this.isReachBottom = isCurrentReachBottom;
}
componentDidMount() {
methods?.onLoad && methods.onLoad.call(this, this.props);
methods?.onReady && methods.onReady.call(this);
lifetimes?.ready && lifetimes.ready.call(this);
pageLifetimes?.show && pageLifetimes.show.call(this);
}
componentWillUnmount() {
hiddenMethods.unsubscribe.call(this);
@ -162,7 +162,6 @@ function createPage(options, features, exceptionRouterDict, context) {
lifetimes?.detached && lifetimes.detached.call(this);
}
render() {
pageLifetimes?.show && pageLifetimes.show();
const Render = render.call(this);
const { oakLoading } = this.state;
return React.cloneElement(<PullToRefresh_1.default onRefresh={() => {
@ -174,7 +173,7 @@ function createPage(options, features, exceptionRouterDict, context) {
}}/>, {}, Render);
}
}
return () => <Wrapper_1.default PageWrapper={OakPageWrapper}/>;
return (0, router_1.default)(OakPageWrapper);
}
exports.createPage = createPage;
function createComponent(options, features, exceptionRouterDict, context) {
@ -216,17 +215,17 @@ function createComponent(options, features, exceptionRouterDict, context) {
isReachBottom = false;
componentDidMount() {
lifetimes?.ready && lifetimes.ready.call(this);
pageLifetimes?.show && pageLifetimes.show.call(this);
}
componentWillUnmount() {
hiddenMethods.unsubscribe.call(this);
lifetimes?.detached && lifetimes.detached.call(this);
}
render() {
pageLifetimes?.show && pageLifetimes.show();
const Render = render.call(this);
return Render;
}
}
return () => <Wrapper_1.default PageWrapper={OakPageWrapper}/>;
return (0, router_1.default)(OakPageWrapper);
}
exports.createComponent = createComponent;

View File

@ -1,4 +0,0 @@
/// <reference types="react" />
export default function Wrapper(props: {
PageWrapper: any;
}): JSX.Element;

3
lib/platforms/web/router.d.ts vendored Normal file
View File

@ -0,0 +1,3 @@
import * as React from 'react';
declare const withRouter: (Component: React.ComponentType<any>) => (props: any) => JSX.Element;
export default withRouter;

View File

@ -28,6 +28,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
//react
const React = __importStar(require("react"));
const react_router_dom_1 = require("react-router-dom");
const url_1 = __importDefault(require("url"));
function getParams(location) {
const { search, state } = location;
@ -39,20 +40,19 @@ function getQuery(url) {
if (!url) {
return query;
}
const parseUrl = url_1.default.parse(url, true);
const parseUrl = url_1.default.parse(url, true, false);
if (parseUrl.query) {
query = parseUrl.query;
}
return query;
}
function Wrapper(props) {
const { PageWrapper } = props;
// const navigate = useNavigate();
// const location = useLocation();
// const params = getParams(location);
const navigate = {};
const location = {};
const params = {};
return <PageWrapper navigate={navigate} location={location} {...params}/>;
}
exports.default = Wrapper;
const withRouter = (Component) => {
const ComponentWithRouterProp = (props) => {
const navigate = (0, react_router_dom_1.useNavigate)();
const location = (0, react_router_dom_1.useLocation)();
const params = getParams(location);
return (<Component {...props} navigate={navigate} location={location} {...params}/>);
};
return ComponentWithRouterProp;
};
exports.default = withRouter;

View File

@ -9,12 +9,14 @@
"oak-domain": "file:../oak-domain",
"oak-external-sdk": "file:../oak-external-sdk",
"oak-memory-tree-store": "file:../oak-memory-tree-store",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-router-dom": "^6.3.0",
"rmc-pull-to-refresh": "^1.0.13",
"uuid": "^8.3.2"
},
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.1.0",
"react-router-dom": "^6.3.0"
},
"devDependencies": {
"@babel/cli": "^7.12.13",
"@babel/core": "^7.12.13",

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import PullToRefresh from './platforms/web/PullToRefresh';
import Wrapper from './platforms/web/Wrapper';
import withRouter from './platforms/web/router';
import { assign, omit } from 'lodash';
import { CommonAspectDict } from 'oak-common-aspect';
import { Aspect, Context, EntityDict } from 'oak-domain/lib/types';
@ -56,10 +56,9 @@ function makeCommonComponentMethods<
): OakCommonComponentMethods<ED, T> &
ComponentThisType<ED, T, FormedData, IsList, TData, TProperty, TMethod> {
return {
resolveInput: (input: WechatMiniprogram.CustomEvent, keys) => {
const { currentTarget, detail } = input;
const { dataset } = currentTarget;
const { value } = detail;
resolveInput: (input: React.BaseSyntheticEvent, keys) => {
const { currentTarget, target } = input;
const { value, dataset } = target;
const result = {
dataset,
value,
@ -67,7 +66,7 @@ function makeCommonComponentMethods<
if (keys) {
keys.forEach((k) =>
assign(result, {
[k]: detail[k],
[k]: target[k],
})
);
}
@ -329,7 +328,7 @@ export function createPage<
);
}
}
return () => <Wrapper PageWrapper={OakPageWrapper} />;
return withRouter(OakPageWrapper);
}
@ -461,7 +460,7 @@ export function createComponent<
return Render;
}
}
return () => <Wrapper PageWrapper={OakPageWrapper} />;
return withRouter(OakPageWrapper);
}
export type MakeOakPage<

View File

@ -1,34 +0,0 @@
//react
import * as React from 'react';
import {
useNavigate,
NavigateFunction,
useSearchParams,
useLocation,
} from 'react-router-dom';
import URL from 'url';
function getParams(location: { state: object; search: string }) {
const { search, state } = location;
const query = getQuery(search);
return Object.assign({}, query, state);
}
function getQuery(url: string) {
let query = {};
if (!url) {
return query;
}
const parseUrl = URL.parse(url, true);
if (parseUrl.query) {
query = parseUrl.query;
}
return query;
}
export default function Wrapper(props: { PageWrapper: any }) {
const { PageWrapper } = props;
return <PageWrapper />;
}

View File

@ -23,20 +23,20 @@ function getQuery(url: string) {
if (!url) {
return query;
}
const parseUrl = URL.parse(url, true);
const parseUrl = URL.parse(url, true, false);
if (parseUrl.query) {
query = parseUrl.query;
}
return query;
}
export function withRouter(PageWrapper: React.ComponentType<any>) {
function ComponentWithRouter(props: any) {
const withRouter = (Component: React.ComponentType<any>) => {
const ComponentWithRouterProp = (props: any) => {
const navigate = useNavigate();
const location = useLocation();
const params = getParams(location as Location);
return (
<PageWrapper
<Component
{...props}
navigate={navigate}
location={location}
@ -45,5 +45,7 @@ export function withRouter(PageWrapper: React.ComponentType<any>) {
);
};
return ComponentWithRouter;
return ComponentWithRouterProp;
}
export default withRouter;