vue-page-store 0.4.1 → 0.5.0

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
@@ -17,6 +17,7 @@
17
17
  - **enter / leave** — 页面可见性生命周期
18
18
  - **$setInterval** — 页面级定时器托管
19
19
  - **event bus** — 页面内作用域通信
20
+ - **plugin** — 外部扩展机制(v0.5 新增)
20
21
 
21
22
  页面离开时可以自动清理页面级定时器,页面销毁时 `$destroy` 一键回收,不污染全局。
22
23
 
@@ -176,6 +177,11 @@ export default {
176
177
  | `init` | `function` | store 创建后一次性调用,`$vm` 已可用。适合拉字典、注册事件监听 |
177
178
  | `enter` | `function` | 页面进入可见 / 可交互状态时触发 |
178
179
  | `leave` | `function` | 页面离开可见 / 可交互状态时触发 |
180
+ | *其它字段* | *any* | 注册过的 plugin 可声明自己的字段(见 [Plugin](#plugin)) |
181
+
182
+ ### `registerPlugin(plugin)` *(v0.5 新增)*
183
+
184
+ 注册全局插件,详见 [Plugin](#plugin) 节。
179
185
 
180
186
  ### Store 实例属性与方法
181
187
 
@@ -260,24 +266,29 @@ v0.4.1 新增 `init`,用于 store 创建后的一次性初始化。
260
266
  created() 开始
261
267
  └→ useStore(this)
262
268
  └→ createStoreInstance() ← state/source/getters/actions 就绪
269
+ └→ plugin.install() ← v0.5:plugin 安装($vm 尚未绑定)
263
270
  └→ bindTo(this) ← $vm 赋值
264
271
  └→ ★ init() ← $vm 可用,只执行一次
265
272
  └→ created() 剩余代码
266
273
  mounted()
267
274
  └→ ★ enter() ← DOM 就绪,每次可见都执行
275
+ └→ plugin.enter() ← v0.5:plugin enter 钩子
268
276
 
269
277
  --- keep-alive 切走 ---
270
278
  deactivated()
271
279
  └→ clearAllIntervals()
272
280
  └→ ★ leave()
281
+ └→ plugin.leave() ← v0.5:plugin leave 钩子
273
282
 
274
283
  --- keep-alive 切回 ---
275
284
  activated()
276
285
  └→ ★ enter() ← 重新开轮询、刷数据
286
+ └→ plugin.enter()
277
287
 
278
288
  --- 页面销毁 ---
279
289
  beforeDestroy()
280
290
  └→ ★ leave()(如果还没 leave)
291
+ └→ plugin.destroy() ← v0.5:plugin destroy 钩子
281
292
  └→ $destroy()
282
293
  ```
283
294
 
@@ -419,6 +430,128 @@ state: () => ({
419
430
  })
420
431
  ```
421
432
 
433
+ ## Plugin
434
+
435
+ *v0.5 新增。* Plugin 机制让外部库可以给 `definePageStore` options 增加**新字段**并消费它,同时挂钩 enter / leave / destroy 生命周期——而不需要修改 page-store 本身。
436
+
437
+ > 典型场景:`vue-page-runtime`(请求编排)、`vue-page-persist`(状态持久化)、devtools 扩展。
438
+
439
+ ### 协议
440
+
441
+ Plugin 是一个对象,包含 `name` 和 `install`:
442
+
443
+ ```js
444
+ {
445
+ name: 'tasks', // 同时作为 options 字段匹配键
446
+ install(store, fieldValue, { Vue }) { // fieldValue === options.tasks
447
+ // 初始化 plugin 自己的逻辑
448
+ return {
449
+ enter() { /* page enter 后调用 */ },
450
+ leave() { /* page leave 后调用 */ },
451
+ destroy() { /* store 销毁时调用 */ },
452
+ }
453
+ }
454
+ }
455
+ ```
456
+
457
+ - **匹配规则**:`options[plugin.name] !== undefined` 才会调用 `install`。没有声明字段的 store 完全不受影响。
458
+ - **install 时机**:store 创建末尾,state / getters / actions / $source / $setInterval / $emit 等全部就绪。`$vm` 此时**尚未**绑定。
459
+ - **返回值**:可选 `{ enter?, leave?, destroy? }`。不需要钩子可以不返回。
460
+
461
+ ### 注册
462
+
463
+ 全局注册一次即可:
464
+
465
+ ```js
466
+ // main.js
467
+ import { registerPlugin } from 'vue-page-store'
468
+ import taskPlugin from 'vue-page-runtime/plugin'
469
+
470
+ registerPlugin(taskPlugin)
471
+ ```
472
+
473
+ 之后正常写 store,声明插件字段:
474
+
475
+ ```js
476
+ import { definePageStore } from 'vue-page-store' // 入口不变
477
+
478
+ definePageStore('order', {
479
+ state: () => ({ /* ... */ }),
480
+
481
+ // page-store 不认识这个字段,但会递给注册过的 plugin
482
+ tasks: {
483
+ fetchUser: {
484
+ trigger: 'enter',
485
+ async run() { return api.getUser(this.$vm.$route.params.id) },
486
+ },
487
+ fetchOrders: {
488
+ deps: ['fetchUser'],
489
+ async run() { /* ... */ },
490
+ },
491
+ },
492
+ })
493
+ ```
494
+
495
+ ### 写一个 plugin
496
+
497
+ 最小示例——一个把 `persist` 字段声明持久化到 localStorage 的插件:
498
+
499
+ ```js
500
+ const persistPlugin = {
501
+ name: 'persist',
502
+
503
+ install(store, fieldValue /* options.persist */, { Vue }) {
504
+ const { key, paths } = fieldValue
505
+
506
+ // 恢复
507
+ try {
508
+ const saved = JSON.parse(localStorage.getItem(key) || '{}')
509
+ store.$patch(saved)
510
+ } catch (e) {}
511
+
512
+ // 持久化 —— 监听指定字段
513
+ const stopWatchers = paths.map(p =>
514
+ store._vm.$watch(
515
+ () => store[p],
516
+ (val) => {
517
+ const cur = JSON.parse(localStorage.getItem(key) || '{}')
518
+ cur[p] = val
519
+ localStorage.setItem(key, JSON.stringify(cur))
520
+ }
521
+ )
522
+ )
523
+
524
+ return {
525
+ destroy() {
526
+ stopWatchers.forEach(stop => stop())
527
+ }
528
+ }
529
+ }
530
+ }
531
+
532
+ registerPlugin(persistPlugin)
533
+ ```
534
+
535
+ 使用:
536
+
537
+ ```js
538
+ definePageStore('page', {
539
+ state: () => ({ keyword: '', filters: {} }),
540
+ persist: {
541
+ key: 'page:cache',
542
+ paths: ['keyword', 'filters']
543
+ }
544
+ })
545
+ ```
546
+
547
+ ### 注意事项
548
+
549
+ - **全局注册,影响所有 store**。plugin 只在对应 store 声明了 `options[plugin.name]` 时才激活,但注册本身是全局的。
550
+ - **同名 plugin 只能注册一次**,重复注册会被跳过并打印 warning。
551
+ - **install 返回的钩子会被按注册顺序依次调用**(FIFO)。
552
+ - **plugin 之间不通信**。如果两个 plugin 有依赖关系,应该合并成一个。
553
+ - **$vm 在 install 时为 null**。如果 plugin 需要组件实例,应在 `enter` 钩子里访问(此时 `$vm` 已绑定)。
554
+
422
555
  ## 实例模型:Singleton
423
556
 
424
557
  当前版本采用 **id → singleton** 模型:
@@ -471,17 +604,43 @@ actions: {
471
604
 
472
605
  ## 调试
473
606
 
474
- `storeRegistry` 是导出的 Map,可以在控制台直接查看:
607
+ ### `storeRegistry` —— 导出的 Map
608
+
609
+ `storeRegistry` 是导出的 Map,可以在代码里用于调试或自定义 devtools 集成:
475
610
 
476
611
  ```js
477
612
  import { storeRegistry } from 'vue-page-store'
478
613
 
479
- // 查看所有活跃 store
480
614
  storeRegistry.forEach((store, id) => {
481
615
  console.log(id, store.$status, store.$disposed)
482
616
  })
483
617
  ```
484
618
 
619
+ ### `window.__VUE_PAGE_STORE__` —— dev 自动挂载 *(v0.5 新增)*
620
+
621
+ 开发环境下(`process.env.NODE_ENV !== 'production'`)会自动挂到 `window.__VUE_PAGE_STORE__`,方便控制台访问。生产环境和 SSR 环境不会挂。
622
+
623
+ 控制台用法:
624
+
625
+ ```js
626
+ __VUE_PAGE_STORE__ // { registry, stores }
627
+ __VUE_PAGE_STORE__.stores // { orderList: {…}, userProfile: {…} }
628
+ __VUE_PAGE_STORE__.stores.orderList // ← 有属性自动补全
629
+ __VUE_PAGE_STORE__.stores.orderList.$source
630
+ __VUE_PAGE_STORE__.stores.orderList.$loading
631
+
632
+ // 原始 Map 也保留
633
+ __VUE_PAGE_STORE__.registry.forEach(...)
634
+ ```
635
+
636
+ - `registry`:导出的原始 Map,和 `import { storeRegistry }` 拿到的是同一个引用
637
+ - `stores`:getter,每次读取重建对象视图;销毁的 store 自动消失
638
+
639
+ **说明**:
640
+
641
+ - `__VUE_PAGE_STORE__` 是 dev-only 调试接口,shape 和键名可能在后续版本变化,**不要在生产代码里依赖**
642
+ - 微前端场景下,多个子应用都加载 vue-page-store 时,最后挂载的会覆盖前面的。如需共存,请退回手动挂载并用自己的命名
643
+
485
644
  ## 从 v0.3.x 升级
486
645
 
487
646
  ### Breaking Changes
@@ -536,11 +695,23 @@ v0.4.0 中:
536
695
  - `$setInterval()`:页面级 interval 托管
537
696
  - `$loading.xxx`:返回 Promise 的 action 自动追踪 loading
538
697
  - `$vm`:只读逃生口,可在 init / enter 中访问 `$route / $router`
698
+ - `registerPlugin()`:外部扩展机制(v0.5)
699
+
700
+ ## 从 v0.4.x 升级到 v0.5
701
+
702
+ v0.5 **完全向后兼容** v0.4.x:
703
+
704
+ - 所有 v0.4 的 API 行为不变
705
+ - 新增 `registerPlugin()` 导出,不注册 plugin 等同于 v0.4 行为
706
+ - options 现在允许包含插件声明的额外字段(如 `tasks`、`persist`)
707
+ - dev 环境自动挂 `window.__VUE_PAGE_STORE__`,方便控制台调试
708
+
709
+ 升级只需要改版本号,无需改代码。
539
710
 
540
711
  ## Roadmap
541
712
 
542
713
  - **Keyed instance** — `useStore(vm, scopeKey)` 支持同定义多实例
543
- - **Page cache strategy** — TTL、revalidate、stale-while-enter
714
+ - **Official plugins** — 随着 `vue-page-runtime` 等生态库成熟,补充第一方 plugin 文档
544
715
  - **More page runtime helpers** — 在不增加心智负担的前提下继续补页面层能力
545
716
 
546
717
  ## License
package/dist/index.cjs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * vue-page-store v0.4.1
2
+ * vue-page-store v0.5.0
3
3
  * (c) 2026 weijianjun
4
4
  * @license MIT
5
5
  */
@@ -7,16 +7,18 @@
7
7
 
8
8
  Object.defineProperty(exports, '__esModule', { value: true });
9
9
 
10
+ var Vue = require('vue');
11
+
10
12
  /*!
11
- * vue-page-store v0.4.1
13
+ * vue-page-store v0.5.0
12
14
  * (c) 2026 weijianjun
13
15
  * @license MIT
14
16
  */
15
17
  /**
16
- * vue-page-store 0.4.1 — Vue 2.6 Page Scope Runtime
18
+ * vue-page-store 0.5.0 — Vue 2.6 Page Scope Runtime
17
19
  *
18
20
  * 页面级作用域运行时容器:
19
- * source · state · getters · actions · watch · init/enter/leave · $setInterval · event bus
21
+ * source · state · getters · actions · watch · init/enter/leave · $setInterval · event bus · plugin
20
22
  *
21
23
  * v0.4 新增:
22
24
  * source → 页面输入 / 原始返回,和业务 state 分开
@@ -27,12 +29,13 @@ Object.defineProperty(exports, '__esModule', { value: true });
27
29
  * v0.4.1 新增:
28
30
  * init → store 创建后一次性初始化钩子,$vm 已可用
29
31
  *
32
+ * v0.5 新增:
33
+ * plugin → registerPlugin 注册外部扩展,声明字段 + 生命周期钩子
34
+ *
30
35
  * @author weijianjun
31
36
  * @license MIT
32
37
  */
33
38
 
34
- // Store 注册表(导出供调试 / devtools 使用)
35
- var storeRegistry = new Map();
36
39
 
37
40
  // ====== dev-only warning ======
38
41
  var isDev = typeof process !== 'undefined'
@@ -45,6 +48,47 @@ function warn(msg) {
45
48
  }
46
49
  }
47
50
 
51
+ // Store 注册表(导出供调试 / devtools 使用)
52
+ var storeRegistry = new Map();
53
+
54
+ // v0.5 新增:dev 环境自动挂到 window,方便控制台调试
55
+ if (isDev && typeof window !== 'undefined') {
56
+ window.__VUE_PAGE_STORE__ = {
57
+ registry: storeRegistry,
58
+ get stores() {
59
+ var result = {};
60
+ storeRegistry.forEach(function (s, id) { result[id] = s; });
61
+ return result;
62
+ },
63
+ };
64
+ }
65
+
66
+ // ====== v0.5 新增:plugin 机制 ======
67
+ var _plugins = [];
68
+
69
+ /**
70
+ * 注册全局 plugin
71
+ *
72
+ * plugin.name 同时作为 options 字段匹配键:
73
+ * 当 definePageStore options 中存在 options[plugin.name] 时,
74
+ * page-store 会调用 plugin.install(store, fieldValue, { Vue })
75
+ *
76
+ * install 可返回 { enter, leave, destroy } 生命周期钩子
77
+ */
78
+ function registerPlugin(plugin) {
79
+ if (!plugin || typeof plugin.name !== 'string') {
80
+ throw new Error('[vue-page-store] plugin 需要一个 name 属性');
81
+ }
82
+ if (typeof plugin.install !== 'function') {
83
+ throw new Error('[vue-page-store] plugin "' + plugin.name + '" 需要一个 install 方法');
84
+ }
85
+ if (_plugins.some(function (p) { return p.name === plugin.name; })) {
86
+ warn('plugin "' + plugin.name + '" 已注册,跳过重复注册');
87
+ return;
88
+ }
89
+ _plugins.push(plugin);
90
+ }
91
+
48
92
  function createStoreInstance(Vue, id, options) {
49
93
  var initialState = options.state();
50
94
 
@@ -58,6 +102,9 @@ function createStoreInstance(Vue, id, options) {
58
102
  var enterHook = typeof options.enter === 'function' ? options.enter : null;
59
103
  var leaveHook = typeof options.leave === 'function' ? options.leave : null;
60
104
 
105
+ // ====== v0.5 新增:plugin hooks 闭包存储(由 install 填充) ======
106
+ var _pluginHooks = [];
107
+
61
108
  // --- 用一个隐藏的 Vue 实例承载响应式 state + source + loading + computed getters ---
62
109
  var computedDefs = {};
63
110
  var store = { $disposed: false };
@@ -325,6 +372,8 @@ function createStoreInstance(Vue, id, options) {
325
372
  enterHook.call(store);
326
373
  }
327
374
  store.$emit('page:enter');
375
+ // v0.5: plugin enter hooks
376
+ _pluginHooks.forEach(function (h) { if (h.enter) h.enter(); });
328
377
  }
329
378
 
330
379
  function runLeave() {
@@ -337,6 +386,8 @@ function createStoreInstance(Vue, id, options) {
337
386
  leaveHook.call(store);
338
387
  }
339
388
  store.$emit('page:leave');
389
+ // v0.5: plugin leave hooks
390
+ _pluginHooks.forEach(function (h) { if (h.leave) h.leave(); });
340
391
  }
341
392
 
342
393
  // ====== bindTo 去重标记 ======
@@ -403,6 +454,7 @@ function createStoreInstance(Vue, id, options) {
403
454
  * 销毁 store
404
455
  *
405
456
  * v0.4 变更:兜底清理 interval
457
+ * v0.5 变更:调用 plugin destroy 钩子
406
458
  */
407
459
  store.$destroy = function () {
408
460
  if (store.$disposed) return;
@@ -413,6 +465,9 @@ function createStoreInstance(Vue, id, options) {
413
465
  // 兜底清理 interval(正常流程 leave 已经清过,这里防遗漏)
414
466
  clearAllIntervals();
415
467
 
468
+ // v0.5: plugin destroy hooks
469
+ _pluginHooks.forEach(function (h) { if (h.destroy) h.destroy(); });
470
+
416
471
  store.$disposed = true;
417
472
  Object.keys(_listeners).forEach(function (key) { delete _listeners[key]; });
418
473
  vm.$destroy();
@@ -421,6 +476,15 @@ function createStoreInstance(Vue, id, options) {
421
476
 
422
477
  store._vm = vm;
423
478
 
479
+ // ====== v0.5 新增:plugin 安装 ======
480
+ // 放在最后,此时 store 的 state/getters/actions/$源数据/$setInterval 等全部就绪
481
+ _plugins.forEach(function (plugin) {
482
+ var fieldValue = options[plugin.name];
483
+ if (fieldValue === undefined) return;
484
+ var hooks = plugin.install(store, fieldValue, { Vue: Vue });
485
+ if (hooks) _pluginHooks.push(hooks);
486
+ });
487
+
424
488
  return store;
425
489
  }
426
490
 
@@ -433,6 +497,8 @@ function createStoreInstance(Vue, id, options) {
433
497
  * - actions 中的 async 函数自动追踪 $loading
434
498
  * v0.4.1 变更:
435
499
  * - options 新增 init(bindTo 之后一次性调用)
500
+ * v0.5 变更:
501
+ * - options 中注册过的 plugin.name 字段会被交给对应 plugin 处理
436
502
  */
437
503
  function definePageStore(id, options) {
438
504
  // 入参校验
@@ -443,7 +509,7 @@ function definePageStore(id, options) {
443
509
  throw new Error('[vue-page-store] definePageStore("' + id + '") 需要 state 为函数');
444
510
  }
445
511
 
446
- var _Vue = null;
512
+ var _Vue = Vue;
447
513
 
448
514
  return function useStore(componentVm) {
449
515
  if (storeRegistry.has(id)) {
@@ -452,17 +518,6 @@ function definePageStore(id, options) {
452
518
  return existing;
453
519
  }
454
520
 
455
- if (!_Vue) {
456
- try {
457
- _Vue = require('vue');
458
- if (_Vue.default) _Vue = _Vue.default;
459
- } catch (e) {
460
- throw new Error(
461
- '[vue-page-store] 无法自动获取 Vue,请确保 vue 已安装'
462
- );
463
- }
464
- }
465
-
466
521
  var store = createStoreInstance(_Vue, id, options);
467
522
  storeRegistry.set(id, store);
468
523
  if (componentVm) store.bindTo(componentVm);
@@ -476,8 +531,13 @@ function definePageStore(id, options) {
476
531
  };
477
532
  }
478
533
 
479
- var index = { definePageStore: definePageStore, storeRegistry: storeRegistry };
534
+ var index = {
535
+ definePageStore: definePageStore,
536
+ registerPlugin: registerPlugin,
537
+ storeRegistry: storeRegistry
538
+ };
480
539
 
481
540
  exports.default = index;
482
541
  exports.definePageStore = definePageStore;
542
+ exports.registerPlugin = registerPlugin;
483
543
  exports.storeRegistry = storeRegistry;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * vue-page-store v0.4.1 - TypeScript 类型定义
2
+ * vue-page-store v0.5.0 - TypeScript 类型定义
3
3
  *
4
4
  * Page Scope Runtime for Vue 2.6
5
5
  */
@@ -68,6 +68,9 @@ export interface StoreOptions<
68
68
  * interval 在 leave 前已自动清理
69
69
  */
70
70
  leave?: (this: PageStore<S, Src>) => void;
71
+
72
+ /** 允许 plugin 声明的额外字段(v0.5 新增) */
73
+ [key: string]: any;
71
74
  }
72
75
 
73
76
  export interface Store<
@@ -138,6 +141,8 @@ export type PageStore<
138
141
  * - async action 自动追踪 $loading
139
142
  * v0.4.1 变更:
140
143
  * - options 新增 init(bindTo 之后一次性调用)
144
+ * v0.5 变更:
145
+ * - options 支持 plugin 声明的自定义字段
141
146
  */
142
147
  export declare function definePageStore<
143
148
  S extends Record<string, any>,
@@ -148,4 +153,44 @@ export declare function definePageStore<
148
153
  ): (componentVm?: Vue2ComponentInstance) => PageStore<S, Src>;
149
154
 
150
155
  /** Store 注册表 */
151
- export declare const storeRegistry: Map<string, PageStore<any, any>>;
156
+ export declare const storeRegistry: Map<string, PageStore<any, any>>;
157
+
158
+ // ====== v0.5 新增:plugin 类型 ======
159
+
160
+ /**
161
+ * Plugin install 返回的生命周期钩子(v0.5 新增)
162
+ * page-store 会在对应时机调用
163
+ */
164
+ export interface PluginHooks {
165
+ /** 每次 page enter 之后调用(用户 enter hook + page:enter event 之后) */
166
+ enter?: () => void;
167
+ /** 每次 page leave 之后调用(用户 leave hook + page:leave event 之后) */
168
+ leave?: () => void;
169
+ /** store $destroy 时调用,用于释放 plugin 自己的资源 */
170
+ destroy?: () => void;
171
+ }
172
+
173
+ /**
174
+ * Plugin 定义(v0.5 新增)
175
+ *
176
+ * plugin.name 同时作为字段名:
177
+ * 当 definePageStore options 中存在 options[name] 时,
178
+ * page-store 会调用 install(store, fieldValue, { Vue })
179
+ *
180
+ * install 在 store 创建末尾、bindTo 之前执行,此时 state/getters/actions/$source/$setInterval 已就绪
181
+ */
182
+ export interface PageStorePlugin {
183
+ name: string;
184
+ install(
185
+ store: PageStore<any, any>,
186
+ fieldValue: any,
187
+ context: { Vue: any }
188
+ ): PluginHooks | void;
189
+ }
190
+
191
+ /**
192
+ * 注册全局 plugin(v0.5 新增)
193
+ *
194
+ * 同名 plugin 重复注册会被跳过并打印 warning
195
+ */
196
+ export declare function registerPlugin(plugin: PageStorePlugin): void;
package/dist/index.esm.js CHANGED
@@ -1,18 +1,20 @@
1
1
  /*!
2
- * vue-page-store v0.4.1
2
+ * vue-page-store v0.5.0
3
3
  * (c) 2026 weijianjun
4
4
  * @license MIT
5
5
  */
6
+ import Vue from 'vue';
7
+
6
8
  /*!
7
- * vue-page-store v0.4.1
9
+ * vue-page-store v0.5.0
8
10
  * (c) 2026 weijianjun
9
11
  * @license MIT
10
12
  */
11
13
  /**
12
- * vue-page-store 0.4.1 — Vue 2.6 Page Scope Runtime
14
+ * vue-page-store 0.5.0 — Vue 2.6 Page Scope Runtime
13
15
  *
14
16
  * 页面级作用域运行时容器:
15
- * source · state · getters · actions · watch · init/enter/leave · $setInterval · event bus
17
+ * source · state · getters · actions · watch · init/enter/leave · $setInterval · event bus · plugin
16
18
  *
17
19
  * v0.4 新增:
18
20
  * source → 页面输入 / 原始返回,和业务 state 分开
@@ -23,12 +25,13 @@
23
25
  * v0.4.1 新增:
24
26
  * init → store 创建后一次性初始化钩子,$vm 已可用
25
27
  *
28
+ * v0.5 新增:
29
+ * plugin → registerPlugin 注册外部扩展,声明字段 + 生命周期钩子
30
+ *
26
31
  * @author weijianjun
27
32
  * @license MIT
28
33
  */
29
34
 
30
- // Store 注册表(导出供调试 / devtools 使用)
31
- var storeRegistry = new Map();
32
35
 
33
36
  // ====== dev-only warning ======
34
37
  var isDev = typeof process !== 'undefined'
@@ -41,6 +44,47 @@ function warn(msg) {
41
44
  }
42
45
  }
43
46
 
47
+ // Store 注册表(导出供调试 / devtools 使用)
48
+ var storeRegistry = new Map();
49
+
50
+ // v0.5 新增:dev 环境自动挂到 window,方便控制台调试
51
+ if (isDev && typeof window !== 'undefined') {
52
+ window.__VUE_PAGE_STORE__ = {
53
+ registry: storeRegistry,
54
+ get stores() {
55
+ var result = {};
56
+ storeRegistry.forEach(function (s, id) { result[id] = s; });
57
+ return result;
58
+ },
59
+ };
60
+ }
61
+
62
+ // ====== v0.5 新增:plugin 机制 ======
63
+ var _plugins = [];
64
+
65
+ /**
66
+ * 注册全局 plugin
67
+ *
68
+ * plugin.name 同时作为 options 字段匹配键:
69
+ * 当 definePageStore options 中存在 options[plugin.name] 时,
70
+ * page-store 会调用 plugin.install(store, fieldValue, { Vue })
71
+ *
72
+ * install 可返回 { enter, leave, destroy } 生命周期钩子
73
+ */
74
+ function registerPlugin(plugin) {
75
+ if (!plugin || typeof plugin.name !== 'string') {
76
+ throw new Error('[vue-page-store] plugin 需要一个 name 属性');
77
+ }
78
+ if (typeof plugin.install !== 'function') {
79
+ throw new Error('[vue-page-store] plugin "' + plugin.name + '" 需要一个 install 方法');
80
+ }
81
+ if (_plugins.some(function (p) { return p.name === plugin.name; })) {
82
+ warn('plugin "' + plugin.name + '" 已注册,跳过重复注册');
83
+ return;
84
+ }
85
+ _plugins.push(plugin);
86
+ }
87
+
44
88
  function createStoreInstance(Vue, id, options) {
45
89
  var initialState = options.state();
46
90
 
@@ -54,6 +98,9 @@ function createStoreInstance(Vue, id, options) {
54
98
  var enterHook = typeof options.enter === 'function' ? options.enter : null;
55
99
  var leaveHook = typeof options.leave === 'function' ? options.leave : null;
56
100
 
101
+ // ====== v0.5 新增:plugin hooks 闭包存储(由 install 填充) ======
102
+ var _pluginHooks = [];
103
+
57
104
  // --- 用一个隐藏的 Vue 实例承载响应式 state + source + loading + computed getters ---
58
105
  var computedDefs = {};
59
106
  var store = { $disposed: false };
@@ -321,6 +368,8 @@ function createStoreInstance(Vue, id, options) {
321
368
  enterHook.call(store);
322
369
  }
323
370
  store.$emit('page:enter');
371
+ // v0.5: plugin enter hooks
372
+ _pluginHooks.forEach(function (h) { if (h.enter) h.enter(); });
324
373
  }
325
374
 
326
375
  function runLeave() {
@@ -333,6 +382,8 @@ function createStoreInstance(Vue, id, options) {
333
382
  leaveHook.call(store);
334
383
  }
335
384
  store.$emit('page:leave');
385
+ // v0.5: plugin leave hooks
386
+ _pluginHooks.forEach(function (h) { if (h.leave) h.leave(); });
336
387
  }
337
388
 
338
389
  // ====== bindTo 去重标记 ======
@@ -399,6 +450,7 @@ function createStoreInstance(Vue, id, options) {
399
450
  * 销毁 store
400
451
  *
401
452
  * v0.4 变更:兜底清理 interval
453
+ * v0.5 变更:调用 plugin destroy 钩子
402
454
  */
403
455
  store.$destroy = function () {
404
456
  if (store.$disposed) return;
@@ -409,6 +461,9 @@ function createStoreInstance(Vue, id, options) {
409
461
  // 兜底清理 interval(正常流程 leave 已经清过,这里防遗漏)
410
462
  clearAllIntervals();
411
463
 
464
+ // v0.5: plugin destroy hooks
465
+ _pluginHooks.forEach(function (h) { if (h.destroy) h.destroy(); });
466
+
412
467
  store.$disposed = true;
413
468
  Object.keys(_listeners).forEach(function (key) { delete _listeners[key]; });
414
469
  vm.$destroy();
@@ -417,6 +472,15 @@ function createStoreInstance(Vue, id, options) {
417
472
 
418
473
  store._vm = vm;
419
474
 
475
+ // ====== v0.5 新增:plugin 安装 ======
476
+ // 放在最后,此时 store 的 state/getters/actions/$源数据/$setInterval 等全部就绪
477
+ _plugins.forEach(function (plugin) {
478
+ var fieldValue = options[plugin.name];
479
+ if (fieldValue === undefined) return;
480
+ var hooks = plugin.install(store, fieldValue, { Vue: Vue });
481
+ if (hooks) _pluginHooks.push(hooks);
482
+ });
483
+
420
484
  return store;
421
485
  }
422
486
 
@@ -429,6 +493,8 @@ function createStoreInstance(Vue, id, options) {
429
493
  * - actions 中的 async 函数自动追踪 $loading
430
494
  * v0.4.1 变更:
431
495
  * - options 新增 init(bindTo 之后一次性调用)
496
+ * v0.5 变更:
497
+ * - options 中注册过的 plugin.name 字段会被交给对应 plugin 处理
432
498
  */
433
499
  function definePageStore(id, options) {
434
500
  // 入参校验
@@ -439,7 +505,7 @@ function definePageStore(id, options) {
439
505
  throw new Error('[vue-page-store] definePageStore("' + id + '") 需要 state 为函数');
440
506
  }
441
507
 
442
- var _Vue = null;
508
+ var _Vue = Vue;
443
509
 
444
510
  return function useStore(componentVm) {
445
511
  if (storeRegistry.has(id)) {
@@ -448,17 +514,6 @@ function definePageStore(id, options) {
448
514
  return existing;
449
515
  }
450
516
 
451
- if (!_Vue) {
452
- try {
453
- _Vue = require('vue');
454
- if (_Vue.default) _Vue = _Vue.default;
455
- } catch (e) {
456
- throw new Error(
457
- '[vue-page-store] 无法自动获取 Vue,请确保 vue 已安装'
458
- );
459
- }
460
- }
461
-
462
517
  var store = createStoreInstance(_Vue, id, options);
463
518
  storeRegistry.set(id, store);
464
519
  if (componentVm) store.bindTo(componentVm);
@@ -472,6 +527,10 @@ function definePageStore(id, options) {
472
527
  };
473
528
  }
474
529
 
475
- var index = { definePageStore: definePageStore, storeRegistry: storeRegistry };
530
+ var index = {
531
+ definePageStore: definePageStore,
532
+ registerPlugin: registerPlugin,
533
+ storeRegistry: storeRegistry
534
+ };
476
535
 
477
- export { index as default, definePageStore, storeRegistry };
536
+ export { index as default, definePageStore, registerPlugin, storeRegistry };
package/dist/index.umd.js CHANGED
@@ -1,24 +1,24 @@
1
1
  /*!
2
- * vue-page-store v0.4.1
2
+ * vue-page-store v0.5.0
3
3
  * (c) 2026 weijianjun
4
4
  * @license MIT
5
5
  */
6
6
  (function (global, factory) {
7
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
8
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
9
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.VuePageStore = {}));
10
- })(this, (function (exports) { 'use strict';
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue')) :
8
+ typeof define === 'function' && define.amd ? define(['exports', 'vue'], factory) :
9
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.VuePageStore = {}, global.Vue));
10
+ })(this, (function (exports, Vue) { 'use strict';
11
11
 
12
12
  /*!
13
- * vue-page-store v0.4.1
13
+ * vue-page-store v0.5.0
14
14
  * (c) 2026 weijianjun
15
15
  * @license MIT
16
16
  */
17
17
  /**
18
- * vue-page-store 0.4.1 — Vue 2.6 Page Scope Runtime
18
+ * vue-page-store 0.5.0 — Vue 2.6 Page Scope Runtime
19
19
  *
20
20
  * 页面级作用域运行时容器:
21
- * source · state · getters · actions · watch · init/enter/leave · $setInterval · event bus
21
+ * source · state · getters · actions · watch · init/enter/leave · $setInterval · event bus · plugin
22
22
  *
23
23
  * v0.4 新增:
24
24
  * source → 页面输入 / 原始返回,和业务 state 分开
@@ -29,12 +29,13 @@
29
29
  * v0.4.1 新增:
30
30
  * init → store 创建后一次性初始化钩子,$vm 已可用
31
31
  *
32
+ * v0.5 新增:
33
+ * plugin → registerPlugin 注册外部扩展,声明字段 + 生命周期钩子
34
+ *
32
35
  * @author weijianjun
33
36
  * @license MIT
34
37
  */
35
38
 
36
- // Store 注册表(导出供调试 / devtools 使用)
37
- var storeRegistry = new Map();
38
39
 
39
40
  // ====== dev-only warning ======
40
41
  var isDev = typeof process !== 'undefined'
@@ -47,6 +48,47 @@
47
48
  }
48
49
  }
49
50
 
51
+ // Store 注册表(导出供调试 / devtools 使用)
52
+ var storeRegistry = new Map();
53
+
54
+ // v0.5 新增:dev 环境自动挂到 window,方便控制台调试
55
+ if (isDev && typeof window !== 'undefined') {
56
+ window.__VUE_PAGE_STORE__ = {
57
+ registry: storeRegistry,
58
+ get stores() {
59
+ var result = {};
60
+ storeRegistry.forEach(function (s, id) { result[id] = s; });
61
+ return result;
62
+ },
63
+ };
64
+ }
65
+
66
+ // ====== v0.5 新增:plugin 机制 ======
67
+ var _plugins = [];
68
+
69
+ /**
70
+ * 注册全局 plugin
71
+ *
72
+ * plugin.name 同时作为 options 字段匹配键:
73
+ * 当 definePageStore options 中存在 options[plugin.name] 时,
74
+ * page-store 会调用 plugin.install(store, fieldValue, { Vue })
75
+ *
76
+ * install 可返回 { enter, leave, destroy } 生命周期钩子
77
+ */
78
+ function registerPlugin(plugin) {
79
+ if (!plugin || typeof plugin.name !== 'string') {
80
+ throw new Error('[vue-page-store] plugin 需要一个 name 属性');
81
+ }
82
+ if (typeof plugin.install !== 'function') {
83
+ throw new Error('[vue-page-store] plugin "' + plugin.name + '" 需要一个 install 方法');
84
+ }
85
+ if (_plugins.some(function (p) { return p.name === plugin.name; })) {
86
+ warn('plugin "' + plugin.name + '" 已注册,跳过重复注册');
87
+ return;
88
+ }
89
+ _plugins.push(plugin);
90
+ }
91
+
50
92
  function createStoreInstance(Vue, id, options) {
51
93
  var initialState = options.state();
52
94
 
@@ -60,6 +102,9 @@
60
102
  var enterHook = typeof options.enter === 'function' ? options.enter : null;
61
103
  var leaveHook = typeof options.leave === 'function' ? options.leave : null;
62
104
 
105
+ // ====== v0.5 新增:plugin hooks 闭包存储(由 install 填充) ======
106
+ var _pluginHooks = [];
107
+
63
108
  // --- 用一个隐藏的 Vue 实例承载响应式 state + source + loading + computed getters ---
64
109
  var computedDefs = {};
65
110
  var store = { $disposed: false };
@@ -327,6 +372,8 @@
327
372
  enterHook.call(store);
328
373
  }
329
374
  store.$emit('page:enter');
375
+ // v0.5: plugin enter hooks
376
+ _pluginHooks.forEach(function (h) { if (h.enter) h.enter(); });
330
377
  }
331
378
 
332
379
  function runLeave() {
@@ -339,6 +386,8 @@
339
386
  leaveHook.call(store);
340
387
  }
341
388
  store.$emit('page:leave');
389
+ // v0.5: plugin leave hooks
390
+ _pluginHooks.forEach(function (h) { if (h.leave) h.leave(); });
342
391
  }
343
392
 
344
393
  // ====== bindTo 去重标记 ======
@@ -405,6 +454,7 @@
405
454
  * 销毁 store
406
455
  *
407
456
  * v0.4 变更:兜底清理 interval
457
+ * v0.5 变更:调用 plugin destroy 钩子
408
458
  */
409
459
  store.$destroy = function () {
410
460
  if (store.$disposed) return;
@@ -415,6 +465,9 @@
415
465
  // 兜底清理 interval(正常流程 leave 已经清过,这里防遗漏)
416
466
  clearAllIntervals();
417
467
 
468
+ // v0.5: plugin destroy hooks
469
+ _pluginHooks.forEach(function (h) { if (h.destroy) h.destroy(); });
470
+
418
471
  store.$disposed = true;
419
472
  Object.keys(_listeners).forEach(function (key) { delete _listeners[key]; });
420
473
  vm.$destroy();
@@ -423,6 +476,15 @@
423
476
 
424
477
  store._vm = vm;
425
478
 
479
+ // ====== v0.5 新增:plugin 安装 ======
480
+ // 放在最后,此时 store 的 state/getters/actions/$源数据/$setInterval 等全部就绪
481
+ _plugins.forEach(function (plugin) {
482
+ var fieldValue = options[plugin.name];
483
+ if (fieldValue === undefined) return;
484
+ var hooks = plugin.install(store, fieldValue, { Vue: Vue });
485
+ if (hooks) _pluginHooks.push(hooks);
486
+ });
487
+
426
488
  return store;
427
489
  }
428
490
 
@@ -435,6 +497,8 @@
435
497
  * - actions 中的 async 函数自动追踪 $loading
436
498
  * v0.4.1 变更:
437
499
  * - options 新增 init(bindTo 之后一次性调用)
500
+ * v0.5 变更:
501
+ * - options 中注册过的 plugin.name 字段会被交给对应 plugin 处理
438
502
  */
439
503
  function definePageStore(id, options) {
440
504
  // 入参校验
@@ -445,7 +509,7 @@
445
509
  throw new Error('[vue-page-store] definePageStore("' + id + '") 需要 state 为函数');
446
510
  }
447
511
 
448
- var _Vue = null;
512
+ var _Vue = Vue;
449
513
 
450
514
  return function useStore(componentVm) {
451
515
  if (storeRegistry.has(id)) {
@@ -454,17 +518,6 @@
454
518
  return existing;
455
519
  }
456
520
 
457
- if (!_Vue) {
458
- try {
459
- _Vue = require('vue');
460
- if (_Vue.default) _Vue = _Vue.default;
461
- } catch (e) {
462
- throw new Error(
463
- '[vue-page-store] 无法自动获取 Vue,请确保 vue 已安装'
464
- );
465
- }
466
- }
467
-
468
521
  var store = createStoreInstance(_Vue, id, options);
469
522
  storeRegistry.set(id, store);
470
523
  if (componentVm) store.bindTo(componentVm);
@@ -478,10 +531,15 @@
478
531
  };
479
532
  }
480
533
 
481
- var index = { definePageStore: definePageStore, storeRegistry: storeRegistry };
534
+ var index = {
535
+ definePageStore: definePageStore,
536
+ registerPlugin: registerPlugin,
537
+ storeRegistry: storeRegistry
538
+ };
482
539
 
483
540
  exports.default = index;
484
541
  exports.definePageStore = definePageStore;
542
+ exports.registerPlugin = registerPlugin;
485
543
  exports.storeRegistry = storeRegistry;
486
544
 
487
545
  Object.defineProperty(exports, '__esModule', { value: true });
@@ -1,19 +1,19 @@
1
1
  /*!
2
- * vue-page-store v0.4.1
2
+ * vue-page-store v0.5.0
3
3
  * (c) 2026 weijianjun
4
4
  * @license MIT
5
5
  */
6
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).VuePageStore={})}(this,function(e){"use strict";
6
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("vue")):"function"==typeof define&&define.amd?define(["exports","vue"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).VuePageStore={},e.Vue)}(this,function(e,t){"use strict";
7
7
  /*!
8
- * vue-page-store v0.4.1
8
+ * vue-page-store v0.5.0
9
9
  * (c) 2026 weijianjun
10
10
  * @license MIT
11
11
  */
12
12
  /**
13
- * vue-page-store 0.4.1 — Vue 2.6 Page Scope Runtime
13
+ * vue-page-store 0.5.0 — Vue 2.6 Page Scope Runtime
14
14
  *
15
15
  * 页面级作用域运行时容器:
16
- * source · state · getters · actions · watch · init/enter/leave · $setInterval · event bus
16
+ * source · state · getters · actions · watch · init/enter/leave · $setInterval · event bus · plugin
17
17
  *
18
18
  * v0.4 新增:
19
19
  * source → 页面输入 / 原始返回,和业务 state 分开
@@ -24,6 +24,9 @@
24
24
  * v0.4.1 新增:
25
25
  * init → store 创建后一次性初始化钩子,$vm 已可用
26
26
  *
27
+ * v0.5 新增:
28
+ * plugin → registerPlugin 注册外部扩展,声明字段 + 生命周期钩子
29
+ *
27
30
  * @author weijianjun
28
31
  * @license MIT
29
- */var t=new Map,n="undefined"!=typeof process&&process.env&&"production"!==process.env.NODE_ENV;function o(e){n&&console.warn("[vue-page-store] "+e)}function r(e,n,r){var i=r.state(),c="function"==typeof r.source?r.source():{},u=r.getters||{},f=r.actions||{},a="function"==typeof r.enter?r.enter:null,s="function"==typeof r.leave?r.leave:null,d={},l={$disposed:!1};Object.keys(u).forEach(function(e){d[e]=function(){return u[e].call(l)}});var p=new e({data:function(){return{$$state:i,$$source:c,$$loading:{},$$status:{mounted:!1,active:!1}}},computed:d}),v=p.$data.$$state,$=p.$data.$$source,h=p.$data.$$loading,y=p.$data.$$status;Object.keys(i).forEach(function(e){Object.defineProperty(l,e,{enumerable:!0,configurable:!0,get:function(){return v[e]},set:function(t){l.$disposed?o('store "'+n+'" 已销毁,忽略对 "'+e+'" 的写入'):v[e]=t}})}),l.$source=$,l.$loading=h,Object.keys(u).forEach(function(e){Object.defineProperty(l,e,{enumerable:!0,get:function(){return p[e]}})});var b={};function g(t){b[t]--,b[t]<=0&&(b[t]=0,e.set(h,t,!1))}Object.keys(f).forEach(function(t){var n=f[t].bind(l);l[t]=function(){var o=n.apply(null,arguments);o&&"function"==typeof o.then&&(b[t]||(b[t]=0),b[t]++,e.set(h,t,!0),Promise.resolve(o).then(function(){g(t)},function(){g(t)}));return o}});var m=r.watch||{};Object.entries(m).forEach(function(e){var t,r,i=e[0],c=e[1];if("function"==typeof c)t=c,r={};else if(t=c.handler,r={},c.deep&&(r.deep=!0),c.immediate&&(r.immediate=!0),!t)return void o('watch "'+i+'" in store "'+n+'" 缺少 handler,该 watcher 将被跳过');p.$watch(function(){return i.split(".").reduce(function(e,t){return e&&e[t]},l)},t.bind(l),r)}),l.$state=v,l.$status=y,l.$id=n;var O=null;Object.defineProperty(l,"$vm",{enumerable:!0,configurable:!1,get:function(){return O},set:function(){o("$vm 是只读属性,不允许业务侧重写")}}),l.$patch=function(t){if(l.$disposed)o('store "'+n+'" 已销毁,忽略 $patch 操作');else{var r="function"==typeof t?t(v):t;Object.keys(r).forEach(function(t){e.set(v,t,r[t])})}},l.$reset=function(){var t=r.state();Object.keys(t).forEach(function(n){e.set(v,n,t[n])}),Object.keys(v).forEach(function(n){n in t||e.delete(v,n)});var n="function"==typeof r.source?r.source():{};Object.keys(n).forEach(function(t){e.set($,t,n[t])}),Object.keys($).forEach(function(t){t in n||e.delete($,t)})};var E={};l.$emit=function(e,t){var n=E[e];n&&n.slice().forEach(function(e){e(t)})},l.$on=function(e,t){return E[e]||(E[e]=[]),E[e].push(t),function(){if(E[e]){var n=E[e].indexOf(t);n>-1&&E[e].splice(n,1)}}},l.$off=function(e,t){if(E[e])if(t){var n=E[e].indexOf(t);n>-1&&E[e].splice(n,1)}else delete E[e]};var j=[];function k(){j.forEach(function(e){e.stopped||(clearInterval(e.id),e.stopped=!0)}),j.length=0}l.$setInterval=function(e,t){var n={id:setInterval(e,t),stopped:!1};j.push(n);return function(){if(!n.stopped){clearInterval(n.id),n.stopped=!0;var e=j.indexOf(n);e>-1&&j.splice(e,1)}}};var w=!1;function P(){w||(w=!0,y.mounted=!0,y.active=!0,a&&a.call(l),l.$emit("page:enter"))}function S(){w&&(k(),w=!1,y.active=!1,s&&s.call(l),l.$emit("page:leave"))}var x="undefined"!=typeof WeakSet?new WeakSet:null,_=x?null:[];return l.bindTo=function(e){return l.$disposed||function(e){return x?x.has(e):_.indexOf(e)>-1}(e)||(function(e){x?x.add(e):_.push(e)}(e),O=e,(e._provided||(e._provided={})).pageStore=l,e.$on("hook:mounted",function(){P()}),e.$on("hook:activated",function(){P()}),e.$on("hook:deactivated",function(){S()}),e.$on("hook:beforeDestroy",function(){S(),l.$destroy()})),l},l.$destroy=function(){l.$disposed||(y.mounted=!1,y.active=!1,k(),l.$disposed=!0,Object.keys(E).forEach(function(e){delete E[e]}),p.$destroy(),t.delete(n))},l._vm=p,l}function i(e,n){if(!e||"string"!=typeof e)throw new Error("[vue-page-store] definePageStore 需要一个非空字符串作为 id");if(!n||"function"!=typeof n.state)throw new Error('[vue-page-store] definePageStore("'+e+'") 需要 state 为函数');var o=null;return function(i){if(t.has(e)){var c=t.get(e);return i&&c.bindTo(i),c}if(!o)try{(o=require("vue")).default&&(o=o.default)}catch(e){throw new Error("[vue-page-store] 无法自动获取 Vue,请确保 vue 已安装")}var u=r(o,e,n);return t.set(e,u),i&&u.bindTo(i),"function"==typeof n.init&&n.init.call(u),u}}var c={definePageStore:i,storeRegistry:t};e.default=c,e.definePageStore=i,e.storeRegistry=t,Object.defineProperty(e,"__esModule",{value:!0})});
32
+ */var n="undefined"!=typeof process&&process.env&&"production"!==process.env.NODE_ENV;function o(e){n&&console.warn("[vue-page-store] "+e)}var r=new Map;n&&"undefined"!=typeof window&&(window.__VUE_PAGE_STORE__={registry:r,get stores(){var e={};return r.forEach(function(t,n){e[n]=t}),e}});var i=[];function u(e){if(!e||"string"!=typeof e.name)throw new Error("[vue-page-store] plugin 需要一个 name 属性");if("function"!=typeof e.install)throw new Error('[vue-page-store] plugin "'+e.name+'" 需要一个 install 方法');i.some(function(t){return t.name===e.name})?o('plugin "'+e.name+'" 已注册,跳过重复注册'):i.push(e)}function a(e,t,n){var u=n.state(),a="function"==typeof n.source?n.source():{},f=n.getters||{},c=n.actions||{},s="function"==typeof n.enter?n.enter:null,d="function"==typeof n.leave?n.leave:null,l=[],p={},v={$disposed:!1};Object.keys(f).forEach(function(e){p[e]=function(){return f[e].call(v)}});var $=new e({data:function(){return{$$state:u,$$source:a,$$loading:{},$$status:{mounted:!1,active:!1}}},computed:p}),h=$.$data.$$state,y=$.$data.$$source,g=$.$data.$$loading,b=$.$data.$$status;Object.keys(u).forEach(function(e){Object.defineProperty(v,e,{enumerable:!0,configurable:!0,get:function(){return h[e]},set:function(n){v.$disposed?o('store "'+t+'" 已销毁,忽略对 "'+e+'" 的写入'):h[e]=n}})}),v.$source=y,v.$loading=g,Object.keys(f).forEach(function(e){Object.defineProperty(v,e,{enumerable:!0,get:function(){return $[e]}})});var m={};function E(t){m[t]--,m[t]<=0&&(m[t]=0,e.set(g,t,!1))}Object.keys(c).forEach(function(t){var n=c[t].bind(v);v[t]=function(){var o=n.apply(null,arguments);o&&"function"==typeof o.then&&(m[t]||(m[t]=0),m[t]++,e.set(g,t,!0),Promise.resolve(o).then(function(){E(t)},function(){E(t)}));return o}});var O=n.watch||{};Object.entries(O).forEach(function(e){var n,r,i=e[0],u=e[1];if("function"==typeof u)n=u,r={};else if(n=u.handler,r={},u.deep&&(r.deep=!0),u.immediate&&(r.immediate=!0),!n)return void o('watch "'+i+'" in store "'+t+'" 缺少 handler,该 watcher 将被跳过');$.$watch(function(){return i.split(".").reduce(function(e,t){return e&&e[t]},v)},n.bind(v),r)}),v.$state=h,v.$status=b,v.$id=t;var w=null;Object.defineProperty(v,"$vm",{enumerable:!0,configurable:!1,get:function(){return w},set:function(){o("$vm 是只读属性,不允许业务侧重写")}}),v.$patch=function(n){if(v.$disposed)o('store "'+t+'" 已销毁,忽略 $patch 操作');else{var r="function"==typeof n?n(h):n;Object.keys(r).forEach(function(t){e.set(h,t,r[t])})}},v.$reset=function(){var t=n.state();Object.keys(t).forEach(function(n){e.set(h,n,t[n])}),Object.keys(h).forEach(function(n){n in t||e.delete(h,n)});var o="function"==typeof n.source?n.source():{};Object.keys(o).forEach(function(t){e.set(y,t,o[t])}),Object.keys(y).forEach(function(t){t in o||e.delete(y,t)})};var j={};v.$emit=function(e,t){var n=j[e];n&&n.slice().forEach(function(e){e(t)})},v.$on=function(e,t){return j[e]||(j[e]=[]),j[e].push(t),function(){if(j[e]){var n=j[e].indexOf(t);n>-1&&j[e].splice(n,1)}}},v.$off=function(e,t){if(j[e])if(t){var n=j[e].indexOf(t);n>-1&&j[e].splice(n,1)}else delete j[e]};var k=[];function P(){k.forEach(function(e){e.stopped||(clearInterval(e.id),e.stopped=!0)}),k.length=0}v.$setInterval=function(e,t){var n={id:setInterval(e,t),stopped:!1};k.push(n);return function(){if(!n.stopped){clearInterval(n.id),n.stopped=!0;var e=k.indexOf(n);e>-1&&k.splice(e,1)}}};var _=!1;function S(){_||(_=!0,b.mounted=!0,b.active=!0,s&&s.call(v),v.$emit("page:enter"),l.forEach(function(e){e.enter&&e.enter()}))}function x(){_&&(P(),_=!1,b.active=!1,d&&d.call(v),v.$emit("page:leave"),l.forEach(function(e){e.leave&&e.leave()}))}var T="undefined"!=typeof WeakSet?new WeakSet:null,V=T?null:[];return v.bindTo=function(e){return v.$disposed||function(e){return T?T.has(e):V.indexOf(e)>-1}(e)||(function(e){T?T.add(e):V.push(e)}(e),w=e,(e._provided||(e._provided={})).pageStore=v,e.$on("hook:mounted",function(){S()}),e.$on("hook:activated",function(){S()}),e.$on("hook:deactivated",function(){x()}),e.$on("hook:beforeDestroy",function(){x(),v.$destroy()})),v},v.$destroy=function(){v.$disposed||(b.mounted=!1,b.active=!1,P(),l.forEach(function(e){e.destroy&&e.destroy()}),v.$disposed=!0,Object.keys(j).forEach(function(e){delete j[e]}),$.$destroy(),r.delete(t))},v._vm=$,i.forEach(function(t){var o=n[t.name];if(void 0!==o){var r=t.install(v,o,{Vue:e});r&&l.push(r)}}),v}function f(e,n){if(!e||"string"!=typeof e)throw new Error("[vue-page-store] definePageStore 需要一个非空字符串作为 id");if(!n||"function"!=typeof n.state)throw new Error('[vue-page-store] definePageStore("'+e+'") 需要 state 为函数');var o=t;return function(t){if(r.has(e)){var i=r.get(e);return t&&i.bindTo(t),i}var u=a(o,e,n);return r.set(e,u),t&&u.bindTo(t),"function"==typeof n.init&&n.init.call(u),u}}var c={definePageStore:f,registerPlugin:u,storeRegistry:r};e.default=c,e.definePageStore=f,e.registerPlugin=u,e.storeRegistry=r,Object.defineProperty(e,"__esModule",{value:!0})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-page-store",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Vue 2.6 页面级 Store —— 状态、通信、生命周期,一个作用域全收",
5
5
  "author": "weijianjun",
6
6
  "license": "MIT",