wevu 0.0.2-alpha.0 → 1.0.0-alpha.2

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/README.md CHANGED
@@ -5,7 +5,7 @@ Vue 3 风格的小程序运行时,复用同款响应式与调度器,通过
5
5
  ## 特性
6
6
 
7
7
  - `ref`/`reactive`/`computed`/`watch` 与 `nextTick` 同源于 Vue 3 的响应式核心
8
- - `definePage`/`defineComponent` + `setup` 生命周期钩子(onShow/onPageScroll/onShareAppMessage 等)自动注册微信小程序 Page/Component
8
+ - `defineComponent` + `setup` 生命周期钩子(onShow/onPageScroll/onShareAppMessage 等)自动注册微信小程序 `Component`(在微信中可用于页面/组件)
9
9
  - 快照 diff + 去重调度,最小化 `setData` 体积,支持 `bindModel` 的双向绑定语法
10
10
  - 插件、`app.config.globalProperties` 及小程序原生选项可自由组合
11
11
  - 内置 `defineStore`/`storeToRefs`/`createStore`,支持 getters、actions、订阅与补丁
@@ -23,7 +23,7 @@ pnpm add wevu
23
23
  ```ts
24
24
  import {
25
25
  computed,
26
- definePage,
26
+ defineComponent,
27
27
  nextTick,
28
28
  onMounted,
29
29
  onPageScroll,
@@ -31,47 +31,45 @@ import {
31
31
  ref,
32
32
  } from 'wevu'
33
33
 
34
- definePage(
35
- {
36
- data: () => ({ count: 0 }),
37
- computed: {
38
- doubled() {
39
- return this.count * 2
40
- },
41
- },
42
- methods: {
43
- inc() {
44
- this.count += 1
45
- },
34
+ defineComponent({
35
+ features: {
36
+ listenPageScroll: true,
37
+ enableShareAppMessage: true,
38
+ },
39
+ data: () => ({ count: 0 }),
40
+ computed: {
41
+ doubled() {
42
+ return this.count * 2
46
43
  },
47
- watch: {
48
- count(n) {
49
- console.log('count changed', n)
50
- },
44
+ },
45
+ methods: {
46
+ inc() {
47
+ this.count += 1
51
48
  },
52
- setup({ state }) {
53
- const title = computed(() => `count: ${state.count}`)
54
- const local = ref(0)
55
-
56
- onMounted(() => {
57
- nextTick(() => console.log('page ready'))
58
- })
59
- onPageScroll((e) => {
60
- console.log('scrollTop', e?.scrollTop)
61
- })
62
- onShareAppMessage(() => ({ title: title.value }))
63
-
64
- return { local }
49
+ },
50
+ watch: {
51
+ count(n) {
52
+ console.log('count changed', n)
65
53
  },
66
54
  },
67
- {
68
- listenPageScroll: true,
69
- enableShareAppMessage: true,
55
+ setup({ state }) {
56
+ const title = computed(() => `count: ${state.count}`)
57
+ const local = ref(0)
58
+
59
+ onMounted(() => {
60
+ nextTick(() => console.log('page ready'))
61
+ })
62
+ onPageScroll((e) => {
63
+ console.log('scrollTop', e?.scrollTop)
64
+ })
65
+ onShareAppMessage(() => ({ title: title.value }))
66
+
67
+ return { local }
70
68
  },
71
- )
69
+ })
72
70
  ```
73
71
 
74
- - 当全局存在 `Page`/`Component` 构造器时自动注册;否则可拿到 `component.__wevu_runtime` 手动挂载适配器。
72
+ - 当全局存在 `Component` 构造器时自动注册;否则可拿到 `component.__wevu_runtime` 手动挂载适配器。
75
73
  - 组件场景使用 `defineComponent`,SFC 构建产物可调用 `createWevuComponent`。
76
74
 
77
75
  ## 状态管理
@@ -104,7 +102,7 @@ counter.inc()
104
102
 
105
103
  - 更新被批量加入微任务队列,`nextTick` 与 Vue 3 行为一致。
106
104
  - 对状态做快照 diff,只把变更路径传给 `setData`,避免大对象全量下发。
