feat: add lifecycle
This commit is contained in:
parent
d7101ff5e3
commit
b725b0d98c
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
printWidth: 120, // 一行120字符数,如果超过会进行换行
|
||||||
|
tabWidth: 2, // tab等2个空格
|
||||||
|
useTabs: false, // 用空格缩进行
|
||||||
|
semi: true, // 行尾使用分号
|
||||||
|
singleQuote: true, // 字符串使用单引号
|
||||||
|
quoteProps: 'as-needed', // 仅在需要时在对象属性添加引号
|
||||||
|
jsxSingleQuote: false, // 在JSX中使用双引号
|
||||||
|
trailingComma: 'es5', // 使用尾逗号(对象、数组等)
|
||||||
|
bracketSpacing: true, // 对象的括号间增加空格
|
||||||
|
bracketSameLine: false, // 将多行JSX元素的>放在最后一行的末尾
|
||||||
|
arrowParens: 'avoid', // 在唯一的arrow函数参数周围省略括号
|
||||||
|
vueIndentScriptAndStyle: false, // 不缩进Vue文件中的<script>和<style>标记内的代码
|
||||||
|
endOfLine: 'lf', // 仅限换行(\n)
|
||||||
|
};
|
|
@ -0,0 +1,2 @@
|
||||||
|
## 适配Vue
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"name": "@inula/vue-adapter",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "vue adapter",
|
||||||
|
"main": "./src/index.ts",
|
||||||
|
"scripts": {
|
||||||
|
"test": "vitest --ui"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"openinula": "workspace:*"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@testing-library/user-event": "^12.1.10",
|
||||||
|
"@vitest/ui": "^0.34.5",
|
||||||
|
"jsdom": "^24.0.0",
|
||||||
|
"vitest": "^0.34.5",
|
||||||
|
"@vitejs/plugin-react": "^4.2.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './lifecycle';
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
import { useEffect, useLayoutEffect, useRef } from 'openinula';
|
||||||
|
|
||||||
|
// 用于存储组件是否已挂载的状态
|
||||||
|
const useIsMounted = () => {
|
||||||
|
const isMounted = useRef(false);
|
||||||
|
useEffect(() => {
|
||||||
|
isMounted.current = true;
|
||||||
|
return () => {
|
||||||
|
isMounted.current = false;
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
return isMounted;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const onBeforeMount = (fn: () => void) => {
|
||||||
|
const isMounted = useIsMounted();
|
||||||
|
if (!isMounted) {
|
||||||
|
fn?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function onMounted(fn: () => void) {
|
||||||
|
useEffect(() => {
|
||||||
|
fn?.();
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function onBeforeUpdated(fn: () => void) {
|
||||||
|
useEffect(() => {
|
||||||
|
fn?.();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function onUpdated(fn: () => void) {
|
||||||
|
useEffect(() => {
|
||||||
|
fn?.();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export const onBeforeUnmount = (fn: () => void) => {
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
return () => {
|
||||||
|
fn?.();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function onUnmounted(fn: () => void) {
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
fn?.();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-nocheck For the compiled code.
|
||||||
|
|
||||||
|
import { describe, it, vi, expect } from 'vitest';
|
||||||
|
import { render, act, useState } from 'openinula';
|
||||||
|
import { onBeforeUnmount } from '../src';
|
||||||
|
|
||||||
|
describe('lifecycle', () => {
|
||||||
|
it('should call the onBeforeUnmount before the component unmounts', () => {
|
||||||
|
const fn = vi.fn(() => {
|
||||||
|
// 断言在组件卸载之前,子组件仍然存在于 DOM 中
|
||||||
|
expect(document.querySelector('span')).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
const Comp = () => {
|
||||||
|
const [toggle, setToggle] = useState(true);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{toggle ? <Child /> : null}
|
||||||
|
<button onClick={() => setToggle(false)}>Unmount</button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Child = () => {
|
||||||
|
onBeforeUnmount(fn);
|
||||||
|
return <span />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const container = document.createElement('div');
|
||||||
|
document.body.appendChild(container);
|
||||||
|
render(<Comp />, container);
|
||||||
|
|
||||||
|
expect(document.querySelector('span')).not.toBeNull();
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
container.querySelector('button').dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(fn).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
expect(document.querySelector('span')).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"lib": ["ESNext", "DOM"],
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
},
|
||||||
|
"ts-node": {
|
||||||
|
"esm": true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
|
||||||
|
let alias = {
|
||||||
|
react: 'openinula', // 新增
|
||||||
|
'react-dom': 'openinula', // 新增
|
||||||
|
'react/jsx-dev-runtime': 'openinula/jsx-dev-runtime',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
plugins: [react()],
|
||||||
|
test: {
|
||||||
|
environment: 'jsdom',
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias,
|
||||||
|
},
|
||||||
|
};
|
|
@ -13,7 +13,8 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ref, reactive, watchEffect, computed } from 'openinula';
|
import { vueReactive } from '../../../src';
|
||||||
|
const { ref, reactive, watchEffect, computed } = vueReactive;
|
||||||
|
|
||||||
describe('test computed', () => {
|
describe('test computed', () => {
|
||||||
it('should correctly update the computed value', () => {
|
it('should correctly update the computed value', () => {
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { reactive, isReactive, toRaw, ref, isRef, computed, watchEffect } from 'openinula';
|
import { vueReactive } from '../../../src';
|
||||||
|
const { reactive, isReactive, toRaw, ref, isRef, computed, watchEffect } = vueReactive;
|
||||||
|
|
||||||
describe('test reactive', () => {
|
describe('test reactive', () => {
|
||||||
it('should validate the reactivity of an object', () => {
|
it('should validate the reactivity of an object', () => {
|
||||||
|
|
|
@ -13,18 +13,9 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import { vueReactive, RefType } from '../../../src';
|
||||||
ref,
|
|
||||||
isRef,
|
const { ref, isRef, isReactive, reactive, watchEffect, unref, shallowRef, isShallow, computed } = vueReactive;
|
||||||
isReactive,
|
|
||||||
reactive,
|
|
||||||
watchEffect,
|
|
||||||
unref,
|
|
||||||
shallowRef,
|
|
||||||
isShallow,
|
|
||||||
RefType,
|
|
||||||
computed,
|
|
||||||
} from 'openinula';
|
|
||||||
|
|
||||||
describe('test ref', () => {
|
describe('test ref', () => {
|
||||||
it('should validate the value holding capability', () => {
|
it('should validate the value holding capability', () => {
|
||||||
|
|
|
@ -13,10 +13,12 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { render, act, useReactive, useReference, useComputed, useWatch } from '../../../src';
|
import { render, act, vueReactive, RefType, unmountComponentAtNode } from '../../../src';
|
||||||
import { Text, triggerClickEvent } from '../../jest/commonComponents';
|
import { Text, triggerClickEvent } from '../../jest/commonComponents';
|
||||||
import * as Inula from '../../../src';
|
import * as Inula from '../../../src';
|
||||||
|
|
||||||
|
const { useReactive, useReference, useComputed, useWatch } = vueReactive;
|
||||||
|
|
||||||
describe('test reactive in FunctionComponent', () => {
|
describe('test reactive in FunctionComponent', () => {
|
||||||
const { unmountComponentAtNode } = Inula;
|
const { unmountComponentAtNode } = Inula;
|
||||||
let container: HTMLElement | null = null;
|
let container: HTMLElement | null = null;
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ref, reactive, watch, computed } from '../../../src';
|
import { vueReactive } from '../../../src';
|
||||||
|
|
||||||
|
const { ref, reactive, watch, computed } = vueReactive;
|
||||||
|
|
||||||
describe('test watch', () => {
|
describe('test watch', () => {
|
||||||
it('should watch effect', async () => {
|
it('should watch effect', async () => {
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { reactive, toRaw, watchEffect } from 'openinula';
|
import { vueReactive } from '../../../src';
|
||||||
|
|
||||||
|
const { reactive, toRaw, watchEffect } = vueReactive;
|
||||||
|
|
||||||
function stop(stopHandle: () => void) {
|
function stop(stopHandle: () => void) {
|
||||||
stopHandle();
|
stopHandle();
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
* See the Mulan PSL v2 for more details.
|
* See the Mulan PSL v2 for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createStore, watch, watchEffect } from '../../../src/index';
|
import { createStore, watch, vueReactive } from '../../../src/index';
|
||||||
|
const { watchEffect } = vueReactive;
|
||||||
|
|
||||||
describe('watch', () => {
|
describe('watch', () => {
|
||||||
it('should watch primitive state variable', async () => {
|
it('should watch primitive state variable', async () => {
|
||||||
|
|
|
@ -75,6 +75,24 @@ import {
|
||||||
import { syncUpdates as flushSync } from './renderer/TreeBuilder';
|
import { syncUpdates as flushSync } from './renderer/TreeBuilder';
|
||||||
import { isReactive, isShallow } from './inulax/CommonUtils';
|
import { isReactive, isShallow } from './inulax/CommonUtils';
|
||||||
|
|
||||||
|
const vueReactive = {
|
||||||
|
ref,
|
||||||
|
useReference,
|
||||||
|
isRef,
|
||||||
|
unref,
|
||||||
|
shallowRef,
|
||||||
|
reactive,
|
||||||
|
useReactive,
|
||||||
|
isReactive,
|
||||||
|
isShallow,
|
||||||
|
computed,
|
||||||
|
useComputed,
|
||||||
|
watchEffect,
|
||||||
|
watch,
|
||||||
|
useWatch,
|
||||||
|
toRaw,
|
||||||
|
};
|
||||||
|
|
||||||
const Inula = {
|
const Inula = {
|
||||||
Children,
|
Children,
|
||||||
createRef,
|
createRef,
|
||||||
|
@ -126,20 +144,7 @@ const Inula = {
|
||||||
StrictMode,
|
StrictMode,
|
||||||
Suspense,
|
Suspense,
|
||||||
// vue reactive api
|
// vue reactive api
|
||||||
ref,
|
vueReactive,
|
||||||
useReference,
|
|
||||||
isRef,
|
|
||||||
unref,
|
|
||||||
shallowRef,
|
|
||||||
reactive,
|
|
||||||
useReactive,
|
|
||||||
isReactive,
|
|
||||||
isShallow,
|
|
||||||
computed,
|
|
||||||
useComputed,
|
|
||||||
watchEffect,
|
|
||||||
useWatch,
|
|
||||||
toRaw,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const version = '';
|
export const version = '';
|
||||||
|
@ -197,20 +202,7 @@ export {
|
||||||
StrictMode,
|
StrictMode,
|
||||||
Suspense,
|
Suspense,
|
||||||
// vue reactive api
|
// vue reactive api
|
||||||
ref,
|
vueReactive,
|
||||||
useReference,
|
|
||||||
isRef,
|
|
||||||
unref,
|
|
||||||
shallowRef,
|
|
||||||
reactive,
|
|
||||||
useReactive,
|
|
||||||
isReactive,
|
|
||||||
isShallow,
|
|
||||||
computed,
|
|
||||||
useComputed,
|
|
||||||
watchEffect,
|
|
||||||
useWatch,
|
|
||||||
toRaw,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export * from './types';
|
export * from './types';
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
|
||||||
|
*
|
||||||
|
* openInula is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
*
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './reactive/Reactive';
|
||||||
|
export * from './reactive/Reactive';
|
||||||
|
export * from './reactive/Reactive';
|
Loading…
Reference in New Issue