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.
Files changed (69) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/api/DefineComponent/normalizeOptions/__throttleDebounce__FieldCheck.d.ts +3 -0
  3. package/dist/api/DefineComponent/normalizeOptions/__throttleDebounce__FieldCheck.js +26 -0
  4. package/dist/api/DefineComponent/normalizeOptions/__throttleDebounce__FieldCheck.js.map +1 -0
  5. package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/computedUpdater.js +4 -4
  6. package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/computedUpdater.js.map +1 -1
  7. package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/data-tracer.d.ts +1 -1
  8. package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/data-tracer.js +7 -12
  9. package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/data-tracer.js.map +1 -1
  10. package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/getPropertiesValue.d.ts +1 -1
  11. package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/getPropertiesValue.js +1 -2
  12. package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/getPropertiesValue.js.map +1 -1
  13. package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/initComputedAndGetCache.js +2 -2
  14. package/dist/api/DefineComponent/normalizeOptions/computedWatchHandle/initComputedAndGetCache.js.map +1 -1
  15. package/dist/api/DefineComponent/normalizeOptions/customEventsHandle.d.ts +1 -1
  16. package/dist/api/DefineComponent/normalizeOptions/customEventsHandle.js +17 -1
  17. package/dist/api/DefineComponent/normalizeOptions/customEventsHandle.js.map +1 -1
  18. package/dist/api/DefineComponent/normalizeOptions/index.d.ts +2 -0
  19. package/dist/api/DefineComponent/normalizeOptions/index.js +8 -1
  20. package/dist/api/DefineComponent/normalizeOptions/index.js.map +1 -1
  21. package/dist/api/DefineComponent/normalizeOptions/internalFieldProtection.js +1 -1
  22. package/dist/api/DefineComponent/normalizeOptions/internalFieldProtection.js.map +1 -1
  23. package/dist/api/DefineComponent/normalizeOptions/rootComponentOptionHandle.js +2 -1
  24. package/dist/api/DefineComponent/normalizeOptions/rootComponentOptionHandle.js.map +1 -1
  25. package/dist/api/DefineComponent/normalizeOptions/sameFuncOptionsHandle.js +2 -2
  26. package/dist/api/DefineComponent/normalizeOptions/sameFuncOptionsHandle.js.map +1 -1
  27. package/dist/api/RootComponent/CustomEvents/CustomEventConstraint.d.ts +22 -0
  28. package/dist/api/RootComponent/CustomEvents/GetCustomEventDoc.d.ts +3 -2
  29. package/dist/behaviors/BbeforeCreated.js +1 -1
  30. package/dist/behaviors/BbeforeCreated.js.map +1 -1
  31. package/dist/behaviors/BthrottleDebounce.d.ts +1 -0
  32. package/dist/behaviors/BthrottleDebounce.js +27 -0
  33. package/dist/behaviors/BthrottleDebounce.js.map +1 -0
  34. package/dist/index.d.ts +1 -0
  35. package/dist/index.js +1 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/utils/_utils.d.ts +7 -0
  38. package/dist/utils/_utils.js +8 -0
  39. package/dist/utils/_utils.js.map +1 -0
  40. package/dist/utils/debounce.d.ts +8 -0
  41. package/dist/utils/debounce.js +18 -0
  42. package/dist/utils/debounce.js.map +1 -0
  43. package/dist/utils/deepEqual.d.ts +1 -7
  44. package/dist/utils/deepEqual.js +18 -58
  45. package/dist/utils/deepEqual.js.map +1 -1
  46. package/dist/utils/throttle.d.ts +10 -0
  47. package/dist/utils/throttle.js +18 -0
  48. package/dist/utils/throttle.js.map +1 -0
  49. package/package.json +5 -8
  50. package/src/api/DefineComponent/normalizeOptions/__throttleDebounce__FieldCheck.ts +27 -0
  51. package/src/api/DefineComponent/normalizeOptions/computedWatchHandle/computedUpdater.ts +4 -5
  52. package/src/api/DefineComponent/normalizeOptions/computedWatchHandle/data-tracer.ts +7 -13
  53. package/src/api/DefineComponent/normalizeOptions/computedWatchHandle/getPropertiesValue.ts +2 -4
  54. package/src/api/DefineComponent/normalizeOptions/computedWatchHandle/initComputedAndGetCache.ts +2 -2
  55. package/src/api/DefineComponent/normalizeOptions/customEventsHandle.ts +24 -3
  56. package/src/api/DefineComponent/normalizeOptions/index.ts +11 -2
  57. package/src/api/DefineComponent/normalizeOptions/internalFieldProtection.ts +1 -1
  58. package/src/api/DefineComponent/normalizeOptions/rootComponentOptionHandle.ts +2 -1
  59. package/src/api/DefineComponent/normalizeOptions/sameFuncOptionsHandle.ts +2 -2
  60. package/src/api/RootComponent/Computed/test/error.test.ts +13 -0
  61. package/src/api/RootComponent/CustomEvents/CustomEventConstraint.ts +22 -0
  62. package/src/api/RootComponent/CustomEvents/GetCustomEventDoc.ts +4 -2
  63. package/src/behaviors/BbeforeCreated.ts +1 -1
  64. package/src/behaviors/BthrottleDebounce.ts +28 -0
  65. package/src/index.ts +2 -0
  66. package/src/utils/_utils.ts +8 -0
  67. package/src/utils/debounce.ts +19 -0
  68. package/src/utils/deepEqual.ts +19 -65
  69. package/src/utils/throttle.ts +23 -0
