vue-page-store 0.4.0 → 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 +258 -20
- package/dist/index.cjs.js +90 -19
- package/dist/index.d.ts +56 -2
- package/dist/index.esm.js +90 -20
- package/dist/index.umd.js +92 -23
- package/dist/index.umd.min.js +12 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# vue-page-store
|
|
2
2
|
|
|
3
|
-
> Vue 2.6 页面级作用域运行时容器 —— source、state、getters、actions、watch、enter/leave,一个页面作用域全收。
|
|
3
|
+
> Vue 2.6 页面级作用域运行时容器 —— source、state、getters、actions、watch、init/enter/leave,一个页面作用域全收。
|
|
4
4
|
|
|
5
5
|
## 它是什么
|
|
6
6
|
|
|
@@ -13,16 +13,18 @@
|
|
|
13
13
|
- **getters** — 派生计算
|
|
14
14
|
- **actions** — 业务逻辑
|
|
15
15
|
- **watch** — 声明式副作用
|
|
16
|
+
- **init** — 一次性初始化(拉字典、注册事件监听等)
|
|
16
17
|
- **enter / leave** — 页面可见性生命周期
|
|
17
18
|
- **$setInterval** — 页面级定时器托管
|
|
18
19
|
- **event bus** — 页面内作用域通信
|
|
20
|
+
- **plugin** — 外部扩展机制(v0.5 新增)
|
|
19
21
|
|
|
20
22
|
页面离开时可以自动清理页面级定时器,页面销毁时 `$destroy` 一键回收,不污染全局。
|
|
21
23
|
|
|
22
24
|
## 它不是什么
|
|
23
25
|
|
|
24
26
|
- **不是 Vuex / Pinia 替代品** — 全局状态(用户信息、权限、路由)请继续用 Vuex / Pinia
|
|
25
|
-
- **不是全局状态管理方案** —
|
|
27
|
+
- **不是全局状态管理方案** — 它的作用域是"页面",不是"应用"
|
|
26
28
|
- **不是大而全的框架** — 它只解决复杂页面的页面层状态编排
|
|
27
29
|
|
|
28
30
|
| | Vuex / Pinia | vue-page-store |
|
|
@@ -109,6 +111,13 @@ export const useOrderStore = definePageStore('orderList', {
|
|
|
109
111
|
}
|
|
110
112
|
},
|
|
111
113
|
|
|
114
|
+
// 只执行一次:拉下拉框选项、注册事件监听等
|
|
115
|
+
init() {
|
|
116
|
+
this.loadDictOptions()
|
|
117
|
+
this.$on('child:refresh', () => this.search())
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
// 每次页面可见时执行
|
|
112
121
|
enter() {
|
|
113
122
|
this.$source.query = this.$vm.$route.query
|
|
114
123
|
this.search()
|
|
@@ -129,7 +138,7 @@ import { useOrderStore } from './stores/order-list'
|
|
|
129
138
|
|
|
130
139
|
export default {
|
|
131
140
|
created() {
|
|
132
|
-
// 传入 this → 自动绑定 enter/leave + 自动 provide + 页面销毁时自动回收
|
|
141
|
+
// 传入 this → 自动绑定 init/enter/leave + 自动 provide + 页面销毁时自动回收
|
|
133
142
|
this.pageStore = useOrderStore(this)
|
|
134
143
|
}
|
|
135
144
|
}
|
|
@@ -165,8 +174,14 @@ export default {
|
|
|
165
174
|
| `getters` | `{ [key]: function }` | 派生计算,`this` 指向 store |
|
|
166
175
|
| `actions` | `{ [key]: function }` | 业务方法,`this` 指向 store |
|
|
167
176
|
| `watch` | `{ [path]: handler \| options }` | 声明式 watcher,支持 dot-path |
|
|
177
|
+
| `init` | `function` | store 创建后一次性调用,`$vm` 已可用。适合拉字典、注册事件监听 |
|
|
168
178
|
| `enter` | `function` | 页面进入可见 / 可交互状态时触发 |
|
|
169
179
|
| `leave` | `function` | 页面离开可见 / 可交互状态时触发 |
|
|
180
|
+
| *其它字段* | *any* | 注册过的 plugin 可声明自己的字段(见 [Plugin](#plugin)) |
|
|
181
|
+
|
|
182
|
+
### `registerPlugin(plugin)` *(v0.5 新增)*
|
|
183
|
+
|
|
184
|
+
注册全局插件,详见 [Plugin](#plugin) 节。
|
|
170
185
|
|
|
171
186
|
### Store 实例属性与方法
|
|
172
187
|
|
|
@@ -207,7 +222,7 @@ watch: {
|
|
|
207
222
|
|
|
208
223
|
## source 与 state
|
|
209
224
|
|
|
210
|
-
v0.4 引入了 `source
|
|
225
|
+
v0.4 引入了 `source`,用于把"页面输入 / 原始返回"和"业务状态"分开。
|
|
211
226
|
|
|
212
227
|
### 推荐分工
|
|
213
228
|
|
|
@@ -233,15 +248,58 @@ state: () => ({
|
|
|
233
248
|
- getters 可以同时基于 `this.$source` 和 `this.xxx` 计算
|
|
234
249
|
- `$reset()` 时 source / state 一起恢复,更清晰
|
|
235
250
|
|
|
236
|
-
## enter / leave
|
|
251
|
+
## init / enter / leave
|
|
237
252
|
|
|
238
253
|
v0.4 用 `enter / leave` 替换了 v0.3 的 `lifecycle.mount / unmount / activate / deactivate`。
|
|
239
254
|
|
|
255
|
+
v0.4.1 新增 `init`,用于 store 创建后的一次性初始化。
|
|
256
|
+
|
|
240
257
|
### 语义
|
|
241
258
|
|
|
259
|
+
- **init**:store 创建后一次性调用,`$vm` 已可用,DOM 未就绪
|
|
242
260
|
- **enter**:页面进入可见 / 可交互状态
|
|
243
261
|
- **leave**:页面离开可见 / 可交互状态
|
|
244
262
|
|
|
263
|
+
### 执行时序
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
created() 开始
|
|
267
|
+
└→ useStore(this)
|
|
268
|
+
└→ createStoreInstance() ← state/source/getters/actions 就绪
|
|
269
|
+
└→ plugin.install() ← v0.5:plugin 安装($vm 尚未绑定)
|
|
270
|
+
└→ bindTo(this) ← $vm 赋值
|
|
271
|
+
└→ ★ init() ← $vm 可用,只执行一次
|
|
272
|
+
└→ created() 剩余代码
|
|
273
|
+
mounted()
|
|
274
|
+
└→ ★ enter() ← DOM 就绪,每次可见都执行
|
|
275
|
+
└→ plugin.enter() ← v0.5:plugin enter 钩子
|
|
276
|
+
|
|
277
|
+
--- keep-alive 切走 ---
|
|
278
|
+
deactivated()
|
|
279
|
+
└→ clearAllIntervals()
|
|
280
|
+
└→ ★ leave()
|
|
281
|
+
└→ plugin.leave() ← v0.5:plugin leave 钩子
|
|
282
|
+
|
|
283
|
+
--- keep-alive 切回 ---
|
|
284
|
+
activated()
|
|
285
|
+
└→ ★ enter() ← 重新开轮询、刷数据
|
|
286
|
+
└→ plugin.enter()
|
|
287
|
+
|
|
288
|
+
--- 页面销毁 ---
|
|
289
|
+
beforeDestroy()
|
|
290
|
+
└→ ★ leave()(如果还没 leave)
|
|
291
|
+
└→ plugin.destroy() ← v0.5:plugin destroy 钩子
|
|
292
|
+
└→ $destroy()
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### 分工原则
|
|
296
|
+
|
|
297
|
+
| 钩子 | 执行次数 | $vm | DOM | 典型场景 |
|
|
298
|
+
|---|---|---|---|---|
|
|
299
|
+
| `init` | 一次 | ✅ | ❌ | 拉下拉框选项、注册事件监听、从 localStorage 恢复配置、初始化 WebSocket |
|
|
300
|
+
| `enter` | 每次可见 | ✅ | ✅ | 读路由参数、刷列表数据、开轮询 |
|
|
301
|
+
| `leave` | 每次离开 | ✅ | ✅ | 通常不需要写,interval 已自动清理 |
|
|
302
|
+
|
|
245
303
|
### keep-alive 行为
|
|
246
304
|
|
|
247
305
|
- 首次 `mounted` → `enter`
|
|
@@ -249,14 +307,26 @@ v0.4 用 `enter / leave` 替换了 v0.3 的 `lifecycle.mount / unmount / activat
|
|
|
249
307
|
- `deactivated` → `leave`
|
|
250
308
|
- `beforeDestroy` → 如果当前还没 leave,先 leave,再 `$destroy`
|
|
251
309
|
|
|
252
|
-
### 适合放在
|
|
310
|
+
### 适合放在 init 里的逻辑
|
|
311
|
+
|
|
312
|
+
- 拉下拉框 / 字典选项(只需要一次)
|
|
313
|
+
- 注册 `$on` 监听 store 内部事件
|
|
314
|
+
- 从 localStorage 恢复上次的筛选条件
|
|
315
|
+
- 初始化 WebSocket / EventSource 连接
|
|
316
|
+
- 根据用户权限裁剪 columns / 按钮配置
|
|
317
|
+
|
|
318
|
+
### 适合放在 enter 里的逻辑
|
|
253
319
|
|
|
254
|
-
-
|
|
255
|
-
-
|
|
320
|
+
- 根据 `$route` 初始化 source / state(keep-alive 切回时路由参数可能变了)
|
|
321
|
+
- 首屏加载 / 刷新列表数据
|
|
256
322
|
- 启动页面轮询
|
|
257
|
-
- 页面离开时做收尾逻辑
|
|
258
323
|
|
|
259
324
|
```js
|
|
325
|
+
init() {
|
|
326
|
+
this.loadDictOptions()
|
|
327
|
+
this.$on('child:refresh', () => this.search())
|
|
328
|
+
},
|
|
329
|
+
|
|
260
330
|
enter() {
|
|
261
331
|
this.$source.query = this.$vm.$route.query
|
|
262
332
|
this.search()
|
|
@@ -360,6 +430,128 @@ state: () => ({
|
|
|
360
430
|
})
|
|
361
431
|
```
|
|
362
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
|
+
|
|
363
555
|
## 实例模型:Singleton
|
|
364
556
|
|
|
365
557
|
当前版本采用 **id → singleton** 模型:
|
|
@@ -385,7 +577,7 @@ state: () => ({
|
|
|
385
577
|
- 仪表盘页面 —— 多模块共享筛选条件、加载状态
|
|
386
578
|
- 漏斗 / 留存等分析详情页 —— 复杂交互 + 异步数据 + 页面可见性管理
|
|
387
579
|
- 大型配置页 —— 多 tab / 多步骤表单的状态统一管理
|
|
388
|
-
- keep-alive 业务页 —— 需要 enter / leave 感知的页面
|
|
580
|
+
- keep-alive 业务页 —— 需要 init / enter / leave 感知的页面
|
|
389
581
|
- 微前端子应用 —— 页面作用域隔离,不污染宿主全局状态
|
|
390
582
|
|
|
391
583
|
## 不适用场景
|
|
@@ -412,22 +604,48 @@ actions: {
|
|
|
412
604
|
|
|
413
605
|
## 调试
|
|
414
606
|
|
|
415
|
-
`storeRegistry`
|
|
607
|
+
### `storeRegistry` —— 导出的 Map
|
|
608
|
+
|
|
609
|
+
`storeRegistry` 是导出的 Map,可以在代码里用于调试或自定义 devtools 集成:
|
|
416
610
|
|
|
417
611
|
```js
|
|
418
612
|
import { storeRegistry } from 'vue-page-store'
|
|
419
613
|
|
|
420
|
-
// 查看所有活跃 store
|
|
421
614
|
storeRegistry.forEach((store, id) => {
|
|
422
615
|
console.log(id, store.$status, store.$disposed)
|
|
423
616
|
})
|
|
424
617
|
```
|
|
425
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
|
+
|
|
426
644
|
## 从 v0.3.x 升级
|
|
427
645
|
|
|
428
646
|
### Breaking Changes
|
|
429
647
|
|
|
430
|
-
**1. `lifecycle` 被移除,改为 `enter / leave`**
|
|
648
|
+
**1. `lifecycle` 被移除,改为 `init` / `enter` / `leave`**
|
|
431
649
|
|
|
432
650
|
v0.3.x:
|
|
433
651
|
|
|
@@ -440,16 +658,23 @@ lifecycle: {
|
|
|
440
658
|
}
|
|
441
659
|
```
|
|
442
660
|
|
|
443
|
-
v0.4.
|
|
661
|
+
v0.4.x:
|
|
444
662
|
|
|
445
663
|
```js
|
|
446
|
-
|
|
447
|
-
|
|
664
|
+
init() {
|
|
665
|
+
// 只执行一次的初始化(拉字典、注册事件等)
|
|
666
|
+
},
|
|
667
|
+
enter() {
|
|
668
|
+
// 每次可见时执行(替代 mount + activate)
|
|
669
|
+
},
|
|
670
|
+
leave() {
|
|
671
|
+
// 每次离开时执行(替代 deactivate + unmount)
|
|
672
|
+
}
|
|
448
673
|
```
|
|
449
674
|
|
|
450
675
|
迁移关系:
|
|
451
676
|
|
|
452
|
-
- `lifecycle.mount` → `enter`
|
|
677
|
+
- `lifecycle.mount` → `enter`(如果包含一次性逻辑,拆到 `init`)
|
|
453
678
|
- `lifecycle.unmount` → `leave`
|
|
454
679
|
- `lifecycle.activate` → `enter`
|
|
455
680
|
- `lifecycle.deactivate` → `leave`
|
|
@@ -465,17 +690,30 @@ v0.4.0 中:
|
|
|
465
690
|
### New Features
|
|
466
691
|
|
|
467
692
|
- `source`:页面输入 / 原始返回与业务状态分离
|
|
693
|
+
- `init`:store 创建后一次性钩子,`$vm` 已可用(v0.4.1)
|
|
468
694
|
- `enter / leave`:更简单的页面可见性生命周期
|
|
469
695
|
- `$setInterval()`:页面级 interval 托管
|
|
470
696
|
- `$loading.xxx`:返回 Promise 的 action 自动追踪 loading
|
|
471
|
-
- `$vm`:只读逃生口,可在 enter 中访问 `$route / $router`
|
|
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
|
+
升级只需要改版本号,无需改代码。
|
|
472
710
|
|
|
473
711
|
## Roadmap
|
|
474
712
|
|
|
475
713
|
- **Keyed instance** — `useStore(vm, scopeKey)` 支持同定义多实例
|
|
476
|
-
- **
|
|
714
|
+
- **Official plugins** — 随着 `vue-page-runtime` 等生态库成熟,补充第一方 plugin 文档
|
|
477
715
|
- **More page runtime helpers** — 在不增加心智负担的前提下继续补页面层能力
|
|
478
716
|
|
|
479
717
|
## License
|
|
480
718
|
|
|
481
|
-
MIT © weijianjun
|
|
719
|
+
MIT © weijianjun
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* vue-page-store v0.
|
|
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.
|
|
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.
|
|
18
|
+
* vue-page-store 0.5.0 — Vue 2.6 Page Scope Runtime
|
|
17
19
|
*
|
|
18
20
|
* 页面级作用域运行时容器:
|
|
19
|
-
* source · state · getters · actions · watch · 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 分开
|
|
@@ -24,12 +26,16 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
24
26
|
* $setInterval → 页面级 timer 托管,leave 时自动清理
|
|
25
27
|
* $loading → async action 自动追踪 loading 状态
|
|
26
28
|
*
|
|
29
|
+
* v0.4.1 新增:
|
|
30
|
+
* init → store 创建后一次性初始化钩子,$vm 已可用
|
|
31
|
+
*
|
|
32
|
+
* v0.5 新增:
|
|
33
|
+
* plugin → registerPlugin 注册外部扩展,声明字段 + 生命周期钩子
|
|
34
|
+
*
|
|
27
35
|
* @author weijianjun
|
|
28
36
|
* @license MIT
|
|
29
37
|
*/
|
|
30
38
|
|
|
31
|
-
// Store 注册表(导出供调试 / devtools 使用)
|
|
32
|
-
var storeRegistry = new Map();
|
|
33
39
|
|
|
34
40
|
// ====== dev-only warning ======
|
|
35
41
|
var isDev = typeof process !== 'undefined'
|
|
@@ -42,6 +48,47 @@ function warn(msg) {
|
|
|
42
48
|
}
|
|
43
49
|
}
|
|
44
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
|
+
|
|
45
92
|
function createStoreInstance(Vue, id, options) {
|
|
46
93
|
var initialState = options.state();
|
|
47
94
|
|
|
@@ -55,6 +102,9 @@ function createStoreInstance(Vue, id, options) {
|
|
|
55
102
|
var enterHook = typeof options.enter === 'function' ? options.enter : null;
|
|
56
103
|
var leaveHook = typeof options.leave === 'function' ? options.leave : null;
|
|
57
104
|
|
|
105
|
+
// ====== v0.5 新增:plugin hooks 闭包存储(由 install 填充) ======
|
|
106
|
+
var _pluginHooks = [];
|
|
107
|
+
|
|
58
108
|
// --- 用一个隐藏的 Vue 实例承载响应式 state + source + loading + computed getters ---
|
|
59
109
|
var computedDefs = {};
|
|
60
110
|
var store = { $disposed: false };
|
|
@@ -322,6 +372,8 @@ function createStoreInstance(Vue, id, options) {
|
|
|
322
372
|
enterHook.call(store);
|
|
323
373
|
}
|
|
324
374
|
store.$emit('page:enter');
|
|
375
|
+
// v0.5: plugin enter hooks
|
|
376
|
+
_pluginHooks.forEach(function (h) { if (h.enter) h.enter(); });
|
|
325
377
|
}
|
|
326
378
|
|
|
327
379
|
function runLeave() {
|
|
@@ -334,6 +386,8 @@ function createStoreInstance(Vue, id, options) {
|
|
|
334
386
|
leaveHook.call(store);
|
|
335
387
|
}
|
|
336
388
|
store.$emit('page:leave');
|
|
389
|
+
// v0.5: plugin leave hooks
|
|
390
|
+
_pluginHooks.forEach(function (h) { if (h.leave) h.leave(); });
|
|
337
391
|
}
|
|
338
392
|
|
|
339
393
|
// ====== bindTo 去重标记 ======
|
|
@@ -400,6 +454,7 @@ function createStoreInstance(Vue, id, options) {
|
|
|
400
454
|
* 销毁 store
|
|
401
455
|
*
|
|
402
456
|
* v0.4 变更:兜底清理 interval
|
|
457
|
+
* v0.5 变更:调用 plugin destroy 钩子
|
|
403
458
|
*/
|
|
404
459
|
store.$destroy = function () {
|
|
405
460
|
if (store.$disposed) return;
|
|
@@ -410,6 +465,9 @@ function createStoreInstance(Vue, id, options) {
|
|
|
410
465
|
// 兜底清理 interval(正常流程 leave 已经清过,这里防遗漏)
|
|
411
466
|
clearAllIntervals();
|
|
412
467
|
|
|
468
|
+
// v0.5: plugin destroy hooks
|
|
469
|
+
_pluginHooks.forEach(function (h) { if (h.destroy) h.destroy(); });
|
|
470
|
+
|
|
413
471
|
store.$disposed = true;
|
|
414
472
|
Object.keys(_listeners).forEach(function (key) { delete _listeners[key]; });
|
|
415
473
|
vm.$destroy();
|
|
@@ -418,6 +476,15 @@ function createStoreInstance(Vue, id, options) {
|
|
|
418
476
|
|
|
419
477
|
store._vm = vm;
|
|
420
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
|
+
|
|
421
488
|
return store;
|
|
422
489
|
}
|
|
423
490
|
|
|
@@ -428,6 +495,10 @@ function createStoreInstance(Vue, id, options) {
|
|
|
428
495
|
* - options 新增 source、enter、leave
|
|
429
496
|
* - options 移除 lifecycle
|
|
430
497
|
* - actions 中的 async 函数自动追踪 $loading
|
|
498
|
+
* v0.4.1 变更:
|
|
499
|
+
* - options 新增 init(bindTo 之后一次性调用)
|
|
500
|
+
* v0.5 变更:
|
|
501
|
+
* - options 中注册过的 plugin.name 字段会被交给对应 plugin 处理
|
|
431
502
|
*/
|
|
432
503
|
function definePageStore(id, options) {
|
|
433
504
|
// 入参校验
|
|
@@ -438,7 +509,7 @@ function definePageStore(id, options) {
|
|
|
438
509
|
throw new Error('[vue-page-store] definePageStore("' + id + '") 需要 state 为函数');
|
|
439
510
|
}
|
|
440
511
|
|
|
441
|
-
var _Vue =
|
|
512
|
+
var _Vue = Vue;
|
|
442
513
|
|
|
443
514
|
return function useStore(componentVm) {
|
|
444
515
|
if (storeRegistry.has(id)) {
|
|
@@ -447,26 +518,26 @@ function definePageStore(id, options) {
|
|
|
447
518
|
return existing;
|
|
448
519
|
}
|
|
449
520
|
|
|
450
|
-
if (!_Vue) {
|
|
451
|
-
try {
|
|
452
|
-
_Vue = require('vue');
|
|
453
|
-
if (_Vue.default) _Vue = _Vue.default;
|
|
454
|
-
} catch (e) {
|
|
455
|
-
throw new Error(
|
|
456
|
-
'[vue-page-store] 无法自动获取 Vue,请确保 vue 已安装'
|
|
457
|
-
);
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
521
|
var store = createStoreInstance(_Vue, id, options);
|
|
462
522
|
storeRegistry.set(id, store);
|
|
463
523
|
if (componentVm) store.bindTo(componentVm);
|
|
524
|
+
|
|
525
|
+
// v0.4.1 新增:init 钩子 —— bindTo 之后调用,$vm 已可用
|
|
526
|
+
if (typeof options.init === 'function') {
|
|
527
|
+
options.init.call(store);
|
|
528
|
+
}
|
|
529
|
+
|
|
464
530
|
return store;
|
|
465
531
|
};
|
|
466
532
|
}
|
|
467
533
|
|
|
468
|
-
var index = {
|
|
534
|
+
var index = {
|
|
535
|
+
definePageStore: definePageStore,
|
|
536
|
+
registerPlugin: registerPlugin,
|
|
537
|
+
storeRegistry: storeRegistry
|
|
538
|
+
};
|
|
469
539
|
|
|
470
540
|
exports.default = index;
|
|
471
541
|
exports.definePageStore = definePageStore;
|
|
542
|
+
exports.registerPlugin = registerPlugin;
|
|
472
543
|
exports.storeRegistry = storeRegistry;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vue-page-store v0.
|
|
2
|
+
* vue-page-store v0.5.0 - TypeScript 类型定义
|
|
3
3
|
*
|
|
4
4
|
* Page Scope Runtime for Vue 2.6
|
|
5
5
|
*/
|
|
@@ -49,6 +49,13 @@ export interface StoreOptions<
|
|
|
49
49
|
};
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* store 创建后一次性调用(v0.4.1 新增)
|
|
54
|
+
* bindTo 之后调用,$vm 已可用
|
|
55
|
+
* 适合拉字典、注册事件监听、从 localStorage 恢复配置、初始化 WebSocket
|
|
56
|
+
*/
|
|
57
|
+
init?: (this: PageStore<S, Src>) => void;
|
|
58
|
+
|
|
52
59
|
/**
|
|
53
60
|
* 页面进入可见/可交互状态(v0.4 新增,替换 v0.3 lifecycle)
|
|
54
61
|
* keep-alive 切回时也会触发
|
|
@@ -61,6 +68,9 @@ export interface StoreOptions<
|
|
|
61
68
|
* interval 在 leave 前已自动清理
|
|
62
69
|
*/
|
|
63
70
|
leave?: (this: PageStore<S, Src>) => void;
|
|
71
|
+
|
|
72
|
+
/** 允许 plugin 声明的额外字段(v0.5 新增) */
|
|
73
|
+
[key: string]: any;
|
|
64
74
|
}
|
|
65
75
|
|
|
66
76
|
export interface Store<
|
|
@@ -129,6 +139,10 @@ export type PageStore<
|
|
|
129
139
|
* - options 新增 source、enter、leave
|
|
130
140
|
* - options 移除 lifecycle(breaking change)
|
|
131
141
|
* - async action 自动追踪 $loading
|
|
142
|
+
* v0.4.1 变更:
|
|
143
|
+
* - options 新增 init(bindTo 之后一次性调用)
|
|
144
|
+
* v0.5 变更:
|
|
145
|
+
* - options 支持 plugin 声明的自定义字段
|
|
132
146
|
*/
|
|
133
147
|
export declare function definePageStore<
|
|
134
148
|
S extends Record<string, any>,
|
|
@@ -139,4 +153,44 @@ export declare function definePageStore<
|
|
|
139
153
|
): (componentVm?: Vue2ComponentInstance) => PageStore<S, Src>;
|
|
140
154
|
|
|
141
155
|
/** Store 注册表 */
|
|
142
|
-
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.
|
|
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.
|
|
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.
|
|
14
|
+
* vue-page-store 0.5.0 — Vue 2.6 Page Scope Runtime
|
|
13
15
|
*
|
|
14
16
|
* 页面级作用域运行时容器:
|
|
15
|
-
* source · state · getters · actions · watch · 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 分开
|
|
@@ -20,12 +22,16 @@
|
|
|
20
22
|
* $setInterval → 页面级 timer 托管,leave 时自动清理
|
|
21
23
|
* $loading → async action 自动追踪 loading 状态
|
|
22
24
|
*
|
|
25
|
+
* v0.4.1 新增:
|
|
26
|
+
* init → store 创建后一次性初始化钩子,$vm 已可用
|
|
27
|
+
*
|
|
28
|
+
* v0.5 新增:
|
|
29
|
+
* plugin → registerPlugin 注册外部扩展,声明字段 + 生命周期钩子
|
|
30
|
+
*
|
|
23
31
|
* @author weijianjun
|
|
24
32
|
* @license MIT
|
|
25
33
|
*/
|
|
26
34
|
|
|
27
|
-
// Store 注册表(导出供调试 / devtools 使用)
|
|
28
|
-
var storeRegistry = new Map();
|
|
29
35
|
|
|
30
36
|
// ====== dev-only warning ======
|
|
31
37
|
var isDev = typeof process !== 'undefined'
|
|
@@ -38,6 +44,47 @@ function warn(msg) {
|
|
|
38
44
|
}
|
|
39
45
|
}
|
|
40
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
|
+
|
|
41
88
|
function createStoreInstance(Vue, id, options) {
|
|
42
89
|
var initialState = options.state();
|
|
43
90
|
|
|
@@ -51,6 +98,9 @@ function createStoreInstance(Vue, id, options) {
|
|
|
51
98
|
var enterHook = typeof options.enter === 'function' ? options.enter : null;
|
|
52
99
|
var leaveHook = typeof options.leave === 'function' ? options.leave : null;
|
|
53
100
|
|
|
101
|
+
// ====== v0.5 新增:plugin hooks 闭包存储(由 install 填充) ======
|
|
102
|
+
var _pluginHooks = [];
|
|
103
|
+
|
|
54
104
|
// --- 用一个隐藏的 Vue 实例承载响应式 state + source + loading + computed getters ---
|
|
55
105
|
var computedDefs = {};
|
|
56
106
|
var store = { $disposed: false };
|
|
@@ -318,6 +368,8 @@ function createStoreInstance(Vue, id, options) {
|
|
|
318
368
|
enterHook.call(store);
|
|
319
369
|
}
|
|
320
370
|
store.$emit('page:enter');
|
|
371
|
+
// v0.5: plugin enter hooks
|
|
372
|
+
_pluginHooks.forEach(function (h) { if (h.enter) h.enter(); });
|
|
321
373
|
}
|
|
322
374
|
|
|
323
375
|
function runLeave() {
|
|
@@ -330,6 +382,8 @@ function createStoreInstance(Vue, id, options) {
|
|
|
330
382
|
leaveHook.call(store);
|
|
331
383
|
}
|
|
332
384
|
store.$emit('page:leave');
|
|
385
|
+
// v0.5: plugin leave hooks
|
|
386
|
+
_pluginHooks.forEach(function (h) { if (h.leave) h.leave(); });
|
|
333
387
|
}
|
|
334
388
|
|
|
335
389
|
// ====== bindTo 去重标记 ======
|
|
@@ -396,6 +450,7 @@ function createStoreInstance(Vue, id, options) {
|
|
|
396
450
|
* 销毁 store
|
|
397
451
|
*
|
|
398
452
|
* v0.4 变更:兜底清理 interval
|
|
453
|
+
* v0.5 变更:调用 plugin destroy 钩子
|
|
399
454
|
*/
|
|
400
455
|
store.$destroy = function () {
|
|
401
456
|
if (store.$disposed) return;
|
|
@@ -406,6 +461,9 @@ function createStoreInstance(Vue, id, options) {
|
|
|
406
461
|
// 兜底清理 interval(正常流程 leave 已经清过,这里防遗漏)
|
|
407
462
|
clearAllIntervals();
|
|
408
463
|
|
|
464
|
+
// v0.5: plugin destroy hooks
|
|
465
|
+
_pluginHooks.forEach(function (h) { if (h.destroy) h.destroy(); });
|
|
466
|
+
|
|
409
467
|
store.$disposed = true;
|
|
410
468
|
Object.keys(_listeners).forEach(function (key) { delete _listeners[key]; });
|
|
411
469
|
vm.$destroy();
|
|
@@ -414,6 +472,15 @@ function createStoreInstance(Vue, id, options) {
|
|
|
414
472
|
|
|
415
473
|
store._vm = vm;
|
|
416
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
|
+
|
|
417
484
|
return store;
|
|
418
485
|
}
|
|
419
486
|
|
|
@@ -424,6 +491,10 @@ function createStoreInstance(Vue, id, options) {
|
|
|
424
491
|
* - options 新增 source、enter、leave
|
|
425
492
|
* - options 移除 lifecycle
|
|
426
493
|
* - actions 中的 async 函数自动追踪 $loading
|
|
494
|
+
* v0.4.1 变更:
|
|
495
|
+
* - options 新增 init(bindTo 之后一次性调用)
|
|
496
|
+
* v0.5 变更:
|
|
497
|
+
* - options 中注册过的 plugin.name 字段会被交给对应 plugin 处理
|
|
427
498
|
*/
|
|
428
499
|
function definePageStore(id, options) {
|
|
429
500
|
// 入参校验
|
|
@@ -434,7 +505,7 @@ function definePageStore(id, options) {
|
|
|
434
505
|
throw new Error('[vue-page-store] definePageStore("' + id + '") 需要 state 为函数');
|
|
435
506
|
}
|
|
436
507
|
|
|
437
|
-
var _Vue =
|
|
508
|
+
var _Vue = Vue;
|
|
438
509
|
|
|
439
510
|
return function useStore(componentVm) {
|
|
440
511
|
if (storeRegistry.has(id)) {
|
|
@@ -443,24 +514,23 @@ function definePageStore(id, options) {
|
|
|
443
514
|
return existing;
|
|
444
515
|
}
|
|
445
516
|
|
|
446
|
-
if (!_Vue) {
|
|
447
|
-
try {
|
|
448
|
-
_Vue = require('vue');
|
|
449
|
-
if (_Vue.default) _Vue = _Vue.default;
|
|
450
|
-
} catch (e) {
|
|
451
|
-
throw new Error(
|
|
452
|
-
'[vue-page-store] 无法自动获取 Vue,请确保 vue 已安装'
|
|
453
|
-
);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
517
|
var store = createStoreInstance(_Vue, id, options);
|
|
458
518
|
storeRegistry.set(id, store);
|
|
459
519
|
if (componentVm) store.bindTo(componentVm);
|
|
520
|
+
|
|
521
|
+
// v0.4.1 新增:init 钩子 —— bindTo 之后调用,$vm 已可用
|
|
522
|
+
if (typeof options.init === 'function') {
|
|
523
|
+
options.init.call(store);
|
|
524
|
+
}
|
|
525
|
+
|
|
460
526
|
return store;
|
|
461
527
|
};
|
|
462
528
|
}
|
|
463
529
|
|
|
464
|
-
var index = {
|
|
530
|
+
var index = {
|
|
531
|
+
definePageStore: definePageStore,
|
|
532
|
+
registerPlugin: registerPlugin,
|
|
533
|
+
storeRegistry: storeRegistry
|
|
534
|
+
};
|
|
465
535
|
|
|
466
|
-
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.
|
|
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.
|
|
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.
|
|
18
|
+
* vue-page-store 0.5.0 — Vue 2.6 Page Scope Runtime
|
|
19
19
|
*
|
|
20
20
|
* 页面级作用域运行时容器:
|
|
21
|
-
* source · state · getters · actions · watch · 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 分开
|
|
@@ -26,12 +26,16 @@
|
|
|
26
26
|
* $setInterval → 页面级 timer 托管,leave 时自动清理
|
|
27
27
|
* $loading → async action 自动追踪 loading 状态
|
|
28
28
|
*
|
|
29
|
+
* v0.4.1 新增:
|
|
30
|
+
* init → store 创建后一次性初始化钩子,$vm 已可用
|
|
31
|
+
*
|
|
32
|
+
* v0.5 新增:
|
|
33
|
+
* plugin → registerPlugin 注册外部扩展,声明字段 + 生命周期钩子
|
|
34
|
+
*
|
|
29
35
|
* @author weijianjun
|
|
30
36
|
* @license MIT
|
|
31
37
|
*/
|
|
32
38
|
|
|
33
|
-
// Store 注册表(导出供调试 / devtools 使用)
|
|
34
|
-
var storeRegistry = new Map();
|
|
35
39
|
|
|
36
40
|
// ====== dev-only warning ======
|
|
37
41
|
var isDev = typeof process !== 'undefined'
|
|
@@ -44,6 +48,47 @@
|
|
|
44
48
|
}
|
|
45
49
|
}
|
|
46
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
|
+
|
|
47
92
|
function createStoreInstance(Vue, id, options) {
|
|
48
93
|
var initialState = options.state();
|
|
49
94
|
|
|
@@ -57,6 +102,9 @@
|
|
|
57
102
|
var enterHook = typeof options.enter === 'function' ? options.enter : null;
|
|
58
103
|
var leaveHook = typeof options.leave === 'function' ? options.leave : null;
|
|
59
104
|
|
|
105
|
+
// ====== v0.5 新增:plugin hooks 闭包存储(由 install 填充) ======
|
|
106
|
+
var _pluginHooks = [];
|
|
107
|
+
|
|
60
108
|
// --- 用一个隐藏的 Vue 实例承载响应式 state + source + loading + computed getters ---
|
|
61
109
|
var computedDefs = {};
|
|
62
110
|
var store = { $disposed: false };
|
|
@@ -324,6 +372,8 @@
|
|
|
324
372
|
enterHook.call(store);
|
|
325
373
|
}
|
|
326
374
|
store.$emit('page:enter');
|
|
375
|
+
// v0.5: plugin enter hooks
|
|
376
|
+
_pluginHooks.forEach(function (h) { if (h.enter) h.enter(); });
|
|
327
377
|
}
|
|
328
378
|
|
|
329
379
|
function runLeave() {
|
|
@@ -336,6 +386,8 @@
|
|
|
336
386
|
leaveHook.call(store);
|
|
337
387
|
}
|
|
338
388
|
store.$emit('page:leave');
|
|
389
|
+
// v0.5: plugin leave hooks
|
|
390
|
+
_pluginHooks.forEach(function (h) { if (h.leave) h.leave(); });
|
|
339
391
|
}
|
|
340
392
|
|
|
341
393
|
// ====== bindTo 去重标记 ======
|
|
@@ -402,6 +454,7 @@
|
|
|
402
454
|
* 销毁 store
|
|
403
455
|
*
|
|
404
456
|
* v0.4 变更:兜底清理 interval
|
|
457
|
+
* v0.5 变更:调用 plugin destroy 钩子
|
|
405
458
|
*/
|
|
406
459
|
store.$destroy = function () {
|
|
407
460
|
if (store.$disposed) return;
|
|
@@ -412,6 +465,9 @@
|
|
|
412
465
|
// 兜底清理 interval(正常流程 leave 已经清过,这里防遗漏)
|
|
413
466
|
clearAllIntervals();
|
|
414
467
|
|
|
468
|
+
// v0.5: plugin destroy hooks
|
|
469
|
+
_pluginHooks.forEach(function (h) { if (h.destroy) h.destroy(); });
|
|
470
|
+
|
|
415
471
|
store.$disposed = true;
|
|
416
472
|
Object.keys(_listeners).forEach(function (key) { delete _listeners[key]; });
|
|
417
473
|
vm.$destroy();
|
|
@@ -420,6 +476,15 @@
|
|
|
420
476
|
|
|
421
477
|
store._vm = vm;
|
|
422
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
|
+
|
|
423
488
|
return store;
|
|
424
489
|
}
|
|
425
490
|
|
|
@@ -430,6 +495,10 @@
|
|
|
430
495
|
* - options 新增 source、enter、leave
|
|
431
496
|
* - options 移除 lifecycle
|
|
432
497
|
* - actions 中的 async 函数自动追踪 $loading
|
|
498
|
+
* v0.4.1 变更:
|
|
499
|
+
* - options 新增 init(bindTo 之后一次性调用)
|
|
500
|
+
* v0.5 变更:
|
|
501
|
+
* - options 中注册过的 plugin.name 字段会被交给对应 plugin 处理
|
|
433
502
|
*/
|
|
434
503
|
function definePageStore(id, options) {
|
|
435
504
|
// 入参校验
|
|
@@ -440,7 +509,7 @@
|
|
|
440
509
|
throw new Error('[vue-page-store] definePageStore("' + id + '") 需要 state 为函数');
|
|
441
510
|
}
|
|
442
511
|
|
|
443
|
-
var _Vue =
|
|
512
|
+
var _Vue = Vue;
|
|
444
513
|
|
|
445
514
|
return function useStore(componentVm) {
|
|
446
515
|
if (storeRegistry.has(id)) {
|
|
@@ -449,28 +518,28 @@
|
|
|
449
518
|
return existing;
|
|
450
519
|
}
|
|
451
520
|
|
|
452
|
-
if (!_Vue) {
|
|
453
|
-
try {
|
|
454
|
-
_Vue = require('vue');
|
|
455
|
-
if (_Vue.default) _Vue = _Vue.default;
|
|
456
|
-
} catch (e) {
|
|
457
|
-
throw new Error(
|
|
458
|
-
'[vue-page-store] 无法自动获取 Vue,请确保 vue 已安装'
|
|
459
|
-
);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
|
|
463
521
|
var store = createStoreInstance(_Vue, id, options);
|
|
464
522
|
storeRegistry.set(id, store);
|
|
465
523
|
if (componentVm) store.bindTo(componentVm);
|
|
524
|
+
|
|
525
|
+
// v0.4.1 新增:init 钩子 —— bindTo 之后调用,$vm 已可用
|
|
526
|
+
if (typeof options.init === 'function') {
|
|
527
|
+
options.init.call(store);
|
|
528
|
+
}
|
|
529
|
+
|
|
466
530
|
return store;
|
|
467
531
|
};
|
|
468
532
|
}
|
|
469
533
|
|
|
470
|
-
var index = {
|
|
534
|
+
var index = {
|
|
535
|
+
definePageStore: definePageStore,
|
|
536
|
+
registerPlugin: registerPlugin,
|
|
537
|
+
storeRegistry: storeRegistry
|
|
538
|
+
};
|
|
471
539
|
|
|
472
540
|
exports.default = index;
|
|
473
541
|
exports.definePageStore = definePageStore;
|
|
542
|
+
exports.registerPlugin = registerPlugin;
|
|
474
543
|
exports.storeRegistry = storeRegistry;
|
|
475
544
|
|
|
476
545
|
Object.defineProperty(exports, '__esModule', { value: true });
|
package/dist/index.umd.min.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* vue-page-store v0.
|
|
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.
|
|
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.
|
|
13
|
+
* vue-page-store 0.5.0 — Vue 2.6 Page Scope Runtime
|
|
14
14
|
*
|
|
15
15
|
* 页面级作用域运行时容器:
|
|
16
|
-
* source · state · getters · actions · watch · 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 分开
|
|
@@ -21,6 +21,12 @@
|
|
|
21
21
|
* $setInterval → 页面级 timer 托管,leave 时自动清理
|
|
22
22
|
* $loading → async action 自动追踪 loading 状态
|
|
23
23
|
*
|
|
24
|
+
* v0.4.1 新增:
|
|
25
|
+
* init → store 创建后一次性初始化钩子,$vm 已可用
|
|
26
|
+
*
|
|
27
|
+
* v0.5 新增:
|
|
28
|
+
* plugin → registerPlugin 注册外部扩展,声明字段 + 生命周期钩子
|
|
29
|
+
*
|
|
24
30
|
* @author weijianjun
|
|
25
31
|
* @license MIT
|
|
26
|
-
*/var
|
|
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})});
|