annil 1.7.8 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/api/DefineComponent/normalizeOptions/__throttleDebounce__FieldCheck.d.ts +3 -0
- package/dist/api/DefineComponent/normalizeOptions/__throttleDebounce__FieldCheck.js +26 -0
- package/dist/api/DefineComponent/normalizeOptions/__throttleDebounce__FieldCheck.js.map +1 -0
- package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/computedUpdater.js +4 -4
- package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/computedUpdater.js.map +1 -1
- package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/data-tracer.d.ts +1 -1
- package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/data-tracer.js +7 -12
- package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/data-tracer.js.map +1 -1
- package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/getPropertiesValue.d.ts +1 -1
- package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/getPropertiesValue.js +1 -2
- package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/getPropertiesValue.js.map +1 -1
- package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/initComputedAndGetCache.js +2 -2
- package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/initComputedAndGetCache.js.map +1 -1
- package/dist/api/DefineComponent/normalizeOptions/customEventsHandle.d.ts +1 -1
- package/dist/api/DefineComponent/normalizeOptions/customEventsHandle.js +17 -1
- package/dist/api/DefineComponent/normalizeOptions/customEventsHandle.js.map +1 -1
- package/dist/api/DefineComponent/normalizeOptions/index.d.ts +2 -0
- package/dist/api/DefineComponent/normalizeOptions/index.js +8 -1
- package/dist/api/DefineComponent/normalizeOptions/index.js.map +1 -1
- package/dist/api/DefineComponent/normalizeOptions/internalFieldProtection.js +1 -1
- package/dist/api/DefineComponent/normalizeOptions/internalFieldProtection.js.map +1 -1
- package/dist/api/DefineComponent/normalizeOptions/rootComponentOptionHandle.js +2 -1
- package/dist/api/DefineComponent/normalizeOptions/rootComponentOptionHandle.js.map +1 -1
- package/dist/api/DefineComponent/normalizeOptions/sameFuncOptionsHandle.js +2 -2
- package/dist/api/DefineComponent/normalizeOptions/sameFuncOptionsHandle.js.map +1 -1
- package/dist/api/RootComponent/CustomEvents/CustomEventConstraint.d.ts +22 -0
- package/dist/api/RootComponent/CustomEvents/GetCustomEventDoc.d.ts +3 -2
- package/dist/behaviors/BbeforeCreated.js +1 -1
- package/dist/behaviors/BbeforeCreated.js.map +1 -1
- package/dist/behaviors/BthrottleDebounce.d.ts +1 -0
- package/dist/behaviors/BthrottleDebounce.js +27 -0
- package/dist/behaviors/BthrottleDebounce.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/_utils.d.ts +7 -0
- package/dist/utils/_utils.js +8 -0
- package/dist/utils/_utils.js.map +1 -0
- package/dist/utils/debounce.d.ts +8 -0
- package/dist/utils/debounce.js +18 -0
- package/dist/utils/debounce.js.map +1 -0
- package/dist/utils/deepEqual.d.ts +1 -7
- package/dist/utils/deepEqual.js +18 -58
- package/dist/utils/deepEqual.js.map +1 -1
- package/dist/utils/throttle.d.ts +10 -0
- package/dist/utils/throttle.js +18 -0
- package/dist/utils/throttle.js.map +1 -0
- package/package.json +5 -8
- package/src/api/DefineComponent/normalizeOptions/__throttleDebounce__FieldCheck.ts +27 -0
- package/src/api/DefineComponent/normalizeOptions/computedWatchHandle/computedUpdater.ts +4 -5
- package/src/api/DefineComponent/normalizeOptions/computedWatchHandle/data-tracer.ts +7 -13
- package/src/api/DefineComponent/normalizeOptions/computedWatchHandle/getPropertiesValue.ts +2 -4
- package/src/api/DefineComponent/normalizeOptions/computedWatchHandle/initComputedAndGetCache.ts +2 -2
- package/src/api/DefineComponent/normalizeOptions/customEventsHandle.ts +24 -3
- package/src/api/DefineComponent/normalizeOptions/index.ts +11 -2
- package/src/api/DefineComponent/normalizeOptions/internalFieldProtection.ts +1 -1
- package/src/api/DefineComponent/normalizeOptions/rootComponentOptionHandle.ts +2 -1
- package/src/api/DefineComponent/normalizeOptions/sameFuncOptionsHandle.ts +2 -2
- package/src/api/RootComponent/Computed/test/error.test.ts +13 -0
- package/src/api/RootComponent/CustomEvents/CustomEventConstraint.ts +22 -0
- package/src/api/RootComponent/CustomEvents/GetCustomEventDoc.ts +4 -2
- package/src/behaviors/BbeforeCreated.ts +1 -1
- package/src/behaviors/BthrottleDebounce.ts +28 -0
- package/src/index.ts +2 -0
- package/src/utils/_utils.ts +8 -0
- package/src/utils/debounce.ts +19 -0
- package/src/utils/deepEqual.ts +19 -65
- package/src/utils/throttle.ts +23 -0
package/dist/utils/deepEqual.js
CHANGED
|
@@ -1,69 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// 非null的对象类型
|
|
2
|
+
function isNonNullObject(value) {
|
|
3
|
+
return value !== null && typeof value === "object";
|
|
3
4
|
}
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// 定义一个辅助函数,用于判断两个函数的代码是否相同
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
10
|
-
function isSameCode(a, b) {
|
|
11
|
-
// 去除空格比较函数字符串
|
|
12
|
-
return a.toString().split(" ").join("") === b.toString().split(" ").join("");
|
|
13
|
-
}
|
|
14
|
-
// 定义一个辅助函数,用于判断两个日期的时间戳是否相同
|
|
15
|
-
function isSameTime(a, b) {
|
|
16
|
-
return a.getTime() === b.getTime();
|
|
17
|
-
}
|
|
18
|
-
// 定义一个辅助函数,用于判断两个正则表达式的模式和标志是否相同
|
|
19
|
-
function isSamePattern(a, b) {
|
|
20
|
-
return a.source === b.source && a.flags === b.flags;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* 深度判断两个值是否相等,有一个值为非对象类型即使用Object.is判断。
|
|
24
|
-
* 不支持原型上的属性
|
|
25
|
-
* 两个函数使用toString()比较
|
|
26
|
-
* 支持Date,RegExp
|
|
27
|
-
*/
|
|
28
|
-
export function deepEqual(a, b) {
|
|
29
|
-
// 如果两个值是原始类型或null,直接用Object.is比较
|
|
30
|
-
if (a === null || b === null || typeof a !== "object" || typeof b !== "object") {
|
|
31
|
-
if (typeof a !== "function" || typeof b !== "function") {
|
|
32
|
-
return Object.is(a, b);
|
|
33
|
-
}
|
|
5
|
+
export function deepEqual(value1, value2) {
|
|
6
|
+
// 2个非对象类型相等或同引用对象的情况。
|
|
7
|
+
if (Object.is(value1, value2)) {
|
|
8
|
+
return true;
|
|
34
9
|
}
|
|
35
|
-
//
|
|
36
|
-
if (!
|
|
10
|
+
// 有一个不是非空对象,返回false。
|
|
11
|
+
if (!isNonNullObject(value1) || !isNonNullObject(value2)) {
|
|
37
12
|
return false;
|
|
38
13
|
}
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return isSameTime(a, b);
|
|
47
|
-
}
|
|
48
|
-
// // 如果两个值是正则表达式类型,再判断它们的模式和标志是否相同
|
|
49
|
-
if (a instanceof RegExp) {
|
|
50
|
-
return isSamePattern(a, b);
|
|
14
|
+
// 到此,2个都是对象类型。
|
|
15
|
+
const _value1 = value1;
|
|
16
|
+
const _value2 = value2;
|
|
17
|
+
const value1Keys = Object.keys(_value1);
|
|
18
|
+
const value2Keys = Object.keys(_value2);
|
|
19
|
+
if (value1Keys.length !== value2Keys.length) {
|
|
20
|
+
return false;
|
|
51
21
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const keysB = Object.keys(b);
|
|
55
|
-
for (const key of keysA) {
|
|
56
|
-
if (keysB.includes(key)) {
|
|
57
|
-
// @ts-ignore
|
|
58
|
-
if (!deepEqual(a[key], b[key])) {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
22
|
+
for (const key of value1Keys) {
|
|
23
|
+
if (!value2Keys.includes(key) || !deepEqual(_value1[key], _value2[key])) {
|
|
63
24
|
return false;
|
|
64
25
|
}
|
|
65
26
|
}
|
|
66
|
-
// 如果以上的条件都满足,说明两个值是深度相等的
|
|
67
27
|
return true;
|
|
68
28
|
}
|
|
69
29
|
//# sourceMappingURL=deepEqual.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deepEqual.js","sourceRoot":"","sources":["../../src/utils/deepEqual.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deepEqual.js","sourceRoot":"","sources":["../../src/utils/deepEqual.ts"],"names":[],"mappings":"AACA,aAAa;AACb,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAe,EAAE,MAAe;IACxD,sBAAsB;IACtB,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,qBAAqB;IACrB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,eAAe;IACf,MAAM,OAAO,GAAG,MAAqB,CAAC;IACtC,MAAM,OAAO,GAAG,MAAqB,CAAC;IACtC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAExC,IAAI,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACxE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type Callback = (...args: any[]) => any;
|
|
2
|
+
/**
|
|
3
|
+
* 节流函数
|
|
4
|
+
* 规定时间内只触发第一次 例如点击按钮
|
|
5
|
+
* @param callback 回调函数
|
|
6
|
+
* @param interval 单位毫秒
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export declare function throttle<F extends Callback>(callback: F, interval?: number): (...args: Parameters<F>) => void;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 节流函数
|
|
3
|
+
* 规定时间内只触发第一次 例如点击按钮
|
|
4
|
+
* @param callback 回调函数
|
|
5
|
+
* @param interval 单位毫秒
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
export function throttle(callback, interval = 200) {
|
|
9
|
+
let lastCall = 0;
|
|
10
|
+
return function (...args) {
|
|
11
|
+
const now = Date.now();
|
|
12
|
+
if (now - lastCall >= interval) {
|
|
13
|
+
lastCall = now;
|
|
14
|
+
callback(...args);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=throttle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throttle.js","sourceRoot":"","sources":["../../src/utils/throttle.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAqB,QAAW,EAAE,QAAQ,GAAG,GAAG;IACtE,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,OAAO,UAAS,GAAG,IAAmB;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,IAAI,GAAG,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC;YAC/B,QAAQ,GAAG,GAAG,CAAC;YAEf,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "annil",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"description": "微信小程序(原生开发)插件",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -17,24 +17,21 @@
|
|
|
17
17
|
"tsc": "tsc --watch",
|
|
18
18
|
"test": "jest --watch",
|
|
19
19
|
"build": "tsc -p tsconfig.build.json",
|
|
20
|
-
"check": "eslint . --fix --max-warnings 0 && (dprint check || (dprint fmt && exit 1))"
|
|
20
|
+
"check": "eslint . --fix --max-warnings 0 && (dprint check || (dprint fmt && exit 1)) "
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@commitlint/config-conventional": "^17.6.5",
|
|
24
|
-
"@eslint/js": "^9.8.0",
|
|
25
|
-
"@types/eslint__js": "^8.42.3",
|
|
26
24
|
"@types/jest": "^29.5.5",
|
|
27
25
|
"commitlint": "^17.6.5",
|
|
28
|
-
"eslint": "^9.
|
|
26
|
+
"eslint": "^9.10.0",
|
|
29
27
|
"husky": "^8.0.3",
|
|
30
28
|
"jest": "^29.7.0",
|
|
31
29
|
"jest-environment-jsdom": "^29.7.0",
|
|
32
30
|
"miniprogram-simulate": "^1.6.1",
|
|
33
31
|
"mobx": "^6.9.0",
|
|
34
|
-
"prettier": "^2.8.8",
|
|
35
32
|
"ts-jest": "^29.1.1",
|
|
36
33
|
"typescript": "^5.5.4",
|
|
37
|
-
"typescript-eslint": "^8.
|
|
34
|
+
"typescript-eslint": "^8.4.0"
|
|
38
35
|
},
|
|
39
36
|
"files": [
|
|
40
37
|
"LICENSE",
|
|
@@ -53,6 +50,6 @@
|
|
|
53
50
|
"license": "MIT",
|
|
54
51
|
"peerDependencies": {
|
|
55
52
|
"hry-types": "^0.18.1",
|
|
56
|
-
"miniprogram-api-typings": "^3.12.
|
|
53
|
+
"miniprogram-api-typings": "^3.12.3"
|
|
57
54
|
}
|
|
58
55
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { RootComponentTrueOptions } from "../../RootComponent";
|
|
2
|
+
import type { SubComponentType } from "../../SubComponent/SubComponentType";
|
|
3
|
+
|
|
4
|
+
export function __throttleDebounce__FieldCheck(config: RootComponentTrueOptions | SubComponentType[]) {
|
|
5
|
+
if (Array.isArray(config)) {
|
|
6
|
+
for (const subComponent of config) {
|
|
7
|
+
__throttleDebounce__FieldCheck(subComponent);
|
|
8
|
+
}
|
|
9
|
+
} else {
|
|
10
|
+
const dataKeys: string[] = [];
|
|
11
|
+
if (config.data) {
|
|
12
|
+
dataKeys.push(...Object.keys(config.data));
|
|
13
|
+
}
|
|
14
|
+
if (config.computed) {
|
|
15
|
+
dataKeys.push(...Object.keys(config.computed));
|
|
16
|
+
}
|
|
17
|
+
if (config.properties) {
|
|
18
|
+
dataKeys.push(...Object.keys(config.properties));
|
|
19
|
+
}
|
|
20
|
+
if (config.store) {
|
|
21
|
+
dataKeys.push(...Object.keys(config.store));
|
|
22
|
+
}
|
|
23
|
+
if (dataKeys.includes("__throttleDebounce__")) {
|
|
24
|
+
throw Error(`__throttleDebounce__字段已被内部字段占用`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { deepEqual } from "../../../../utils/deepEqual";
|
|
2
2
|
import type { Instance } from "../../../RootComponent/Instance/RootComponentInstance";
|
|
3
|
-
import { deepProxy,
|
|
3
|
+
import { deepProxy, getOriginalValue } from "./data-tracer";
|
|
4
4
|
import { removeSubDependences } from "./dependencesOptimize";
|
|
5
5
|
import { getPathsValue } from "./getPathsValue";
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ export function computedUpdater(this: Instance, isUpdated = false): boolean {
|
|
|
14
14
|
// getPathsValue返回的是数组
|
|
15
15
|
const curVal = getPathsValue(this.data, dep.paths.join("."))[0];
|
|
16
16
|
|
|
17
|
-
//
|
|
17
|
+
// 检查依赖是否改变了
|
|
18
18
|
if (!deepEqual(curVal, dep.val)) {
|
|
19
19
|
changed = true;
|
|
20
20
|
|
|
@@ -24,10 +24,9 @@ export function computedUpdater(this: Instance, isUpdated = false): boolean {
|
|
|
24
24
|
if (changed) {
|
|
25
25
|
const newDependences: ComputedDependence[] = [];
|
|
26
26
|
const newValue = itemCache.method.call({ data: deepProxy(this.data, newDependences) });
|
|
27
|
-
|
|
28
|
-
// 更新值不会立即再次进入**函数,而是当前**函数运行完毕后触发**函数,
|
|
27
|
+
// 更新值不会立即再次进入**函数,而是当前**函数运行完毕后触发**函数,\
|
|
29
28
|
this.setData({
|
|
30
|
-
[key]:
|
|
29
|
+
[key]: getOriginalValue(newValue),
|
|
31
30
|
});
|
|
32
31
|
|
|
33
32
|
isUpdated = true;
|
|
@@ -13,9 +13,9 @@ export function deepProxy(
|
|
|
13
13
|
}
|
|
14
14
|
const val = target[prop];
|
|
15
15
|
|
|
16
|
-
//
|
|
16
|
+
// 自身没有但原型链上有的属性不收集依赖,比如数组上的方法 slice map forEach
|
|
17
17
|
if (prop in target && !Object.prototype.hasOwnProperty.call(target, prop)) {
|
|
18
|
-
return typeof val === "function" ? val.bind(target) : val;
|
|
18
|
+
return typeof val === "function" ? val.bind(target) : val; // : val 覆盖测试不到.
|
|
19
19
|
}
|
|
20
20
|
removePreviousDependence(dependences, basePath);
|
|
21
21
|
|
|
@@ -25,7 +25,7 @@ export function deepProxy(
|
|
|
25
25
|
|
|
26
26
|
// 非对象不代理
|
|
27
27
|
if (typeof val !== "object" || val === null) return val;
|
|
28
|
-
|
|
28
|
+
// console.log(val, typeof val);
|
|
29
29
|
return deepProxy(val, dependences, curPath);
|
|
30
30
|
},
|
|
31
31
|
set(_target: object, prop: string) {
|
|
@@ -36,17 +36,11 @@ export function deepProxy(
|
|
|
36
36
|
return new Proxy(data, handler);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
// 如果是代理对象可以从__original__中获取原始值,否则返回自身
|
|
40
|
+
export function getOriginalValue(value: { __original__?: unknown }): unknown {
|
|
41
|
+
if (typeof value !== "object" || value === null || value.__original__ === undefined) {
|
|
41
42
|
return value;
|
|
42
43
|
}
|
|
43
|
-
if (value.__original__) return value.__original__;
|
|
44
|
-
|
|
45
|
-
const ret = Array.isArray(value) ? [] : {};
|
|
46
|
-
for (const key in value) {
|
|
47
|
-
// @ts-ignore 隐式索引
|
|
48
|
-
ret[key] = getProxyOriginalValue(value[key]);
|
|
49
|
-
}
|
|
50
44
|
|
|
51
|
-
return
|
|
45
|
+
return value.__original__;
|
|
52
46
|
}
|
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
} from "../../../RootComponent/Properties/PropertiesConstraint";
|
|
7
7
|
|
|
8
8
|
type PropertiesDefaultValue = "" | 0 | [] | null | false;
|
|
9
|
-
|
|
9
|
+
/* istanbul ignore next */
|
|
10
10
|
function getRequiredSingleValue(
|
|
11
11
|
PropType: RequiredSingle,
|
|
12
12
|
): PropertiesDefaultValue {
|
|
@@ -34,12 +34,10 @@ function IsRequiredSingle(config: PropertiesTypes): config is RequiredSingle {
|
|
|
34
34
|
function IsRequiredUnion(config: PropertiesTypes): config is RequiredUnion {
|
|
35
35
|
return !Reflect.has(config, "value");
|
|
36
36
|
}
|
|
37
|
-
export function getPropertiesValue(propertiesOpt: PropertiesConstraint
|
|
38
|
-
if (propertiesOpt === undefined) return;
|
|
37
|
+
export function getPropertiesValue(propertiesOpt: PropertiesConstraint): object {
|
|
39
38
|
const result = {};
|
|
40
39
|
for (const key in propertiesOpt) {
|
|
41
40
|
const config = propertiesOpt[key];
|
|
42
|
-
|
|
43
41
|
if (IsRequiredSingle(config)) {
|
|
44
42
|
// @ts-ignore 隐式索引
|
|
45
43
|
result[key] = getRequiredSingleValue(config);
|
package/src/api/DefineComponent/normalizeOptions/computedWatchHandle/initComputedAndGetCache.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Func } from "hry-types/src/Misc/Func";
|
|
|
2
2
|
import type { FinalOptionsOfComponent } from "..";
|
|
3
3
|
|
|
4
4
|
import type { ComputedDependence } from "./computedUpdater";
|
|
5
|
-
import { deepProxy,
|
|
5
|
+
import { deepProxy, getOriginalValue } from "./data-tracer";
|
|
6
6
|
import { removeSubDependences } from "./dependencesOptimize";
|
|
7
7
|
|
|
8
8
|
type ItemCache = {
|
|
@@ -56,7 +56,7 @@ export function initComputedAndGetCache(
|
|
|
56
56
|
|
|
57
57
|
// 验证依赖是否有效
|
|
58
58
|
if (isValidDependences(dependences, uninitedkeys)) {
|
|
59
|
-
initValue =
|
|
59
|
+
initValue = getOriginalValue(initValue);
|
|
60
60
|
|
|
61
61
|
// 把计算属性初始值加入到options.data中
|
|
62
62
|
options.data[key] = initValue;
|
|
@@ -4,7 +4,23 @@ import type {
|
|
|
4
4
|
FullCustomEvents,
|
|
5
5
|
} from "../../RootComponent/CustomEvents/CustomEventConstraint";
|
|
6
6
|
import type { Instance } from "../../RootComponent/Instance/RootComponentInstance";
|
|
7
|
-
import type { FinalOptionsOfComponent } from ".";
|
|
7
|
+
import type { FinalOptionsOfComponent, ThrottleDebounce } from ".";
|
|
8
|
+
function getThrottleDebounceConfig(
|
|
9
|
+
methodsName: string,
|
|
10
|
+
customEventOptions: FullCustomEvents,
|
|
11
|
+
__throttleDebounce__: ThrottleDebounce,
|
|
12
|
+
) {
|
|
13
|
+
const { debounce, throttle } = customEventOptions;
|
|
14
|
+
|
|
15
|
+
if (debounce) {
|
|
16
|
+
__throttleDebounce__.debounce ||= {};
|
|
17
|
+
__throttleDebounce__.debounce[methodsName] = debounce;
|
|
18
|
+
} else if (throttle) {
|
|
19
|
+
__throttleDebounce__.throttle ||= {};
|
|
20
|
+
__throttleDebounce__.throttle[methodsName] = throttle;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
8
24
|
// 类型守卫
|
|
9
25
|
function IsFullCustomEvents(
|
|
10
26
|
customEventOptions: CustomEvents,
|
|
@@ -15,16 +31,21 @@ function IsFullCustomEvents(
|
|
|
15
31
|
* 把customEvents字段配置变成函数放入到componentOptions.methods中
|
|
16
32
|
*/
|
|
17
33
|
export function customEventsHandle(
|
|
18
|
-
|
|
34
|
+
finalOptions: FinalOptionsOfComponent,
|
|
19
35
|
customEventsConfig: CustomEventConstraint,
|
|
20
36
|
) {
|
|
37
|
+
const methods = finalOptions.methods;
|
|
38
|
+
const data = finalOptions.data;
|
|
39
|
+
|
|
21
40
|
for (const key in customEventsConfig) {
|
|
22
41
|
const customEventOptions = customEventsConfig[key];
|
|
23
|
-
|
|
24
42
|
if (IsFullCustomEvents(customEventOptions)) {
|
|
25
43
|
methods[key] = function(this: Instance, detail: unknown) {
|
|
26
44
|
this.triggerEvent(key, detail, customEventOptions.options);
|
|
27
45
|
};
|
|
46
|
+
data.__throttleDebounce__ ||= {};
|
|
47
|
+
// 全配置允许设置防抖和节流,在这里保留配置到data.__throttleDebounce__中,以便后续使用
|
|
48
|
+
getThrottleDebounceConfig(key, customEventOptions, data.__throttleDebounce__);
|
|
28
49
|
} else {
|
|
29
50
|
methods[key] = function(this: Instance, detail: unknown) {
|
|
30
51
|
this.triggerEvent(key, detail);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Func } from "hry-types/src/Misc/_api";
|
|
2
2
|
import { BBeforeCreate } from "../../../behaviors/BbeforeCreated";
|
|
3
3
|
import { BStore } from "../../../behaviors/BStore";
|
|
4
|
+
import { BthrottleDebounce } from "../../../behaviors/BthrottleDebounce";
|
|
4
5
|
import { isEmptyObject } from "../../../utils/isEmptyObject";
|
|
5
6
|
import { instanceConfig } from "../../InstanceInject/instanceConfig";
|
|
6
7
|
import type { ComputedConstraint } from "../../RootComponent/Computed/ComputedConstraint";
|
|
@@ -11,6 +12,7 @@ import type { PageLifetimesOption } from "../../RootComponent/PageLifetimes/Page
|
|
|
11
12
|
import type { PropertiesConstraint } from "../../RootComponent/Properties/PropertiesConstraint";
|
|
12
13
|
import type { StoreConstraint } from "../../RootComponent/Store/StoreConstraint";
|
|
13
14
|
import type { DefineComponentOption } from "..";
|
|
15
|
+
import { __throttleDebounce__FieldCheck } from "./__throttleDebounce__FieldCheck";
|
|
14
16
|
import { computedWatchHandle } from "./computedWatchHandle";
|
|
15
17
|
import type { ComputedCache } from "./computedWatchHandle/initComputedAndGetCache";
|
|
16
18
|
import { hijack } from "./hijackHandle";
|
|
@@ -25,12 +27,13 @@ import { sameFuncOptionsHandle } from "./sameFuncOptionsHandle";
|
|
|
25
27
|
import { subComponentsOptionHandle } from "./subComponentsOptionHandle";
|
|
26
28
|
|
|
27
29
|
export type WatchOldValue = Record<string, unknown[]>;
|
|
28
|
-
|
|
30
|
+
export type ThrottleDebounce = Partial<Record<"throttle" | "debounce", Record<string, number>>>;
|
|
29
31
|
export type OptionsInnerFields = {
|
|
30
32
|
data: {
|
|
31
33
|
__computedCache__?: ComputedCache;
|
|
32
34
|
__storeConfig__?: StoreConstraint;
|
|
33
35
|
__watchOldValue__?: WatchOldValue;
|
|
36
|
+
__throttleDebounce__?: ThrottleDebounce;
|
|
34
37
|
};
|
|
35
38
|
methods: {
|
|
36
39
|
disposer?: Record<string, Func>;
|
|
@@ -78,7 +81,7 @@ export function normalizeOptions(
|
|
|
78
81
|
data: {},
|
|
79
82
|
methods: {},
|
|
80
83
|
// 加入BStore,处理store字段的behavior
|
|
81
|
-
behaviors: [BStore],
|
|
84
|
+
behaviors: [BStore, BthrottleDebounce],
|
|
82
85
|
externalClasses: [],
|
|
83
86
|
pageLifetimes: {},
|
|
84
87
|
isPage: false,
|
|
@@ -99,10 +102,15 @@ export function normalizeOptions(
|
|
|
99
102
|
watch: {},
|
|
100
103
|
observers: {},
|
|
101
104
|
};
|
|
105
|
+
|
|
102
106
|
if (rootComponentOption && !isEmptyObject(rootComponentOption)) {
|
|
107
|
+
// 验证配置中是否有内部字段__throttleDebounce__,有则报错,因为在rootComponentOptionHandle中会加入__throttleDebounce__字段到data中
|
|
108
|
+
__throttleDebounce__FieldCheck(rootComponentOption);
|
|
103
109
|
rootComponentOptionHandle(finalOptionsForComponent, sameFuncOptions, rootComponentOption);
|
|
104
110
|
}
|
|
105
111
|
if (subComponentsOption && !isEmptyObject(subComponentsOption)) {
|
|
112
|
+
// 验证配置中是否有内部字段__throttleDebounce__,有则报错,因为在rootComponentOptionHandle中会加入__throttleDebounce__字段到data中
|
|
113
|
+
__throttleDebounce__FieldCheck(subComponentsOption);
|
|
106
114
|
subComponentsOptionHandle(finalOptionsForComponent, subComponentsOption, sameFuncOptions);
|
|
107
115
|
}
|
|
108
116
|
sameFuncOptionsHandle(finalOptionsForComponent, rootComponentOption?.isPage, sameFuncOptions);
|
|
@@ -134,6 +142,7 @@ export function normalizeOptions(
|
|
|
134
142
|
|
|
135
143
|
// 处理computed和watch配置
|
|
136
144
|
computedWatchHandle(finalOptionsForComponent);
|
|
145
|
+
// 在rootComponentOptionHandle中保留了防抖节流配置,这里处理后,删除data.__throttleDebounce__字段
|
|
137
146
|
|
|
138
147
|
// BBeforeCreate在最后面,让BeforeCreate生命周期运行在最终建立组件时。
|
|
139
148
|
finalOptionsForComponent.behaviors.push(BBeforeCreate);
|
|
@@ -3,7 +3,7 @@ import type { FinalOptionsOfComponent } from ".";
|
|
|
3
3
|
// 内部字段
|
|
4
4
|
const internalFiled = {
|
|
5
5
|
methods: ["disposer", "__computedUpdater__"],
|
|
6
|
-
data: ["__computedCache__", "__storeConfig__", "__watchOldValue__"],
|
|
6
|
+
data: ["__computedCache__", "__storeConfig__", "__watchOldValue__"], // "__throttleDebounce__" 放在之前的位置验证
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -15,7 +15,8 @@ export function rootComponentOptionHandle(
|
|
|
15
15
|
funcOptions: SameFuncOptions,
|
|
16
16
|
rootComponentOptions: RootComponentTrueOptions,
|
|
17
17
|
) {
|
|
18
|
-
|
|
18
|
+
// 自定义事件处理时,如果配置了防抖节流,则需要在data.__throttleDebounce__保留配置信息,以便后续使用
|
|
19
|
+
if (rootComponentOptions.customEvents) customEventsHandle(finalOptions, rootComponentOptions.customEvents);
|
|
19
20
|
|
|
20
21
|
if (rootComponentOptions.events) Object.assign(finalOptions.methods, rootComponentOptions.events);
|
|
21
22
|
|
|
@@ -31,7 +31,7 @@ export function sameFuncOptionsHandle(
|
|
|
31
31
|
_sameFuncOptionsHandle(finalOptionsForComponent.pageLifetimes, funcOptions.pageLifetimes);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
if (funcOptions.lifetimes) _sameFuncOptionsHandle(finalOptionsForComponent.lifetimes
|
|
34
|
+
if (funcOptions.lifetimes) _sameFuncOptionsHandle(finalOptionsForComponent.lifetimes, funcOptions.lifetimes);
|
|
35
35
|
|
|
36
|
-
if (funcOptions.watch) _sameFuncOptionsHandle(finalOptionsForComponent.watch
|
|
36
|
+
if (funcOptions.watch) _sameFuncOptionsHandle(finalOptionsForComponent.watch, funcOptions.watch);
|
|
37
37
|
}
|
|
@@ -35,3 +35,16 @@ RootComponent()({
|
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
});
|
|
38
|
+
// 3 、实例上不存在的字段应该报错
|
|
39
|
+
RootComponent()({
|
|
40
|
+
computed: {
|
|
41
|
+
str(): number {
|
|
42
|
+
// @ts-ignore 不存在的字段
|
|
43
|
+
return this.data.numd;
|
|
44
|
+
},
|
|
45
|
+
other(): string {
|
|
46
|
+
// @ts-ignore 不存在的字段
|
|
47
|
+
return this.func;
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|
|
@@ -45,6 +45,28 @@ export type OptionsFieldsConfigOfCustomEvents =
|
|
|
45
45
|
export type FullCustomEvents = {
|
|
46
46
|
detail: ShortCustomeEvents;
|
|
47
47
|
options: OptionsFieldsConfigOfCustomEvents;
|
|
48
|
+
debounce?: never;
|
|
49
|
+
throttle?: never;
|
|
50
|
+
} | {
|
|
51
|
+
detail: ShortCustomeEvents;
|
|
52
|
+
options?: never;
|
|
53
|
+
debounce: number;
|
|
54
|
+
throttle?: never;
|
|
55
|
+
} | {
|
|
56
|
+
detail: ShortCustomeEvents;
|
|
57
|
+
options?: never;
|
|
58
|
+
debounce?: never;
|
|
59
|
+
throttle: number;
|
|
60
|
+
} | {
|
|
61
|
+
detail: ShortCustomeEvents;
|
|
62
|
+
options: OptionsFieldsConfigOfCustomEvents;
|
|
63
|
+
debounce?: never;
|
|
64
|
+
throttle: number;
|
|
65
|
+
} | {
|
|
66
|
+
detail: ShortCustomeEvents;
|
|
67
|
+
options: OptionsFieldsConfigOfCustomEvents;
|
|
68
|
+
debounce: number;
|
|
69
|
+
throttle?: never;
|
|
48
70
|
};
|
|
49
71
|
|
|
50
72
|
export type CustomEvents = FullCustomEvents | ShortCustomeEvents;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IfExtends } from "hry-types/src/Any/IfExtends";
|
|
1
2
|
import type { DetailedType } from "../../../types/DetailedType";
|
|
2
3
|
import type { InferDetailedType } from "../../../types/InferDetailedType";
|
|
3
4
|
import type {
|
|
@@ -16,7 +17,7 @@ export type GetShortCustomEventsDoc<T extends ShortCustomeEvents> = T extends De
|
|
|
16
17
|
|
|
17
18
|
export type GetFullCustomEventsDoc<T extends FullCustomEvents> =
|
|
18
19
|
| GetShortCustomEventsDoc<T["detail"]>
|
|
19
|
-
| AddTagForCustomEventsDoc<T["options"]
|
|
20
|
+
| IfExtends<unknown, T["options"], never, AddTagForCustomEventsDoc<T["options"] & {}>>;
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* 获取自定义事件的文档
|
|
@@ -40,6 +41,7 @@ export type GetCustomEventDoc<T extends CustomEventConstraint> =
|
|
|
40
41
|
| GetShortCustomEventsDoc<T[k]["detail"]>
|
|
41
42
|
// 为自定义事件模型加标记,方便识别
|
|
42
43
|
// @ts-ignore T[k] 一定为 FullCustomEvents 类型
|
|
43
|
-
| AddTagForCustomEventsDoc<T[k]["options"]>;
|
|
44
|
+
// | AddTagForCustomEventsDoc<T[k]["options"]>;
|
|
45
|
+
| IfExtends<unknown, T[k]["options"], never, AddTagForCustomEventsDoc<T[k]["options"] & {}>>;
|
|
44
46
|
}
|
|
45
47
|
;
|
|
@@ -8,7 +8,7 @@ export const BBeforeCreate = Behavior({
|
|
|
8
8
|
definitionFilter(
|
|
9
9
|
options: Omit<FinalOptionsOfComponent, "customEvents" | "store" | "events" | "computed">,
|
|
10
10
|
) {
|
|
11
|
-
// 触发beforeCreate生命周期函数
|
|
11
|
+
// 触发beforeCreate生命周期函数
|
|
12
12
|
const beforeCreateFunc = options.lifetimes.beforeCreate;
|
|
13
13
|
|
|
14
14
|
if (beforeCreateFunc) {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import type { Instance } from "../api/RootComponent/Instance/RootComponentInstance";
|
|
3
|
+
import { debounce } from "../utils/debounce";
|
|
4
|
+
import { throttle } from "../utils/throttle";
|
|
5
|
+
|
|
6
|
+
export const BthrottleDebounce = Behavior({
|
|
7
|
+
lifetimes: {
|
|
8
|
+
created(this: Instance) {
|
|
9
|
+
const __throttleDebounce__ = this.data.__throttleDebounce__;
|
|
10
|
+
if (!__throttleDebounce__) return;
|
|
11
|
+
const debounceConfig = __throttleDebounce__.debounce;
|
|
12
|
+
if (debounceConfig) {
|
|
13
|
+
for (const key in debounceConfig) {
|
|
14
|
+
const _this = this as any;
|
|
15
|
+
_this[key] = debounce(_this[key].bind(this), debounceConfig[key]);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const throttleConfig = __throttleDebounce__.throttle;
|
|
19
|
+
if (throttleConfig) {
|
|
20
|
+
for (const key in throttleConfig) {
|
|
21
|
+
const _this = this as any;
|
|
22
|
+
_this[key] = throttle(_this[key].bind(this), throttleConfig[key]);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
delete this.data.__throttleDebounce__;
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,8 @@ import type { CreateComponentType } from "./types/CreateComponentType";
|
|
|
7
7
|
import type { DetailedType } from "./types/DetailedType";
|
|
8
8
|
import type { ExtendComponentType } from "./types/ExtendComponentType";
|
|
9
9
|
import type { ParamsEqual } from "./types/TwoParamsEqual";
|
|
10
|
+
export * from "./utils/_utils";
|
|
11
|
+
|
|
10
12
|
export type {
|
|
11
13
|
Bubbles,
|
|
12
14
|
BubblesCapture,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { assertNonNullable } from "./assertNonNullable";
|
|
2
|
+
import { debounce } from "./debounce";
|
|
3
|
+
import { deepClone } from "./deepClone";
|
|
4
|
+
import { deepEqual } from "./deepEqual";
|
|
5
|
+
import { isEmptyObject } from "./isEmptyObject";
|
|
6
|
+
import { throttle } from "./throttle";
|
|
7
|
+
|
|
8
|
+
export { assertNonNullable, debounce, deepClone, deepEqual, isEmptyObject, throttle };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/**
|
|
3
|
+
* 防抖函数
|
|
4
|
+
* 应用在输入框输入时,只有在输入完成并delay后,才会触发搜索
|
|
5
|
+
* @param func
|
|
6
|
+
* @param delay
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export function debounce<F extends (...args: any[]) => any>(func: F, delay: number): (...args: Parameters<F>) => void {
|
|
10
|
+
let timeoutId: NodeJS.Timeout | null = null;
|
|
11
|
+
|
|
12
|
+
return (...args: Parameters<F>): void => {
|
|
13
|
+
if (timeoutId) {
|
|
14
|
+
clearTimeout(timeoutId);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
timeoutId = setTimeout(() => func(...args), delay);
|
|
18
|
+
};
|
|
19
|
+
}
|