@@ -1,69 +1,29 @@
1
- function isSameType(a, b) {
2
- return Object.prototype.toString.call(a) === Object.prototype.toString.call(b);
1
+ // 非null的对象类型
2
+ function isNonNullObject(value) {
3
+ return value !== null && typeof value === "object";
3
4
  }
4
- // 定义一个辅助函数,用于判断两个对象的属性数量是否相同
5
- function isSameSize(a, b) {
6
- return Object.keys(a).length === Object.keys(b).length;
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 (!isSameType(a, b) || a.constructor !== b.constructor || !isSameSize(a, b)) {
10
+ // 有一个不是非空对象,返回false。
11
+ if (!isNonNullObject(value1) || !isNonNullObject(value2)) {
37
12
  return false;
38
13
  }
39
- // 如果两个值是函数类型,再判断它们的代码是否相同
40
- if (typeof a === "function") {
41
- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
42
- return isSameCode(a, b);
43
- }
44
- // 如果两个值是日期类型,再判断它们的时间戳是否相同
45
- if (a instanceof Date) {
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
- const keysA = Object.keys(a);
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":"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"}
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.7.8",
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.8.0",
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.0.0"
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.2"
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, getProxyOriginalValue } from "./data-tracer";
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]: getProxyOriginalValue(newValue),
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
- export function getProxyOriginalValue(value: { __original__?: unknown }): unknown {
40
- if (typeof value !== "object" || value === null) {
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 ret;
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 | undefined): object | undefined {
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);
@@ -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, getProxyOriginalValue } from "./data-tracer";
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 = getProxyOriginalValue(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
- methods: FinalOptionsOfComponent["methods"],
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
- if (rootComponentOptions.customEvents) customEventsHandle(finalOptions.methods, rootComponentOptions.customEvents);
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 ||= {}, funcOptions.lifetimes);
34
+ if (funcOptions.lifetimes) _sameFuncOptionsHandle(finalOptionsForComponent.lifetimes, funcOptions.lifetimes);
35
35
 
36
- if (funcOptions.watch) _sameFuncOptionsHandle(finalOptionsForComponent.watch ||= {}, funcOptions.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生命周期函数 options.lifetimes在之前被赋值过默认{}所以!
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
+ }