107
- - 可在 `createApp().mount(adapter)` 传入自定义 `setData` 适配器(例如单元测试或其他小程序平台)。
105
+ - 提供 `batch`/`startBatch`/`endBatch` 用于同步更新合并触发;以及 `effectScope`/`onScopeDispose` 统一管理 effect/watch 的销毁,便于避免泄漏。
108
106
 
109
107
  ## 本地开发
110
108
 
@@ -1,6 +1,8 @@
1
1
  //#region src/reactivity/ref.d.ts
2
- interface Ref<T = any> {
3
- value: T;
2
+ interface Ref<T = any, S = T> {
3
+ get value(): T;
4
+ set value(_: S);
5
+ [key: symbol]: any;
4
6
  }
5
7
  declare function isRef(value: unknown): value is Ref<any>;
6
8
  declare function ref<T>(value: T): Ref<T>;
@@ -1,6 +1,8 @@
1
1
  //#region src/reactivity/ref.d.ts
2
- interface Ref<T = any> {
3
- value: T;
2
+ interface Ref<T = any, S = T> {
3
+ get value(): T;
4
+ set value(_: S);
5
+ [key: symbol]: any;
4
6
  }
5
7
  declare function isRef(value: unknown): value is Ref<any>;
6
8
  declare function ref<T>(value: T): Ref<T>;
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_store = require('./store-Cmw9vWBT.cjs');
1
+ const require_store = require('./store-D0GD8ulz.cjs');
2
2
 
3
3
  //#region src/reactivity/readonly.ts
4
4
  function readonly(target) {
@@ -155,10 +155,13 @@ function watch(source, cb, options = {}) {
155
155
  });
156
156
  if (options.immediate) job();
157
157
  else oldValue = runner();
158
- return () => {
158
+ const stopHandle = () => {
159
159
  cleanup?.();
160
+ cleanup = void 0;
160
161
  require_store.stop(runner);
161
162
  };
163
+ require_store.onScopeDispose(stopHandle);
164
+ return stopHandle;
162
165
  }
163
166
  /**
164
167
  * watchEffect 注册一个响应式副作用,可选清理函数。
@@ -173,14 +176,20 @@ function watchEffect(effectFn) {
173
176
  cleanup?.();
174
177
  cleanup = void 0;
175
178
  effectFn(onCleanup);
176
- }, { scheduler: () => require_store.queueJob(() => {
177
- if (runner.active) runner();
178
- }) });
179
+ }, {
180
+ lazy: true,
181
+ scheduler: () => require_store.queueJob(() => {
182
+ if (runner.active) runner();
183
+ })
184
+ });
179
185
  runner();
180
- return () => {
186
+ const stopHandle = () => {
181
187
  cleanup?.();
188
+ cleanup = void 0;
182
189
  require_store.stop(runner);
183
190
  };
191
+ require_store.onScopeDispose(stopHandle);
192
+ return stopHandle;
184
193
  }
185
194
 
186
195
  //#endregion
@@ -283,7 +292,7 @@ function createBindModel(publicInstance, state, computedRefs, computedSetters) {
283
292
 
284
293
  //#endregion
285
294
  //#region src/runtime/diff.ts
286
- function isPlainObject(value) {
295
+ function isPlainObject$1(value) {
287
296
  if (Object.prototype.toString.call(value) !== "[object Object]") return false;
288
297
  const proto = Object.getPrototypeOf(value);
289
298
  return proto === null || proto === Object.prototype;
@@ -311,7 +320,7 @@ function toPlain(value, seen = /* @__PURE__ */ new WeakMap()) {
311
320
  function isDeepEqual(a, b) {
312
321
  if (Object.is(a, b)) return true;
313
322
  if (Array.isArray(a) && Array.isArray(b)) return isArrayEqual(a, b);
314
- if (isPlainObject(a) && isPlainObject(b)) return isPlainObjectEqual(a, b);
323
+ if (isPlainObject$1(a) && isPlainObject$1(b)) return isPlainObjectEqual(a, b);
315
324
  return false;
316
325
  }
317
326
  function isArrayEqual(a, b) {
@@ -334,7 +343,7 @@ function normalizeSetDataValue(value) {
334
343
  }
335
344
  function assignNestedDiff(prev, next, path, output) {
336
345
  if (isDeepEqual(prev, next)) return;
337
- if (isPlainObject(prev) && isPlainObject(next)) {
346
+ if (isPlainObject$1(prev) && isPlainObject$1(next)) {
338
347
  new Set([...Object.keys(prev), ...Object.keys(next)]).forEach((key) => {
339
348
  if (!Object.prototype.hasOwnProperty.call(next, key)) {
340
349
  output[`${path}.${key}`] = null;
@@ -546,6 +555,20 @@ function callUpdateHooks(target, phase) {
546
555
 
547
556
  //#endregion
548
557
  //#region src/runtime/register.ts
558
+ function runInlineExpression(ctx, expr, event) {
559
+ const handlerName = typeof expr === "string" ? expr : void 0;
560
+ if (!handlerName) return;
561
+ const argsRaw = (event?.currentTarget)?.dataset?.wvArgs ?? (event?.target)?.dataset?.wvArgs;
562
+ let args = [];
563
+ if (typeof argsRaw === "string") try {
564
+ args = JSON.parse(argsRaw);
565
+ } catch {
566
+ args = [];
567
+ }
568
+ const resolvedArgs = args.map((item) => item === "$event" ? event : item);
569
+ const handler = ctx?.[handlerName];
570
+ if (typeof handler === "function") return handler.apply(ctx, resolvedArgs);
571
+ }
549
572
  function runSetupFunction(setup, props, context) {
550
573
  if (typeof setup !== "function") return;
551
574
  const runtimeContext = context?.runtime ?? {
@@ -611,6 +634,7 @@ function registerWatches(runtime, watchMap, instance) {
611
634
  return stops;
612
635
  }
613
636
  function mountRuntimeInstance(target, runtimeApp, watchMap, setup) {
637
+ if (target.__wevu) return target.__wevu;
614
638
  const runtime = runtimeApp.mount({ setData(payload) {
615
639
  if (typeof target.setData === "function") target.setData(payload);
616
640
  } });
@@ -682,6 +706,7 @@ function mountRuntimeInstance(target, runtimeApp, watchMap, setup) {
682
706
  }
683
707
  function teardownRuntimeInstance(target) {
684
708
  const runtime = target.__wevu;
709
+ if (runtime && target.__wevuHooks) callHookList(target, "onUnload", []);
685
710
  if (target.__wevuHooks) target.__wevuHooks = void 0;
686
711
  const stops = target.__wevuWatchStops;
687
712
  if (Array.isArray(stops)) for (const stop$1 of stops) try {
@@ -697,6 +722,10 @@ function registerApp(runtimeApp, methods, watch$1, setup, mpOptions) {
697
722
  const methodNames = Object.keys(methods ?? {});
698
723
  const appOptions = { ...mpOptions };
699
724
  appOptions.globalData = appOptions.globalData ?? {};
725
+ if (!appOptions.__weapp_vite_inline) appOptions.__weapp_vite_inline = function __weapp_vite_inline(event) {
726
+ const expr = event?.currentTarget?.dataset?.wvHandler ?? event?.target?.dataset?.wvHandler;
727
+ return runInlineExpression(this.__wevu?.proxy ?? this, expr, event);
728
+ };
700
729
  const userOnLaunch = appOptions.onLaunch;
701
730
  appOptions.onLaunch = function onLaunch(...args) {
702
731
  mountRuntimeInstance(this, runtimeApp, watch$1, setup);
@@ -731,89 +760,38 @@ function registerApp(runtimeApp, methods, watch$1, setup, mpOptions) {
731
760
  }
732
761
  App(appOptions);
733
762
  }
734
- function registerPage(runtimeApp, methods, watch$1, setup, mpOptions, features) {
735
- if (typeof Page !== "function") throw new TypeError("definePage requires the global Page constructor to be available");
736
- const methodNames = Object.keys(methods ?? {});
737
- const pageOptions = { ...mpOptions };
738
- const userOnLoad = mpOptions.onLoad;
739
- pageOptions.onLoad = function onLoad(...args) {
740
- mountRuntimeInstance(this, runtimeApp, watch$1, setup);
741
- callHookList(this, "onShow", args);
742
- if (typeof userOnLoad === "function") userOnLoad.apply(this, args);
743
- };
744
- const userOnUnload = mpOptions.onUnload;
745
- pageOptions.onUnload = function onUnload$1(...args) {
746
- teardownRuntimeInstance(this);
747
- if (typeof userOnUnload === "function") userOnUnload.apply(this, args);
763
+ function registerComponent(runtimeApp, methods, watch$1, setup, mpOptions, features) {
764
+ const { methods: userMethods = {}, lifetimes: userLifetimes = {}, pageLifetimes: userPageLifetimes = {}, options: userOptions = {}, ...rest } = mpOptions;
765
+ const userOnLoad = rest.onLoad;
766
+ const userOnUnload = rest.onUnload;
767
+ const userOnShow = rest.onShow;
768
+ const userOnHide = rest.onHide;
769
+ const userOnReady = rest.onReady;
770
+ const userOnSaveExitState = rest.onSaveExitState;
771
+ const userOnPageScroll = rest.onPageScroll;
772
+ const userOnShareAppMessage = rest.onShareAppMessage;
773
+ const userOnShareTimeline = rest.onShareTimeline;
774
+ const userOnAddToFavorites = rest.onAddToFavorites;
775
+ const restOptions = { ...rest };
776
+ delete restOptions.onLoad;
777
+ delete restOptions.onUnload;
778
+ delete restOptions.onShow;
779
+ delete restOptions.onHide;
780
+ delete restOptions.onReady;
781
+ delete restOptions.onSaveExitState;
782
+ delete restOptions.onPageScroll;
783
+ delete restOptions.onShareAppMessage;
784
+ delete restOptions.onShareTimeline;
785
+ delete restOptions.onAddToFavorites;
786
+ const finalOptions = {
787
+ multipleSlots: userOptions.multipleSlots ?? true,
788
+ ...userOptions
748
789
  };
749
- const userOnShow = mpOptions.onShow;
750
- pageOptions.onShow = function onShow$1(...args) {
751
- callHookList(this, "onShow", args);
752
- if (typeof userOnShow === "function") userOnShow.apply(this, args);
753
- };
754
- const userOnHide = mpOptions.onHide;
755
- pageOptions.onHide = function onHide$1(...args) {
756
- callHookList(this, "onHide", args);
757
- if (typeof userOnHide === "function") userOnHide.apply(this, args);
758
- };
759
- const userOnReady = mpOptions.onReady;
760
- pageOptions.onReady = function onReady$1(...args) {
761
- callHookList(this, "onReady", args);
762
- if (typeof userOnReady === "function") return userOnReady.apply(this, args);
763
- };
764
- const userOnSaveExitState = mpOptions.onSaveExitState;
765
- pageOptions.onSaveExitState = function onSaveExitState$1(...args) {
766
- const ret = callHookReturn(this, "onSaveExitState", args);
767
- if (ret !== void 0) return ret;
768
- if (typeof userOnSaveExitState === "function") return userOnSaveExitState.apply(this, args);
769
- };
770
- if (features?.listenPageScroll) {
771
- const userOnPageScroll = mpOptions.onPageScroll;
772
- pageOptions.onPageScroll = function onPageScroll$1(...args) {
773
- callHookList(this, "onPageScroll", args);
774
- if (typeof userOnPageScroll === "function") return userOnPageScroll.apply(this, args);
775
- };
776
- }
777
- if (features?.enableShareAppMessage) {
778
- const userOnShare = mpOptions.onShareAppMessage;
779
- pageOptions.onShareAppMessage = function pageOnShareAppMessage(...args) {
780
- const ret = callHookReturn(this, "onShareAppMessage", args);
781
- if (ret !== void 0) return ret;
782
- if (typeof userOnShare === "function") return userOnShare.apply(this, args);
783
- };
784
- }
785
- if (features?.enableShareTimeline) {
786
- const userOnShareTimeline = mpOptions.onShareTimeline;
787
- pageOptions.onShareTimeline = function pageOnShareTimeline(...args) {
788
- const ret = callHookReturn(this, "onShareTimeline", args);
789
- if (ret !== void 0) return ret;
790
- if (typeof userOnShareTimeline === "function") return userOnShareTimeline.apply(this, args);
791
- };
792
- }
793
- if (features?.enableAddToFavorites) {
794
- const userOnAddToFavorites = mpOptions.onAddToFavorites;
795
- pageOptions.onAddToFavorites = function pageOnAddToFavorites(...args) {
796
- const ret = callHookReturn(this, "onAddToFavorites", args);
797
- if (ret !== void 0) return ret;
798
- if (typeof userOnAddToFavorites === "function") return userOnAddToFavorites.apply(this, args);
799
- };
800
- }
801
- for (const methodName of methodNames) {
802
- const userMethod = mpOptions[methodName];
803
- pageOptions[methodName] = function runtimeMethod(...args) {
804
- const runtime = this.__wevu;
805
- let result;
806
- const bound = runtime?.methods?.[methodName];
807
- if (bound) result = bound.apply(runtime.proxy, args);
808
- if (typeof userMethod === "function") return userMethod.apply(this, args);
809
- return result;
810
- };
811
- }
812
- Page(pageOptions);
813
- }
814
- function registerComponent(runtimeApp, methods, watch$1, setup, mpOptions) {
815
- const { methods: userMethods = {}, lifetimes: userLifetimes = {}, pageLifetimes: userPageLifetimes = {}, ...rest } = mpOptions;
816
790
  const finalMethods = { ...userMethods };
791
+ if (!finalMethods.__weapp_vite_inline) finalMethods.__weapp_vite_inline = function __weapp_vite_inline(event) {
792
+ const expr = event?.currentTarget?.dataset?.wvHandler ?? event?.target?.dataset?.wvHandler;
793
+ return runInlineExpression(this.__wevu?.proxy ?? this, expr, event);
794
+ };
817
795
  const methodNames = Object.keys(methods ?? {});
818
796
  for (const methodName of methodNames) {
819
797
  const userMethod = finalMethods[methodName];
@@ -835,8 +813,58 @@ function registerComponent(runtimeApp, methods, watch$1, setup, mpOptions) {
835
813
  };
836
814
  wrapSpecial("onTabItemTap");
837
815
  wrapSpecial("onRouteDone");
816
+ const pageLifecycleHooks = {
817
+ onLoad(...args) {
818
+ mountRuntimeInstance(this, runtimeApp, watch$1, setup);
819
+ if (typeof userOnLoad === "function") return userOnLoad.apply(this, args);
820
+ },
821
+ onUnload(...args) {
822
+ teardownRuntimeInstance(this);
823
+ if (typeof userOnUnload === "function") return userOnUnload.apply(this, args);
824
+ },
825
+ onShow(...args) {
826
+ callHookList(this, "onShow", args);
827
+ if (typeof userOnShow === "function") return userOnShow.apply(this, args);
828
+ },
829
+ onHide(...args) {
830
+ callHookList(this, "onHide", args);
831
+ if (typeof userOnHide === "function") return userOnHide.apply(this, args);
832
+ },
833
+ onReady(...args) {
834
+ if (!this.__wevuReadyCalled) {
835
+ this.__wevuReadyCalled = true;
836
+ callHookList(this, "onReady", args);
837
+ }
838
+ if (typeof userOnReady === "function") return userOnReady.apply(this, args);
839
+ },
840
+ onSaveExitState(...args) {
841
+ const ret = callHookReturn(this, "onSaveExitState", args);
842
+ if (ret !== void 0) return ret;
843
+ if (typeof userOnSaveExitState === "function") return userOnSaveExitState.apply(this, args);
844
+ }
845
+ };
846
+ if (features?.listenPageScroll) pageLifecycleHooks.onPageScroll = function onPageScroll$1(...args) {
847
+ callHookList(this, "onPageScroll", args);
848
+ if (typeof userOnPageScroll === "function") return userOnPageScroll.apply(this, args);
849
+ };
850
+ if (features?.enableShareAppMessage) pageLifecycleHooks.onShareAppMessage = function onShareAppMessage$1(...args) {
851
+ const ret = callHookReturn(this, "onShareAppMessage", args);
852
+ if (ret !== void 0) return ret;
853
+ if (typeof userOnShareAppMessage === "function") return userOnShareAppMessage.apply(this, args);
854
+ };
855
+ if (features?.enableShareTimeline) pageLifecycleHooks.onShareTimeline = function onShareTimeline$1(...args) {
856
+ const ret = callHookReturn(this, "onShareTimeline", args);
857
+ if (ret !== void 0) return ret;
858
+ if (typeof userOnShareTimeline === "function") return userOnShareTimeline.apply(this, args);
859
+ };
860
+ if (features?.enableAddToFavorites) pageLifecycleHooks.onAddToFavorites = function onAddToFavorites$1(...args) {
861
+ const ret = callHookReturn(this, "onAddToFavorites", args);
862
+ if (ret !== void 0) return ret;
863
+ if (typeof userOnAddToFavorites === "function") return userOnAddToFavorites.apply(this, args);
864
+ };
838
865
  Component({
839
- ...rest,
866
+ ...restOptions,
867
+ ...pageLifecycleHooks,
840
868
  lifetimes: {
841
869
  ...userLifetimes,
842
870
  attached: function attached(...args) {
@@ -844,7 +872,10 @@ function registerComponent(runtimeApp, methods, watch$1, setup, mpOptions) {
844
872
  if (typeof userLifetimes.attached === "function") userLifetimes.attached.apply(this, args);
845
873
  },
846
874
  ready: function ready(...args) {
847
- callHookList(this, "onReady", args);
875
+ if (!this.__wevuReadyCalled) {
876
+ this.__wevuReadyCalled = true;
877
+ callHookList(this, "onReady", args);
878
+ }
848
879
  if (typeof userLifetimes.ready === "function") userLifetimes.ready.apply(this, args);
849
880
  },
850
881
  detached: function detached(...args) {
@@ -863,7 +894,8 @@ function registerComponent(runtimeApp, methods, watch$1, setup, mpOptions) {
863
894
  if (typeof userPageLifetimes.hide === "function") userPageLifetimes.hide.apply(this, args);
864
895
  }
865
896
  },
866
- methods: finalMethods
897
+ methods: finalMethods,
898
+ options: finalOptions
867
899
  });
868
900
  }
869
901
 
@@ -986,6 +1018,7 @@ function createApp(options) {
986
1018
  };
987
1019
  const job = () => {
988
1020
  if (!mounted) return;
1021
+ tracker();
989
1022
  const snapshot = collectSnapshot();
990
1023
  const diff = diffSnapshots(latestSnapshot, snapshot);
991
1024
  latestSnapshot = snapshot;
@@ -995,10 +1028,18 @@ function createApp(options) {
995
1028
  if (result && typeof result.then === "function") result.catch(() => {});
996
1029
  }
997
1030
  };
998
- const tracker = require_store.effect(() => {
1031
+ let tracker;
1032
+ tracker = require_store.effect(() => {
999
1033
  require_store.touchReactive(state);
1034
+ Object.keys(state).forEach((key) => {
1035
+ const v = state[key];
1036
+ if (require_store.isRef(v)) v.value;
1037
+ });
1000
1038
  Object.keys(computedRefs).forEach((key) => computedRefs[key].value);
1001
- }, { scheduler: () => require_store.queueJob(job) });
1039
+ }, {
1040
+ lazy: true,
1041
+ scheduler: () => require_store.queueJob(job)
1042
+ });
1002
1043
  job();
1003
1044
  stopHandles.push(() => require_store.stop(tracker));
1004
1045
  function registerWatch(source, cb, watchOptions) {
@@ -1065,7 +1106,9 @@ function setComputedValue(setters, key, value) {
1065
1106
  //#endregion
1066
1107
  //#region src/runtime/define.ts
1067
1108
  /**
1068
- * 按 Vue 3 风格定义一个小程序组件(始终注册为 Component,页面请用 definePage)。
1109
+ * 按 Vue 3 风格定义一个小程序组件/页面。
1110
+ *
1111
+ * - 统一注册为 `Component()`
1069
1112
  *
1070
1113
  * @param options 组件定义项
1071
1114
  * @returns 可手动注册的组件定义
@@ -1079,57 +1122,19 @@ function setComputedValue(setters, key, value) {
1079
1122
  * }
1080
1123
  * })
1081
1124
  * ```
1082
- */
1083
- function defineComponent(options) {
1084
- const { data, computed: computed$1, methods, watch: watch$1, setup, props, ...mpOptions } = options;
1085
- const mpOptionsWithProps = normalizeProps(mpOptions, props);
1086
- const runtimeApp = createApp({
1087
- data,
1088
- computed: computed$1,
1089
- methods
1090
- });
1091
- const setupWrapper = (ctx) => {
1092
- const result = runSetupFunction(setup, ctx?.props ?? {}, ctx);
1093
- if (result) applySetupResult(ctx.runtime, ctx.instance, result);
1094
- };
1095
- const componentOptions = {
1096
- data,
1097
- computed: computed$1,
1098
- methods,
1099
- watch: watch$1,
1100
- setup: setupWrapper,
1101
- mpOptions: mpOptionsWithProps
1102
- };
1103
- registerComponent(runtimeApp, methods ?? {}, watch$1, setupWrapper, mpOptionsWithProps);
1104
- return {
1105
- __wevu_runtime: runtimeApp,
1106
- __wevu_options: componentOptions
1107
- };
1108
- }
1109
- /**
1110
- * 按 Vue 3 风格定义一个小程序页面
1111
- *
1112
- * @param options 页面定义
1113
- * @param features 页面特性(例如 listenPageScroll、enableShareAppMessage 等)
1114
- * @returns 页面定义
1115
1125
  *
1116
1126
  * @example
1117
1127
  * ```ts
1118
- * definePage({
1119
- * data: () => ({ count: 0 }),
1128
+ * defineComponent({
1129
+ * features: { listenPageScroll: true },
1120
1130
  * setup() {
1121
- * const count = ref(0)
1122
- * onMounted(() => console.log('page mounted'))
1123
- * return { count }
1131
+ * onPageScroll(() => {})
1124
1132
  * }
1125
- * }, {
1126
- * listenPageScroll: true,
1127
- * enableShareAppMessage: true
1128
1133
  * })
1129
1134
  * ```
1130
1135
  */
1131
- function definePage(options, features) {
1132
- const { data, computed: computed$1, methods, watch: watch$1, setup, props: _props, ...mpOptions } = options;
1136
+ function defineComponent(options) {
1137
+ const { features, data, computed: computed$1, methods, watch: watch$1, setup, props, ...mpOptions } = options;
1133
1138
  const runtimeApp = createApp({
1134
1139
  data,
1135
1140
  computed: computed$1,
@@ -1139,19 +1144,18 @@ function definePage(options, features) {
1139
1144
  const result = runSetupFunction(setup, ctx?.props ?? {}, ctx);
1140
1145
  if (result) applySetupResult(ctx.runtime, ctx.instance, result);
1141
1146
  };
1147
+ const mpOptionsWithProps = normalizeProps(mpOptions, props);
1142
1148
  const componentOptions = {
1143
- type: "page",
1144
1149
  data,
1145
1150
  computed: computed$1,
1146
1151
  methods,
1147
1152
  watch: watch$1,
1148
1153
  setup: setupWrapper,
1149
- mpOptions,
1154
+ mpOptions: mpOptionsWithProps,
1150
1155
  features
1151
1156
  };
1152
- registerPage(runtimeApp, methods ?? {}, watch$1, setupWrapper, mpOptions, features);
1157
+ registerComponent(runtimeApp, methods ?? {}, watch$1, setupWrapper, mpOptionsWithProps, features);
1153
1158
  return {
1154
- mount: () => {},
1155
1159
  __wevu_runtime: runtimeApp,
1156
1160
  __wevu_options: componentOptions
1157
1161
  };
@@ -1159,6 +1163,7 @@ function definePage(options, features) {
1159
1163
  function applySetupResult(runtime, _target, result) {
1160
1164
  const methods = runtime?.methods ?? Object.create(null);
1161
1165
  const state = runtime?.state ?? Object.create(null);
1166
+ const rawState = require_store.isReactive(state) ? require_store.toRaw(state) : state;
1162
1167
  if (runtime && !runtime.methods) try {
1163
1168
  runtime.methods = methods;
1164
1169
  } catch {}
@@ -1168,6 +1173,16 @@ function applySetupResult(runtime, _target, result) {
1168
1173
  Object.keys(result).forEach((key) => {
1169
1174
  const val = result[key];
1170
1175
  if (typeof val === "function") methods[key] = (...args) => val.apply(runtime?.proxy ?? runtime, args);
1176
+ else if (val === _target || !shouldExposeInSnapshot(val)) try {
1177
+ Object.defineProperty(rawState, key, {
1178
+ value: val,
1179
+ configurable: true,
1180
+ enumerable: false,
1181
+ writable: true
1182
+ });
1183
+ } catch {
1184
+ state[key] = val;
1185
+ }
1171
1186
  else state[key] = val;
1172
1187
  });
1173
1188
  if (runtime) {
@@ -1175,6 +1190,18 @@ function applySetupResult(runtime, _target, result) {
1175
1190
  runtime.state = runtime.state ?? state;
1176
1191
  }
1177
1192
  }
1193
+ function isPlainObject(value) {
1194
+ if (Object.prototype.toString.call(value) !== "[object Object]") return false;
1195
+ const proto = Object.getPrototypeOf(value);
1196
+ return proto === null || proto === Object.prototype;
1197
+ }
1198
+ function shouldExposeInSnapshot(value) {
1199
+ if (value == null) return true;
1200
+ if (typeof value !== "object") return true;
1201
+ if (require_store.isRef(value) || require_store.isReactive(value)) return true;
1202
+ if (Array.isArray(value)) return true;
1203
+ return isPlainObject(value);
1204
+ }
1178
1205
  /**
1179
1206
  * 从 Vue SFC 选项创建 wevu 组件,供 weapp-vite 编译产物直接调用的兼容入口。
1180
1207
  *
@@ -1287,6 +1314,7 @@ function injectGlobal(key, defaultValue) {
1287
1314
  }
1288
1315
 
1289
1316
  //#endregion
1317
+ exports.batch = require_store.batch;
1290
1318
  exports.callHookList = callHookList;
1291
1319
  exports.callHookReturn = callHookReturn;
1292
1320
  exports.callUpdateHooks = callUpdateHooks;
@@ -1295,10 +1323,12 @@ exports.createApp = createApp;
1295
1323
  exports.createStore = require_store.createStore;
1296
1324
  exports.createWevuComponent = createWevuComponent;
1297
1325
  exports.defineComponent = defineComponent;
1298
- exports.definePage = definePage;
1299
1326
  exports.defineStore = require_store.defineStore;
1300
1327
  exports.effect = require_store.effect;
1328
+ exports.effectScope = require_store.effectScope;
1329
+ exports.endBatch = require_store.endBatch;
1301
1330
  exports.getCurrentInstance = getCurrentInstance;
1331
+ exports.getCurrentScope = require_store.getCurrentScope;
1302
1332
  exports.getDeepWatchStrategy = getDeepWatchStrategy;
1303
1333
  exports.inject = inject;
1304
1334
  exports.injectGlobal = injectGlobal;
@@ -1326,6 +1356,7 @@ exports.onPageScroll = onPageScroll;
1326
1356
  exports.onReady = onReady;
1327
1357
  exports.onRouteDone = onRouteDone;
1328
1358
  exports.onSaveExitState = onSaveExitState;
1359
+ exports.onScopeDispose = require_store.onScopeDispose;
1329
1360
  exports.onServerPrefetch = onServerPrefetch;
1330
1361
  exports.onShareAppMessage = onShareAppMessage;
1331
1362
  exports.onShareTimeline = onShareTimeline;
@@ -1341,12 +1372,12 @@ exports.readonly = readonly;
1341
1372
  exports.ref = require_store.ref;
1342
1373
  exports.registerApp = registerApp;
1343
1374
  exports.registerComponent = registerComponent;
1344
- exports.registerPage = registerPage;
1345
1375
  exports.runSetupFunction = runSetupFunction;
1346
1376
  exports.setCurrentInstance = setCurrentInstance;
1347
1377
  exports.setDeepWatchStrategy = setDeepWatchStrategy;
1348
1378
  exports.shallowReactive = require_store.shallowReactive;
1349
1379
  exports.shallowRef = shallowRef;
1380
+ exports.startBatch = require_store.startBatch;
1350
1381
  exports.stop = require_store.stop;
1351
1382
  exports.storeToRefs = require_store.storeToRefs;
1352
1383
  exports.teardownRuntimeInstance = teardownRuntimeInstance;