mirror of https://github.com/alibaba/ice.git
feat: impl onAppear and onDisappear
This commit is contained in:
parent
8aa8764d06
commit
68fdcf8bc0
|
|
@ -17,5 +17,7 @@ export default defineConfig({
|
||||||
},
|
},
|
||||||
dropLogLevel: 'warn',
|
dropLogLevel: 'warn',
|
||||||
plugins: [pluginAuth(), pluginRaxCompat()],
|
plugins: [pluginAuth(), pluginRaxCompat()],
|
||||||
eslint: true,
|
// eslint: true,
|
||||||
});
|
ssr: false,
|
||||||
|
ssg: false,
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,10 @@
|
||||||
"@ice/plugin-rax-compat": "workspace:*",
|
"@ice/plugin-rax-compat": "workspace:*",
|
||||||
"@ice/runtime": "workspace:*",
|
"@ice/runtime": "workspace:*",
|
||||||
"ahooks": "^3.3.8",
|
"ahooks": "^3.3.8",
|
||||||
|
"rax-image": "^2.4.1",
|
||||||
"rax-is-valid-element": "^1.0.0",
|
"rax-is-valid-element": "^1.0.0",
|
||||||
|
"rax-text": "^2.2.0",
|
||||||
|
"rax-view": "^2.3.0",
|
||||||
"react": "^18.0.0",
|
"react": "^18.0.0",
|
||||||
"react-dom": "^18.0.0"
|
"react-dom": "^18.0.0"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { createElement } from 'rax';
|
||||||
|
import Image from 'rax-image';
|
||||||
|
|
||||||
|
import styles from './index.module.css';
|
||||||
|
|
||||||
|
export default (props) => {
|
||||||
|
const { uri } = props;
|
||||||
|
const source = { uri };
|
||||||
|
return <Image className={styles.logo} source={source} />;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
.logo {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 180rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
@ -5,4 +5,21 @@
|
||||||
|
|
||||||
.data {
|
.data {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.homeContainer {
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 200rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homeTitle {
|
||||||
|
font-size: 45rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homeInfo {
|
||||||
|
font-size: 36rpx;
|
||||||
|
margin: 8rpx 0;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { createElement, forwardRef, createRef, useRef } from 'rax';
|
||||||
|
import View from 'rax-view';
|
||||||
|
import Text from 'rax-text';
|
||||||
|
|
||||||
|
import styles from './index.module.css';
|
||||||
|
|
||||||
|
import Logo from '@/components/Logo';
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<View className={styles.homeContainer} onAppear={() => { console.log('view appear'); }}>
|
||||||
|
<Logo uri="//gw.alicdn.com/tfs/TB1MRC_cvb2gK0jSZK9XXaEgFXa-1701-1535.png" />
|
||||||
|
<Text className={styles.homeTitle}>Welcome to Your Rax App</Text>
|
||||||
|
<Text className={styles.homeInfo}>More information about Rax</Text>
|
||||||
|
<Text className={styles.homeInfo}>Visit https://rax.js.org</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -45,7 +45,8 @@
|
||||||
"compat"
|
"compat"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@swc/helpers": "^0.3.8"
|
"@swc/helpers": "^0.3.8",
|
||||||
|
"appear-polyfill": "^0.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ice/pkg": "^1.0.0-rc.0",
|
"@ice/pkg": "^1.0.0-rc.0",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,22 @@
|
||||||
import React from 'react';
|
import React, {
|
||||||
|
Attributes,
|
||||||
|
FunctionComponent,
|
||||||
|
ReactElement,
|
||||||
|
ReactNode,
|
||||||
|
RefObject,
|
||||||
|
useEffect, useRef, forwardRef,
|
||||||
|
} from 'react';
|
||||||
|
import { isFunction } from './type';
|
||||||
|
// @ts-ignore
|
||||||
|
import { setupAppear } from 'appear-polyfill';
|
||||||
|
|
||||||
|
let appearSetup = false;
|
||||||
|
function setupAppearOnce() {
|
||||||
|
if (!appearSetup) {
|
||||||
|
setupAppear();
|
||||||
|
appearSetup = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compat createElement for rax export.
|
* Compat createElement for rax export.
|
||||||
|
|
@ -6,9 +24,56 @@ import React from 'react';
|
||||||
* @param type
|
* @param type
|
||||||
* @param props
|
* @param props
|
||||||
* @param children
|
* @param children
|
||||||
* @param others
|
|
||||||
* @returns Element
|
* @returns Element
|
||||||
*/
|
*/
|
||||||
export function createElement(type: any, props: Object, children: any, ...others: any) {
|
export function createElement<P extends {
|
||||||
return React.createElement(type, props, children, ...others);
|
ref: RefObject<any>;
|
||||||
|
children: any; onAppear?: Function;
|
||||||
|
onDisappear?: Function;
|
||||||
|
}>(
|
||||||
|
type: FunctionComponent<P>,
|
||||||
|
props?: Attributes & P | null,
|
||||||
|
...children: ReactNode[]): ReactElement {
|
||||||
|
const { children: propsChildren, onAppear, onDisappear, ...rest } = props;
|
||||||
|
|
||||||
|
rest.ref = props.ref || useRef(null);
|
||||||
|
let element: any = React.createElement(type, rest as Attributes & P | null, propsChildren, ...children);
|
||||||
|
// Polyfill onAppear and onDisappear.
|
||||||
|
if (isFunction(onAppear) || isFunction(onDisappear)) {
|
||||||
|
setupAppearOnce();
|
||||||
|
element = React.createElement(forwardRef(AppearOrDisappear), {
|
||||||
|
onAppear: onAppear,
|
||||||
|
onDisappear: onDisappear,
|
||||||
|
ref: rest.ref,
|
||||||
|
}, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Appear HOC Component.
|
||||||
|
function AppearOrDisappear(props: any, ref: RefObject<EventTarget>) {
|
||||||
|
const { onAppear, onDisappear } = props;
|
||||||
|
|
||||||
|
listen('appear', onAppear);
|
||||||
|
listen('disappear', onDisappear);
|
||||||
|
|
||||||
|
function listen(eventName: string, handler: EventListenerOrEventListenerObject) {
|
||||||
|
if (isFunction(handler) && ref != null) {
|
||||||
|
useEffect(() => {
|
||||||
|
const { current } = ref;
|
||||||
|
if (current != null) {
|
||||||
|
current.addEventListener(eventName, handler);
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
const { current } = ref;
|
||||||
|
if (current) {
|
||||||
|
current.removeEventListener(eventName, handler);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [ref, handler]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return props.children;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ export async function loadRoutesData(
|
||||||
matches.map(async (match) => {
|
matches.map(async (match) => {
|
||||||
const { id } = match.route;
|
const { id } = match.route;
|
||||||
const routeModule = routeModules[id];
|
const routeModule = routeModules[id];
|
||||||
const { getData } = routeModule;
|
const { getData } = routeModule ?? {};
|
||||||
|
|
||||||
if (getData) {
|
if (getData) {
|
||||||
routesData[id] = await getData(requestContext);
|
routesData[id] = await getData(requestContext);
|
||||||
|
|
@ -195,4 +195,4 @@ export function filterMatchesToLoad(prevMatches: RouteMatch[], currentMatches: R
|
||||||
return currentMatches.filter((match, index) => {
|
return currentMatches.filter((match, index) => {
|
||||||
return isNew(match, index) || matchPathChanged(match, index);
|
return isNew(match, index) || matchPathChanged(match, index);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue