vue-page-store 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,16 +13,16 @@
13
13
  | **provide / inject** | 只传数据,不管通信和副作用 |
14
14
  | **组件 data** | 跨组件共享困难,深层传递 props 地狱 |
15
15
 
16
- `vue-page-store` 解决的就是这个中间地带:**页面内部需要共享状态 + 通信 + 副作用管理,但不应该污染全局。**
16
+ `vue-page-store` 解决的就是这个中间地带:**页面内部需要共享状态 + 通信 + 生命周期管理,但不应该污染全局。**
17
17
 
18
18
  ## 核心特性
19
19
 
20
20
  - **页面级作用域隔离** — 每个 store 独立一份 state 和事件,互不干扰
21
- - **`$destroy` 一键回收**页面销毁时自动清空 state、watchers、事件监听,零泄漏
22
- - **API 对齐 Pinia** — `state` / `getters` / `actions` / `$patch` / `$subscribe` / `$reset`,零学习成本
21
+ - **`useStore(this)` 一行绑定**自动挂载生命周期,自动销毁,零手动清理
22
+ - **页面生命周期** — `mount` / `unmount` / `activate` / `deactivate`,keep-alive 原生支持
23
+ - **API 对齐 Pinia** — `state` / `getters` / `actions` / `$patch` / `$reset`,零学习成本
23
24
  - **内置作用域事件** — `$emit` / `$on` / `$off` 限定在当前 store 内,替代全局 EventBus
24
25
  - **声明式 watch** — 页面级副作用自动绑定生命周期
25
- - **TypeScript 支持** — 开箱即用的类型定义
26
26
 
27
27
  ## 安装
28
28
 
@@ -37,7 +37,6 @@ npm install vue-page-store
37
37
  ### 1. 定义 Store
38
38
 
39
39
  ```javascript
40
- // store.js
41
40
  import { definePageStore } from 'vue-page-store';
42
41
 
43
42
  export const useFunnelStore = definePageStore('funnelDetail', {
@@ -66,26 +65,38 @@ export const useFunnelStore = definePageStore('funnelDetail', {
66
65
 
67
66
  watch: {
68
67
  'filters.platform'(newVal) {
69
- // platform 变了自动重新拉数据
70
68
  this.fetchData();
71
69
  },
72
70
  },
71
+
72
+ // 0.2.0 新增:页面生命周期
73
+ lifecycle: {
74
+ mount() {
75
+ // 页面挂载时自动拉数据
76
+ this.fetchData();
77
+ },
78
+ unmount() {
79
+ console.log('页面销毁');
80
+ },
81
+ },
73
82
  });
74
83
  ```
75
84
 
76
85
  ### 2. 组件中使用
77
86
 
78
87
  ```javascript
79
- // 任意子组件
80
88
  export default {
89
+ created() {
90
+ // 传 this → 自动绑定生命周期 + 自动销毁,不需要 beforeDestroy
91
+ this.store = useFunnelStore(this);
92
+ },
93
+
81
94
  computed: {
82
- store() {
83
- return useFunnelStore();
84
- },
85
95
  isReady() {
86
96
  return this.store.isReady;
87
97
  },
88
98
  },
99
+
89
100
  methods: {
90
101
  handleSearch() {
91
102
  this.store.$patch({ filters: this.localFilters });
@@ -95,6 +106,8 @@ export default {
95
106
  };
96
107
  ```
97
108
 
109
+ > **不传 `this`** 也完全可以,行为和 0.1.0 一样,需要自己在 `beforeDestroy` 里调 `$destroy()`。
110
+
98
111
  ### 3. 页面内通信
99
112
 
100
113
  ```javascript
@@ -109,15 +122,73 @@ const off = this.store.$on('filter:change', (filters) => {
109
122
  // 无需手动清理 —— $destroy 时自动回收
110
123
  ```
111
124
 
112
- ### 4. 页面销毁时回收
125
+ ## 页面生命周期(0.2.0)
126
+
127
+ 通过 `useStore(this)` 传入组件实例,store 会自动绑定到组件的生命周期:
128
+
129
+ | 组件钩子 | store 行为 | `$status` 变化 |
130
+ |----------|-----------|---------------|
131
+ | `mounted` | 调用 `lifecycle.mount` | `mounted: true, active: true` |
132
+ | `activated` | 调用 `lifecycle.activate` | `active: true` |
133
+ | `deactivated` | 调用 `lifecycle.deactivate` | `active: false` |
134
+ | `beforeDestroy` | 自动调 `$destroy()`,触发 `lifecycle.unmount` | `mounted: false, active: false` |
135
+
136
+ ### 无 keep-alive
137
+
138
+ ```
139
+ mounted → lifecycle.mount → ... → beforeDestroy → lifecycle.unmount
140
+ ```
141
+
142
+ ### 有 keep-alive
143
+
144
+ ```
145
+ mounted → lifecycle.mount
146
+ → deactivated → lifecycle.deactivate
147
+ → activated → lifecycle.activate
148
+ → deactivated → lifecycle.deactivate
149
+ → activated → lifecycle.activate
150
+ → ... 反复切换 ...
151
+ → beforeDestroy → lifecycle.unmount
152
+ ```
153
+
154
+ ### keep-alive 示例
113
155
 
114
156
  ```javascript
115
- // 页面根组件
116
- export default {
117
- beforeDestroy() {
118
- useFunnelStore().$destroy();
157
+ export const useListStore = definePageStore('listPage', {
158
+ state: () => ({
159
+ list: [],
160
+ needRefresh: false,
161
+ }),
162
+
163
+ actions: {
164
+ async fetchList() {
165
+ this.list = await api.getList();
166
+ this.needRefresh = false;
167
+ },
119
168
  },
120
- };
169
+
170
+ lifecycle: {
171
+ mount() {
172
+ this.fetchList();
173
+ },
174
+ activate() {
175
+ // 从缓存恢复时,按需刷新
176
+ if (this.needRefresh) this.fetchList();
177
+ },
178
+ },
179
+ });
180
+ ```
181
+
182
+ ### `$status` 响应式状态
183
+
184
+ `$status` 是响应式对象,可以直接在模板中使用:
185
+
186
+ ```html
187
+ <template>
188
+ <div v-if="store.$status.active">
189
+ <!-- 页面激活时才渲染 -->
190
+ </div>
191
+ </template>
121
192
  ```
122
193
 
123
194
  ## API
@@ -133,30 +204,71 @@ export default {
133
204
  | `options.getters` | `Object` | 计算属性,`this` 指向 store |
134
205
  | `options.actions` | `Object` | 方法,`this` 指向 store |
135
206
  | `options.watch` | `Object` | 声明式侦听,支持点路径 `'a.b.c'` |
207
+ | `options.lifecycle` | `Object` | 页面生命周期钩子 |
208
+
209
+ ### `useStore(vm?)`
210
+
211
+ 调用 `definePageStore` 返回的函数。
212
+
213
+ | 用法 | 行为 |
214
+ |------|------|
215
+ | `useStore()` | 获取/创建 store,手动管理生命周期(兼容 0.1.0) |
216
+ | `useStore(this)` | 获取/创建 store,自动绑定生命周期 + 自动销毁 |
217
+
218
+ ### `lifecycle` 钩子
219
+
220
+ | 钩子 | 触发时机 | `this` 指向 |
221
+ |------|---------|------------|
222
+ | `mount` | 组件 `mounted` | store |
223
+ | `unmount` | 组件 `beforeDestroy`(`$destroy` 时触发) | store |
224
+ | `activate` | 组件 `activated`(keep-alive 恢复) | store |
225
+ | `deactivate` | 组件 `deactivated`(keep-alive 缓存) | store |
136
226
 
137
227
  ### Store 实例方法
138
228
 
139
229
  | 方法 | 说明 |
140
230
  |------|------|
141
231
  | `$patch(partial)` | 浅合并更新 state,接受对象或 `(state) => Object` 函数 |
142
- | `$subscribe(cb)` | 订阅 state 变化,返回取消函数 |
143
232
  | `$reset()` | 重置 state 到初始值 |
144
233
  | `$emit(event, payload?)` | 发射事件(仅当前 store 作用域) |
145
234
  | `$on(event, handler)` | 订阅事件,返回取消函数 |
146
235
  | `$off(event, handler?)` | 取消事件订阅(不传 handler 则取消该事件全部监听) |
147
236
  | `$destroy()` | 销毁 store,回收所有资源 |
237
+ | `bindTo(vm)` | 手动绑定到组件实例(通常不需要,`useStore(this)` 内部调用) |
238
+
239
+ ### Store 实例属性
240
+
241
+ | 属性 | 说明 |
242
+ |------|------|
243
+ | `$id` | store 唯一标识 |
244
+ | `$state` | 原始响应式 state 对象 |
245
+ | `$status` | 响应式对象 `{ mounted: boolean, active: boolean }` |
246
+
247
+ ## 从 0.1.0 升级
148
248
 
149
- ### `storeToRefs(store)`
249
+ **零破坏性变更**。0.1.0 的代码不改一行也能跑。
150
250
 
151
- 将 store 的 state 属性转为可解构的 refs 对象。
251
+ 区别只在于你现在可以把:
152
252
 
153
253
  ```javascript
154
- import { storeToRefs } from 'vue-page-store';
254
+ created() {
255
+ this.store = useSomeStore();
256
+ },
257
+ beforeDestroy() {
258
+ this.store.$destroy();
259
+ }
260
+ ```
155
261
 
156
- const store = useFunnelStore();
157
- const { filters, loading } = storeToRefs(store);
262
+ 简化成:
263
+
264
+ ```javascript
265
+ created() {
266
+ this.store = useSomeStore(this);
267
+ }
158
268
  ```
159
269
 
270
+ > `storeToRefs` 和 `$subscribe` 在 0.2.0 中移除——实际项目中无使用场景,精简 API。
271
+
160
272
  ## 与 Pinia / Vuex 的关系
161
273
 
162
274
  这不是 Pinia 或 Vuex 的替代品,而是补充:
@@ -164,7 +276,7 @@ const { filters, loading } = storeToRefs(store);
164
276
  | | Vuex | Pinia | vue-page-store |
165
277
  |---|---|---|---|
166
278
  | 作用域 | 全局 | 全局 | 页面级 |
167
- | 生命周期 | 应用级 | 应用级 | 页面级(手动 $destroy) |
279
+ | 生命周期 | 应用级 | 应用级 | 页面级(自动绑定) |
168
280
  | 事件通信 | 无 | 无 | 内置 $emit/$on |
169
281
  | Vue 2.6 支持 | ✅ | ⚠️ 需 @vue/composition-api | ✅ 原生支持 |
170
282
  | 适用场景 | 用户信息、权限、全局配置 | 同 Vuex | 复杂页面内部状态 |
@@ -177,4 +289,4 @@ const { filters, loading } = storeToRefs(store);
177
289
 
178
290
  ## License
179
291
 
180
- [MIT](./LICENSE)
292
+ [MIT](./LICENSE)
package/dist/index.cjs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * vue-page-store v0.1.0
2
+ * vue-page-store v0.2.1
3
3
  * (c) 2026 weijianjun
4
4
  * @license MIT
5
5
  */
@@ -8,7 +8,7 @@
8
8
  Object.defineProperty(exports, '__esModule', { value: true });
9
9
 
10
10
  /**
11
- * vue-page-store - Vue 2.6 页面级 Store
11
+ * vue-page-store 0.2.0 Vue 2.6 页面级 Store
12
12
  *
13
13
  * 状态、通信、生命周期,一个作用域全收。
14
14
  *
@@ -22,16 +22,17 @@ Object.defineProperty(exports, '__esModule', { value: true });
22
22
  */
23
23
 
24
24
  // Store 注册表(导出供调试 / devtools 使用)
25
- const storeRegistry = new Map();
25
+ var storeRegistry = new Map();
26
26
 
27
27
  function createStoreInstance(Vue, id, options) {
28
- const initialState = options.state();
29
- const getters = options.getters || {};
30
- const actions = options.actions || {};
28
+ var initialState = options.state();
29
+ var getters = options.getters || {};
30
+ var actions = options.actions || {};
31
+ var lifecycles = options.lifecycle || {};
31
32
 
32
33
  // --- 用一个隐藏的 Vue 实例承载响应式 state + computed getters ---
33
- const computedDefs = {};
34
- const store = { _disposed: false };
34
+ var computedDefs = {};
35
+ var store = { _disposed: false };
35
36
 
36
37
  Object.keys(getters).forEach(function (key) {
37
38
  computedDefs[key] = function () {
@@ -39,14 +40,21 @@ function createStoreInstance(Vue, id, options) {
39
40
  };
40
41
  });
41
42
 
42
- const vm = new Vue({
43
+ var vm = new Vue({
43
44
  data: function () {
44
- return { $$state: initialState };
45
+ return {
46
+ $$state: initialState,
47
+ $$status: {
48
+ mounted: false,
49
+ active: false
50
+ }
51
+ };
45
52
  },
46
53
  computed: computedDefs,
47
54
  });
48
55
 
49
- const rawState = vm.$data.$$state;
56
+ var rawState = vm.$data.$$state;
57
+ var rawStatus = vm.$data.$$status;
50
58
 
51
59
  // ====== state —— 代理到 vm.$$state ======
52
60
  Object.keys(initialState).forEach(function (key) {
@@ -71,14 +79,14 @@ function createStoreInstance(Vue, id, options) {
71
79
  });
72
80
 
73
81
  // ====== watch —— 声明式副作用,生命周期自动回收 ======
74
- const watches = options.watch || {};
82
+ var watches = options.watch || {};
75
83
  Object.entries(watches).forEach(function (_ref) {
76
- const path = _ref[0];
77
- const def = _ref[1];
78
- const handler = typeof def === 'function' ? def : def.handler;
79
- const watchOpts = { deep: true };
84
+ var path = _ref[0];
85
+ var def = _ref[1];
86
+ var handler = typeof def === 'function' ? def : def.handler;
87
+ var watchOpts = { deep: true };
80
88
  if (typeof def === 'object' && def.immediate) watchOpts.immediate = true;
81
- const expr = function () {
89
+ var expr = function () {
82
90
  return path.split('.').reduce(function (obj, k) { return obj && obj[k]; }, store);
83
91
  };
84
92
  vm.$watch(expr, handler.bind(store), watchOpts);
@@ -86,6 +94,7 @@ function createStoreInstance(Vue, id, options) {
86
94
 
87
95
  // ====== 内置方法 ======
88
96
  store.$state = rawState;
97
+ store.$status = rawStatus;
89
98
  store.$id = id;
90
99
 
91
100
  /**
@@ -93,37 +102,24 @@ function createStoreInstance(Vue, id, options) {
93
102
  * @param {Object|Function} partial - 要合并的对象,或 (state) => Object 函数
94
103
  */
95
104
  store.$patch = function (partial) {
96
- const obj = typeof partial === 'function' ? partial(rawState) : partial;
105
+ var obj = typeof partial === 'function' ? partial(rawState) : partial;
97
106
  Object.keys(obj).forEach(function (key) {
98
107
  Vue.set(rawState, key, obj[key]);
99
108
  });
100
109
  };
101
110
 
102
- /**
103
- * 订阅 state 变化
104
- * @param {Function} callback - (newState) => void
105
- * @returns {Function} 取消订阅函数
106
- */
107
- store.$subscribe = function (callback) {
108
- return vm.$watch(
109
- function () { return Object.assign({}, rawState); },
110
- callback,
111
- { deep: true }
112
- );
113
- };
114
-
115
111
  /**
116
112
  * 重置 state 到初始值
117
113
  */
118
114
  store.$reset = function () {
119
- const fresh = options.state();
115
+ var fresh = options.state();
120
116
  Object.keys(fresh).forEach(function (key) {
121
117
  rawState[key] = fresh[key];
122
118
  });
123
119
  };
124
120
 
125
121
  // ====== 内置事件总线(页面作用域隔离通信) ======
126
- const _listeners = {};
122
+ var _listeners = {};
127
123
 
128
124
  /**
129
125
  * 发射事件(仅当前 store 作用域内)
@@ -131,7 +127,7 @@ function createStoreInstance(Vue, id, options) {
131
127
  * @param {*} payload - 事件数据
132
128
  */
133
129
  store.$emit = function (event, payload) {
134
- const fns = _listeners[event];
130
+ var fns = _listeners[event];
135
131
  if (fns) fns.slice().forEach(function (fn) { fn(payload); });
136
132
  };
137
133
 
@@ -145,7 +141,7 @@ function createStoreInstance(Vue, id, options) {
145
141
  if (!_listeners[event]) _listeners[event] = [];
146
142
  _listeners[event].push(handler);
147
143
  return function () {
148
- const idx = _listeners[event].indexOf(handler);
144
+ var idx = _listeners[event].indexOf(handler);
149
145
  if (idx > -1) _listeners[event].splice(idx, 1);
150
146
  };
151
147
  };
@@ -158,17 +154,77 @@ function createStoreInstance(Vue, id, options) {
158
154
  store.$off = function (event, handler) {
159
155
  if (!_listeners[event]) return;
160
156
  if (handler) {
161
- const idx = _listeners[event].indexOf(handler);
157
+ var idx = _listeners[event].indexOf(handler);
162
158
  if (idx > -1) _listeners[event].splice(idx, 1);
163
159
  } else {
164
160
  delete _listeners[event];
165
161
  }
166
162
  };
167
163
 
164
+ // ====== 页面生命周期 ======
165
+
166
+ /** 触发生命周期钩子 + 广播事件 */
167
+ function runHook(name, payload) {
168
+ var hook = lifecycles[name];
169
+ if (typeof hook === 'function') {
170
+ hook.call(store, payload);
171
+ }
172
+ store.$emit('page:' + name, payload);
173
+ }
174
+
168
175
  /**
169
- * 销毁 store —— 清空事件、销毁 vm、移除注册
176
+ * 绑定到组件实例,自动挂载生命周期
177
+ *
178
+ * 原理:Vue 2 的 vm.$on('hook:xxx') 可监听组件自身生命周期事件,
179
+ * 这是 Vue 2 内置能力,不是 hack。
180
+ *
181
+ * 时序保证:
182
+ * 无 keep-alive → mounted → beforeDestroy
183
+ * 有 keep-alive → mounted → activated ⇄ deactivated → beforeDestroy
184
+ *
185
+ * 必须在 created 中调用(mounted 之前),否则 hook:mounted 捕获不到。
186
+ *
187
+ * @param {Vue} componentVm - 组件实例(通常传 this)
188
+ * @returns {Object} store - 支持链式调用
189
+ */
190
+ store.bindTo = function (componentVm) {
191
+ if (store._disposed) return store;
192
+
193
+ componentVm.$on('hook:mounted', function () {
194
+ rawStatus.mounted = true;
195
+ rawStatus.active = true;
196
+ runHook('mount');
197
+ });
198
+
199
+ componentVm.$on('hook:activated', function () {
200
+ rawStatus.active = true;
201
+ runHook('activate');
202
+ });
203
+
204
+ componentVm.$on('hook:deactivated', function () {
205
+ rawStatus.active = false;
206
+ runHook('deactivate');
207
+ });
208
+
209
+ componentVm.$on('hook:beforeDestroy', function () {
210
+ store.$destroy();
211
+ });
212
+
213
+ return store;
214
+ };
215
+
216
+ // ====== $destroy ======
217
+
218
+ /**
219
+ * 销毁 store —— 触发 unmount 钩子、清空事件、销毁 vm、移除注册
170
220
  */
171
221
  store.$destroy = function () {
222
+ if (store._disposed) return;
223
+
224
+ rawStatus.mounted = false;
225
+ rawStatus.active = false;
226
+ runHook('unmount');
227
+
172
228
  store._disposed = true;
173
229
  Object.keys(_listeners).forEach(function (key) { delete _listeners[key]; });
174
230
  vm.$destroy();
@@ -184,41 +240,47 @@ function createStoreInstance(Vue, id, options) {
184
240
  * 定义页面级 Store
185
241
  *
186
242
  * @param {string} id - 唯一标识
187
- * @param {Object} options - { state, getters, actions, watch }
188
- * @returns {Function} useStore - 调用即获取 / 创建 store 实例
243
+ * @param {Object} options - { state, getters, actions, watch, lifecycle }
244
+ * @returns {Function} useStore(vm?) - 调用即获取 / 创建 store 实例
189
245
  *
190
246
  * @example
191
- * const useFunnelStore = definePageStore('funnelDetail', {
192
- * state: () => ({ filters: {}, loading: false }),
247
+ * var useFunnelStore = definePageStore('funnelDetail', {
248
+ * state: function () { return { filters: {}, loading: false }; },
193
249
  * getters: {
194
- * isReady() { return !this.loading; }
250
+ * isReady: function () { return !this.loading; }
195
251
  * },
196
252
  * actions: {
197
- * async fetchData() { ... }
253
+ * fetchData: async function () { ... }
254
+ * },
255
+ * lifecycle: {
256
+ * mount: function () { this.fetchData(); },
257
+ * unmount: function () { console.log('bye'); },
258
+ * activate: function () { this.needRefresh && this.fetchData(); }
198
259
  * }
199
260
  * });
200
261
  *
201
- * // 组件中
202
- * const store = useFunnelStore();
203
- * store.fetchData();
262
+ * // 组件中(created 里传 this,自动绑定全部生命周期 + 自动销毁)
263
+ * created() {
264
+ * this.store = useFunnelStore(this);
265
+ * }
204
266
  *
205
- * // 页面销毁时
206
- * store.$destroy();
267
+ * // 不需要 lifecycle 时,不传参数,和 0.1.0 完全一样
268
+ * this.store = useFunnelStore();
207
269
  */
208
270
  function definePageStore(id, options) {
209
271
  if (!id || typeof options.state !== 'function') {
210
272
  throw new Error('[vue-page-store] 需要 id 和 state 函数');
211
273
  }
212
274
 
213
- // 缓存 Vue 引用,首次调用时从 store 的 vm 实例获取
214
- let _Vue = null;
275
+ var _Vue = null;
215
276
 
216
- return function useStore() {
277
+ return function useStore(componentVm) {
217
278
  if (storeRegistry.has(id)) {
218
- return storeRegistry.get(id);
279
+ var existing = storeRegistry.get(id);
280
+ if (componentVm) existing.bindTo(componentVm);
281
+ return existing;
219
282
  }
220
283
 
221
- // 自动获取 Vue 构造函数
222
284
  if (!_Vue) {
223
285
  try {
224
286
  _Vue = require('vue');
@@ -230,35 +292,14 @@ function definePageStore(id, options) {
230
292
  }
231
293
  }
232
294
 
233
- const store = createStoreInstance(_Vue, id, options);
295
+ var store = createStoreInstance(_Vue, id, options);
234
296
  storeRegistry.set(id, store);
297
+ if (componentVm) store.bindTo(componentVm);
235
298
  return store;
236
299
  };
237
300
  }
238
-
239
- /**
240
- * 将 store 的 state 属性转为可在模板中使用的 refs 对象
241
- *
242
- * @param {Object} store - pageStore 实例
243
- * @returns {Object} refs 对象(可解构赋值到 computed)
244
- *
245
- * @example
246
- * const { filters, loading } = storeToRefs(store);
247
- */
248
- function storeToRefs(store) {
249
- const refs = {};
250
- Object.keys(store.$state).forEach(function (key) {
251
- Object.defineProperty(refs, key, {
252
- enumerable: true,
253
- get: function () { return store[key]; },
254
- set: function (val) { store[key] = val; },
255
- });
256
- });
257
- return refs;
258
- }
259
- var index = { definePageStore, storeToRefs, storeRegistry };
301
+ var index = { definePageStore, storeRegistry };
260
302
 
261
303
  exports.default = index;
262
304
  exports.definePageStore = definePageStore;
263
305
  exports.storeRegistry = storeRegistry;
264
- exports.storeToRefs = storeToRefs;
package/dist/index.esm.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * vue-page-store v0.1.0
2
+ * vue-page-store v0.2.1
3
3
  * (c) 2026 weijianjun
4
4
  * @license MIT
5
5
  */
6
6
  /**
7
- * vue-page-store - Vue 2.6 页面级 Store
7
+ * vue-page-store 0.2.0 Vue 2.6 页面级 Store
8
8
  *
9
9
  * 状态、通信、生命周期,一个作用域全收。
10
10
  *
@@ -18,16 +18,17 @@
18
18
  */
19
19
 
20
20
  // Store 注册表(导出供调试 / devtools 使用)
21
- const storeRegistry = new Map();
21
+ var storeRegistry = new Map();
22
22
 
23
23
  function createStoreInstance(Vue, id, options) {
24
- const initialState = options.state();
25
- const getters = options.getters || {};
26
- const actions = options.actions || {};
24
+ var initialState = options.state();
25
+ var getters = options.getters || {};
26
+ var actions = options.actions || {};
27
+ var lifecycles = options.lifecycle || {};
27
28
 
28
29
  // --- 用一个隐藏的 Vue 实例承载响应式 state + computed getters ---
29
- const computedDefs = {};
30
- const store = { _disposed: false };
30
+ var computedDefs = {};
31
+ var store = { _disposed: false };
31
32
 
32
33
  Object.keys(getters).forEach(function (key) {
33
34
  computedDefs[key] = function () {
@@ -35,14 +36,21 @@ function createStoreInstance(Vue, id, options) {
35
36
  };
36
37
  });
37
38
 
38
- const vm = new Vue({
39
+ var vm = new Vue({
39
40
  data: function () {
40
- return { $$state: initialState };
41
+ return {
42
+ $$state: initialState,
43
+ $$status: {
44
+ mounted: false,
45
+ active: false
46
+ }
47
+ };
41
48
  },
42
49
  computed: computedDefs,
43
50
  });
44
51
 
45
- const rawState = vm.$data.$$state;
52
+ var rawState = vm.$data.$$state;
53
+ var rawStatus = vm.$data.$$status;
46
54
 
47
55
  // ====== state —— 代理到 vm.$$state ======
48
56
  Object.keys(initialState).forEach(function (key) {
@@ -67,14 +75,14 @@ function createStoreInstance(Vue, id, options) {
67
75
  });
68
76
 
69
77
  // ====== watch —— 声明式副作用,生命周期自动回收 ======
70
- const watches = options.watch || {};
78
+ var watches = options.watch || {};
71
79
  Object.entries(watches).forEach(function (_ref) {
72
- const path = _ref[0];
73
- const def = _ref[1];
74
- const handler = typeof def === 'function' ? def : def.handler;
75
- const watchOpts = { deep: true };
80
+ var path = _ref[0];
81
+ var def = _ref[1];
82
+ var handler = typeof def === 'function' ? def : def.handler;
83
+ var watchOpts = { deep: true };
76
84
  if (typeof def === 'object' && def.immediate) watchOpts.immediate = true;
77
- const expr = function () {
85
+ var expr = function () {
78
86
  return path.split('.').reduce(function (obj, k) { return obj && obj[k]; }, store);
79
87
  };
80
88
  vm.$watch(expr, handler.bind(store), watchOpts);
@@ -82,6 +90,7 @@ function createStoreInstance(Vue, id, options) {
82
90
 
83
91
  // ====== 内置方法 ======
84
92
  store.$state = rawState;
93
+ store.$status = rawStatus;
85
94
  store.$id = id;
86
95
 
87
96
  /**
@@ -89,37 +98,24 @@ function createStoreInstance(Vue, id, options) {
89
98
  * @param {Object|Function} partial - 要合并的对象,或 (state) => Object 函数
90
99
  */
91
100
  store.$patch = function (partial) {
92
- const obj = typeof partial === 'function' ? partial(rawState) : partial;
101
+ var obj = typeof partial === 'function' ? partial(rawState) : partial;
93
102
  Object.keys(obj).forEach(function (key) {
94
103
  Vue.set(rawState, key, obj[key]);
95
104
  });
96
105
  };
97
106
 
98
- /**
99
- * 订阅 state 变化
100
- * @param {Function} callback - (newState) => void
101
- * @returns {Function} 取消订阅函数
102
- */
103
- store.$subscribe = function (callback) {
104
- return vm.$watch(
105
- function () { return Object.assign({}, rawState); },
106
- callback,
107
- { deep: true }
108
- );
109
- };
110
-
111
107
  /**
112
108
  * 重置 state 到初始值
113
109
  */
114
110
  store.$reset = function () {
115
- const fresh = options.state();
111
+ var fresh = options.state();
116
112
  Object.keys(fresh).forEach(function (key) {
117
113
  rawState[key] = fresh[key];
118
114
  });
119
115
  };
120
116
 
121
117
  // ====== 内置事件总线(页面作用域隔离通信) ======
122
- const _listeners = {};
118
+ var _listeners = {};
123
119
 
124
120
  /**
125
121
  * 发射事件(仅当前 store 作用域内)
@@ -127,7 +123,7 @@ function createStoreInstance(Vue, id, options) {
127
123
  * @param {*} payload - 事件数据
128
124
  */
129
125
  store.$emit = function (event, payload) {
130
- const fns = _listeners[event];
126
+ var fns = _listeners[event];
131
127
  if (fns) fns.slice().forEach(function (fn) { fn(payload); });
132
128
  };
133
129
 
@@ -141,7 +137,7 @@ function createStoreInstance(Vue, id, options) {
141
137
  if (!_listeners[event]) _listeners[event] = [];
142
138
  _listeners[event].push(handler);
143
139
  return function () {
144
- const idx = _listeners[event].indexOf(handler);
140
+ var idx = _listeners[event].indexOf(handler);
145
141
  if (idx > -1) _listeners[event].splice(idx, 1);
146
142
  };
147
143
  };
@@ -154,17 +150,77 @@ function createStoreInstance(Vue, id, options) {
154
150
  store.$off = function (event, handler) {
155
151
  if (!_listeners[event]) return;
156
152
  if (handler) {
157
- const idx = _listeners[event].indexOf(handler);
153
+ var idx = _listeners[event].indexOf(handler);
158
154
  if (idx > -1) _listeners[event].splice(idx, 1);
159
155
  } else {
160
156
  delete _listeners[event];
161
157
  }
162
158
  };
163
159
 
160
+ // ====== 页面生命周期 ======
161
+
162
+ /** 触发生命周期钩子 + 广播事件 */
163
+ function runHook(name, payload) {
164
+ var hook = lifecycles[name];
165
+ if (typeof hook === 'function') {
166
+ hook.call(store, payload);
167
+ }
168
+ store.$emit('page:' + name, payload);
169
+ }
170
+
164
171
  /**
165
- * 销毁 store —— 清空事件、销毁 vm、移除注册
172
+ * 绑定到组件实例,自动挂载生命周期
173
+ *
174
+ * 原理:Vue 2 的 vm.$on('hook:xxx') 可监听组件自身生命周期事件,
175
+ * 这是 Vue 2 内置能力,不是 hack。
176
+ *
177
+ * 时序保证:
178
+ * 无 keep-alive → mounted → beforeDestroy
179
+ * 有 keep-alive → mounted → activated ⇄ deactivated → beforeDestroy
180
+ *
181
+ * 必须在 created 中调用(mounted 之前),否则 hook:mounted 捕获不到。
182
+ *
183
+ * @param {Vue} componentVm - 组件实例(通常传 this)
184
+ * @returns {Object} store - 支持链式调用
185
+ */
186
+ store.bindTo = function (componentVm) {
187
+ if (store._disposed) return store;
188
+
189
+ componentVm.$on('hook:mounted', function () {
190
+ rawStatus.mounted = true;
191
+ rawStatus.active = true;
192
+ runHook('mount');
193
+ });
194
+
195
+ componentVm.$on('hook:activated', function () {
196
+ rawStatus.active = true;
197
+ runHook('activate');
198
+ });
199
+
200
+ componentVm.$on('hook:deactivated', function () {
201
+ rawStatus.active = false;
202
+ runHook('deactivate');
203
+ });
204
+
205
+ componentVm.$on('hook:beforeDestroy', function () {
206
+ store.$destroy();
207
+ });
208
+
209
+ return store;
210
+ };
211
+
212
+ // ====== $destroy ======
213
+
214
+ /**
215
+ * 销毁 store —— 触发 unmount 钩子、清空事件、销毁 vm、移除注册
166
216
  */
167
217
  store.$destroy = function () {
218
+ if (store._disposed) return;
219
+
220
+ rawStatus.mounted = false;
221
+ rawStatus.active = false;
222
+ runHook('unmount');
223
+
168
224
  store._disposed = true;
169
225
  Object.keys(_listeners).forEach(function (key) { delete _listeners[key]; });
170
226
  vm.$destroy();
@@ -180,41 +236,47 @@ function createStoreInstance(Vue, id, options) {
180
236
  * 定义页面级 Store
181
237
  *
182
238
  * @param {string} id - 唯一标识
183
- * @param {Object} options - { state, getters, actions, watch }
184
- * @returns {Function} useStore - 调用即获取 / 创建 store 实例
239
+ * @param {Object} options - { state, getters, actions, watch, lifecycle }
240
+ * @returns {Function} useStore(vm?) - 调用即获取 / 创建 store 实例
185
241
  *
186
242
  * @example
187
- * const useFunnelStore = definePageStore('funnelDetail', {
188
- * state: () => ({ filters: {}, loading: false }),
243
+ * var useFunnelStore = definePageStore('funnelDetail', {
244
+ * state: function () { return { filters: {}, loading: false }; },
189
245
  * getters: {
190
- * isReady() { return !this.loading; }
246
+ * isReady: function () { return !this.loading; }
191
247
  * },
192
248
  * actions: {
193
- * async fetchData() { ... }
249
+ * fetchData: async function () { ... }
250
+ * },
251
+ * lifecycle: {
252
+ * mount: function () { this.fetchData(); },
253
+ * unmount: function () { console.log('bye'); },
254
+ * activate: function () { this.needRefresh && this.fetchData(); }
194
255
  * }
195
256
  * });
196
257
  *
197
- * // 组件中
198
- * const store = useFunnelStore();
199
- * store.fetchData();
258
+ * // 组件中(created 里传 this,自动绑定全部生命周期 + 自动销毁)
259
+ * created() {
260
+ * this.store = useFunnelStore(this);
261
+ * }
200
262
  *
201
- * // 页面销毁时
202
- * store.$destroy();
263
+ * // 不需要 lifecycle 时,不传参数,和 0.1.0 完全一样
264
+ * this.store = useFunnelStore();
203
265
  */
204
266
  function definePageStore(id, options) {
205
267
  if (!id || typeof options.state !== 'function') {
206
268
  throw new Error('[vue-page-store] 需要 id 和 state 函数');
207
269
  }
208
270
 
209
- // 缓存 Vue 引用,首次调用时从 store 的 vm 实例获取
210
- let _Vue = null;
271
+ var _Vue = null;
211
272
 
212
- return function useStore() {
273
+ return function useStore(componentVm) {
213
274
  if (storeRegistry.has(id)) {
214
- return storeRegistry.get(id);
275
+ var existing = storeRegistry.get(id);
276
+ if (componentVm) existing.bindTo(componentVm);
277
+ return existing;
215
278
  }
216
279
 
217
- // 自动获取 Vue 构造函数
218
280
  if (!_Vue) {
219
281
  try {
220
282
  _Vue = require('vue');
@@ -226,32 +288,12 @@ function definePageStore(id, options) {
226
288
  }
227
289
  }
228
290
 
229
- const store = createStoreInstance(_Vue, id, options);
291
+ var store = createStoreInstance(_Vue, id, options);
230
292
  storeRegistry.set(id, store);
293
+ if (componentVm) store.bindTo(componentVm);
231
294
  return store;
232
295
  };
233
296
  }
297
+ var index = { definePageStore, storeRegistry };
234
298
 
235
- /**
236
- * 将 store 的 state 属性转为可在模板中使用的 refs 对象
237
- *
238
- * @param {Object} store - pageStore 实例
239
- * @returns {Object} refs 对象(可解构赋值到 computed)
240
- *
241
- * @example
242
- * const { filters, loading } = storeToRefs(store);
243
- */
244
- function storeToRefs(store) {
245
- const refs = {};
246
- Object.keys(store.$state).forEach(function (key) {
247
- Object.defineProperty(refs, key, {
248
- enumerable: true,
249
- get: function () { return store[key]; },
250
- set: function (val) { store[key] = val; },
251
- });
252
- });
253
- return refs;
254
- }
255
- var index = { definePageStore, storeToRefs, storeRegistry };
256
-
257
- export { index as default, definePageStore, storeRegistry, storeToRefs };
299
+ export { index as default, definePageStore, storeRegistry };
package/dist/index.umd.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * vue-page-store v0.1.0
2
+ * vue-page-store v0.2.1
3
3
  * (c) 2026 weijianjun
4
4
  * @license MIT
5
5
  */
@@ -10,7 +10,7 @@
10
10
  })(this, (function (exports) { 'use strict';
11
11
 
12
12
  /**
13
- * vue-page-store - Vue 2.6 页面级 Store
13
+ * vue-page-store 0.2.0 Vue 2.6 页面级 Store
14
14
  *
15
15
  * 状态、通信、生命周期,一个作用域全收。
16
16
  *
@@ -24,16 +24,17 @@
24
24
  */
25
25
 
26
26
  // Store 注册表(导出供调试 / devtools 使用)
27
- const storeRegistry = new Map();
27
+ var storeRegistry = new Map();
28
28
 
29
29
  function createStoreInstance(Vue, id, options) {
30
- const initialState = options.state();
31
- const getters = options.getters || {};
32
- const actions = options.actions || {};
30
+ var initialState = options.state();
31
+ var getters = options.getters || {};
32
+ var actions = options.actions || {};
33
+ var lifecycles = options.lifecycle || {};
33
34
 
34
35
  // --- 用一个隐藏的 Vue 实例承载响应式 state + computed getters ---
35
- const computedDefs = {};
36
- const store = { _disposed: false };
36
+ var computedDefs = {};
37
+ var store = { _disposed: false };
37
38
 
38
39
  Object.keys(getters).forEach(function (key) {
39
40
  computedDefs[key] = function () {
@@ -41,14 +42,21 @@
41
42
  };
42
43
  });
43
44
 
44
- const vm = new Vue({
45
+ var vm = new Vue({
45
46
  data: function () {
46
- return { $$state: initialState };
47
+ return {
48
+ $$state: initialState,
49
+ $$status: {
50
+ mounted: false,
51
+ active: false
52
+ }
53
+ };
47
54
  },
48
55
  computed: computedDefs,
49
56
  });
50
57
 
51
- const rawState = vm.$data.$$state;
58
+ var rawState = vm.$data.$$state;
59
+ var rawStatus = vm.$data.$$status;
52
60
 
53
61
  // ====== state —— 代理到 vm.$$state ======
54
62
  Object.keys(initialState).forEach(function (key) {
@@ -73,14 +81,14 @@
73
81
  });
74
82
 
75
83
  // ====== watch —— 声明式副作用,生命周期自动回收 ======
76
- const watches = options.watch || {};
84
+ var watches = options.watch || {};
77
85
  Object.entries(watches).forEach(function (_ref) {
78
- const path = _ref[0];
79
- const def = _ref[1];
80
- const handler = typeof def === 'function' ? def : def.handler;
81
- const watchOpts = { deep: true };
86
+ var path = _ref[0];
87
+ var def = _ref[1];
88
+ var handler = typeof def === 'function' ? def : def.handler;
89
+ var watchOpts = { deep: true };
82
90
  if (typeof def === 'object' && def.immediate) watchOpts.immediate = true;
83
- const expr = function () {
91
+ var expr = function () {
84
92
  return path.split('.').reduce(function (obj, k) { return obj && obj[k]; }, store);
85
93
  };
86
94
  vm.$watch(expr, handler.bind(store), watchOpts);
@@ -88,6 +96,7 @@
88
96
 
89
97
  // ====== 内置方法 ======
90
98
  store.$state = rawState;
99
+ store.$status = rawStatus;
91
100
  store.$id = id;
92
101
 
93
102
  /**
@@ -95,37 +104,24 @@
95
104
  * @param {Object|Function} partial - 要合并的对象,或 (state) => Object 函数
96
105
  */
97
106
  store.$patch = function (partial) {
98
- const obj = typeof partial === 'function' ? partial(rawState) : partial;
107
+ var obj = typeof partial === 'function' ? partial(rawState) : partial;
99
108
  Object.keys(obj).forEach(function (key) {
100
109
  Vue.set(rawState, key, obj[key]);
101
110
  });
102
111
  };
103
112
 
104
- /**
105
- * 订阅 state 变化
106
- * @param {Function} callback - (newState) => void
107
- * @returns {Function} 取消订阅函数
108
- */
109
- store.$subscribe = function (callback) {
110
- return vm.$watch(
111
- function () { return Object.assign({}, rawState); },
112
- callback,
113
- { deep: true }
114
- );
115
- };
116
-
117
113
  /**
118
114
  * 重置 state 到初始值
119
115
  */
120
116
  store.$reset = function () {
121
- const fresh = options.state();
117
+ var fresh = options.state();
122
118
  Object.keys(fresh).forEach(function (key) {
123
119
  rawState[key] = fresh[key];
124
120
  });
125
121
  };
126
122
 
127
123
  // ====== 内置事件总线(页面作用域隔离通信) ======
128
- const _listeners = {};
124
+ var _listeners = {};
129
125
 
130
126
  /**
131
127
  * 发射事件(仅当前 store 作用域内)
@@ -133,7 +129,7 @@
133
129
  * @param {*} payload - 事件数据
134
130
  */
135
131
  store.$emit = function (event, payload) {
136
- const fns = _listeners[event];
132
+ var fns = _listeners[event];
137
133
  if (fns) fns.slice().forEach(function (fn) { fn(payload); });
138
134
  };
139
135
 
@@ -147,7 +143,7 @@
147
143
  if (!_listeners[event]) _listeners[event] = [];
148
144
  _listeners[event].push(handler);
149
145
  return function () {
150
- const idx = _listeners[event].indexOf(handler);
146
+ var idx = _listeners[event].indexOf(handler);
151
147
  if (idx > -1) _listeners[event].splice(idx, 1);
152
148
  };
153
149
  };
@@ -160,17 +156,77 @@
160
156
  store.$off = function (event, handler) {
161
157
  if (!_listeners[event]) return;
162
158
  if (handler) {
163
- const idx = _listeners[event].indexOf(handler);
159
+ var idx = _listeners[event].indexOf(handler);
164
160
  if (idx > -1) _listeners[event].splice(idx, 1);
165
161
  } else {
166
162
  delete _listeners[event];
167
163
  }
168
164
  };
169
165
 
166
+ // ====== 页面生命周期 ======
167
+
168
+ /** 触发生命周期钩子 + 广播事件 */
169
+ function runHook(name, payload) {
170
+ var hook = lifecycles[name];
171
+ if (typeof hook === 'function') {
172
+ hook.call(store, payload);
173
+ }
174
+ store.$emit('page:' + name, payload);
175
+ }
176
+
170
177
  /**
171
- * 销毁 store —— 清空事件、销毁 vm、移除注册
178
+ * 绑定到组件实例,自动挂载生命周期
179
+ *
180
+ * 原理:Vue 2 的 vm.$on('hook:xxx') 可监听组件自身生命周期事件,
181
+ * 这是 Vue 2 内置能力,不是 hack。
182
+ *
183
+ * 时序保证:
184
+ * 无 keep-alive → mounted → beforeDestroy
185
+ * 有 keep-alive → mounted → activated ⇄ deactivated → beforeDestroy
186
+ *
187
+ * 必须在 created 中调用(mounted 之前),否则 hook:mounted 捕获不到。
188
+ *
189
+ * @param {Vue} componentVm - 组件实例(通常传 this)
190
+ * @returns {Object} store - 支持链式调用
191
+ */
192
+ store.bindTo = function (componentVm) {
193
+ if (store._disposed) return store;
194
+
195
+ componentVm.$on('hook:mounted', function () {
196
+ rawStatus.mounted = true;
197
+ rawStatus.active = true;
198
+ runHook('mount');
199
+ });
200
+
201
+ componentVm.$on('hook:activated', function () {
202
+ rawStatus.active = true;
203
+ runHook('activate');
204
+ });
205
+
206
+ componentVm.$on('hook:deactivated', function () {
207
+ rawStatus.active = false;
208
+ runHook('deactivate');
209
+ });
210
+
211
+ componentVm.$on('hook:beforeDestroy', function () {
212
+ store.$destroy();
213
+ });
214
+
215
+ return store;
216
+ };
217
+
218
+ // ====== $destroy ======
219
+
220
+ /**
221
+ * 销毁 store —— 触发 unmount 钩子、清空事件、销毁 vm、移除注册
172
222
  */
173
223
  store.$destroy = function () {
224
+ if (store._disposed) return;
225
+
226
+ rawStatus.mounted = false;
227
+ rawStatus.active = false;
228
+ runHook('unmount');
229
+
174
230
  store._disposed = true;
175
231
  Object.keys(_listeners).forEach(function (key) { delete _listeners[key]; });
176
232
  vm.$destroy();
@@ -186,41 +242,47 @@
186
242
  * 定义页面级 Store
187
243
  *
188
244
  * @param {string} id - 唯一标识
189
- * @param {Object} options - { state, getters, actions, watch }
190
- * @returns {Function} useStore - 调用即获取 / 创建 store 实例
245
+ * @param {Object} options - { state, getters, actions, watch, lifecycle }
246
+ * @returns {Function} useStore(vm?) - 调用即获取 / 创建 store 实例
191
247
  *
192
248
  * @example
193
- * const useFunnelStore = definePageStore('funnelDetail', {
194
- * state: () => ({ filters: {}, loading: false }),
249
+ * var useFunnelStore = definePageStore('funnelDetail', {
250
+ * state: function () { return { filters: {}, loading: false }; },
195
251
  * getters: {
196
- * isReady() { return !this.loading; }
252
+ * isReady: function () { return !this.loading; }
197
253
  * },
198
254
  * actions: {
199
- * async fetchData() { ... }
255
+ * fetchData: async function () { ... }
256
+ * },
257
+ * lifecycle: {
258
+ * mount: function () { this.fetchData(); },
259
+ * unmount: function () { console.log('bye'); },
260
+ * activate: function () { this.needRefresh && this.fetchData(); }
200
261
  * }
201
262
  * });
202
263
  *
203
- * // 组件中
204
- * const store = useFunnelStore();
205
- * store.fetchData();
264
+ * // 组件中(created 里传 this,自动绑定全部生命周期 + 自动销毁)
265
+ * created() {
266
+ * this.store = useFunnelStore(this);
267
+ * }
206
268
  *
207
- * // 页面销毁时
208
- * store.$destroy();
269
+ * // 不需要 lifecycle 时,不传参数,和 0.1.0 完全一样
270
+ * this.store = useFunnelStore();
209
271
  */
210
272
  function definePageStore(id, options) {
211
273
  if (!id || typeof options.state !== 'function') {
212
274
  throw new Error('[vue-page-store] 需要 id 和 state 函数');
213
275
  }
214
276
 
215
- // 缓存 Vue 引用,首次调用时从 store 的 vm 实例获取
216
- let _Vue = null;
277
+ var _Vue = null;
217
278
 
218
- return function useStore() {
279
+ return function useStore(componentVm) {
219
280
  if (storeRegistry.has(id)) {
220
- return storeRegistry.get(id);
281
+ var existing = storeRegistry.get(id);
282
+ if (componentVm) existing.bindTo(componentVm);
283
+ return existing;
221
284
  }
222
285
 
223
- // 自动获取 Vue 构造函数
224
286
  if (!_Vue) {
225
287
  try {
226
288
  _Vue = require('vue');
@@ -232,38 +294,17 @@
232
294
  }
233
295
  }
234
296
 
235
- const store = createStoreInstance(_Vue, id, options);
297
+ var store = createStoreInstance(_Vue, id, options);
236
298
  storeRegistry.set(id, store);
299
+ if (componentVm) store.bindTo(componentVm);
237
300
  return store;
238
301
  };
239
302
  }
240
-
241
- /**
242
- * 将 store 的 state 属性转为可在模板中使用的 refs 对象
243
- *
244
- * @param {Object} store - pageStore 实例
245
- * @returns {Object} refs 对象(可解构赋值到 computed)
246
- *
247
- * @example
248
- * const { filters, loading } = storeToRefs(store);
249
- */
250
- function storeToRefs(store) {
251
- const refs = {};
252
- Object.keys(store.$state).forEach(function (key) {
253
- Object.defineProperty(refs, key, {
254
- enumerable: true,
255
- get: function () { return store[key]; },
256
- set: function (val) { store[key] = val; },
257
- });
258
- });
259
- return refs;
260
- }
261
- var index = { definePageStore, storeToRefs, storeRegistry };
303
+ var index = { definePageStore, storeRegistry };
262
304
 
263
305
  exports.default = index;
264
306
  exports.definePageStore = definePageStore;
265
307
  exports.storeRegistry = storeRegistry;
266
- exports.storeToRefs = storeToRefs;
267
308
 
268
309
  Object.defineProperty(exports, '__esModule', { value: true });
269
310
 
@@ -1,11 +1,11 @@
1
1
  /*!
2
- * vue-page-store v0.1.0
2
+ * vue-page-store v0.2.1
3
3
  * (c) 2026 weijianjun
4
4
  * @license MIT
5
5
  */
6
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";
7
7
  /**
8
- * vue-page-store - Vue 2.6 页面级 Store
8
+ * vue-page-store 0.2.0 Vue 2.6 页面级 Store
9
9
  *
10
10
  * 状态、通信、生命周期,一个作用域全收。
11
11
  *
@@ -16,4 +16,4 @@
16
16
  *
17
17
  * @author weijianjun
18
18
  * @license MIT
19
- */const t=new Map;function n(e,n){if(!e||"function"!=typeof n.state)throw new Error("[vue-page-store] 需要 id 和 state 函数");let o=null;return function(){if(t.has(e))return t.get(e);if(!o)try{o=require("vue"),o.default&&(o=o.default)}catch(e){throw new Error("[vue-page-store] 无法自动获取 Vue,请确保 vue 已安装")}const c=function(e,n,o){const c=o.state(),r=o.getters||{},f=o.actions||{},i={},u={_disposed:!1};Object.keys(r).forEach(function(e){i[e]=function(){return r[e].call(u)}});const s=new e({data:function(){return{$$state:c}},computed:i}),a=s.$data.$$state;Object.keys(c).forEach(function(e){Object.defineProperty(u,e,{enumerable:!0,get:function(){return a[e]},set:function(t){a[e]=t}})}),Object.keys(r).forEach(function(e){Object.defineProperty(u,e,{enumerable:!0,get:function(){return s[e]}})}),Object.keys(f).forEach(function(e){u[e]=f[e].bind(u)});const d=o.watch||{};Object.entries(d).forEach(function(e){const t=e[0],n=e[1],o="function"==typeof n?n:n.handler,c={deep:!0};"object"==typeof n&&n.immediate&&(c.immediate=!0),s.$watch(function(){return t.split(".").reduce(function(e,t){return e&&e[t]},u)},o.bind(u),c)}),u.$state=a,u.$id=n,u.$patch=function(t){const n="function"==typeof t?t(a):t;Object.keys(n).forEach(function(t){e.set(a,t,n[t])})},u.$subscribe=function(e){return s.$watch(function(){return Object.assign({},a)},e,{deep:!0})},u.$reset=function(){const e=o.state();Object.keys(e).forEach(function(t){a[t]=e[t]})};const l={};return u.$emit=function(e,t){const n=l[e];n&&n.slice().forEach(function(e){e(t)})},u.$on=function(e,t){return l[e]||(l[e]=[]),l[e].push(t),function(){const n=l[e].indexOf(t);n>-1&&l[e].splice(n,1)}},u.$off=function(e,t){if(l[e])if(t){const n=l[e].indexOf(t);n>-1&&l[e].splice(n,1)}else delete l[e]},u.$destroy=function(){u._disposed=!0,Object.keys(l).forEach(function(e){delete l[e]}),s.$destroy(),t.delete(n)},u._vm=s,u}(o,e,n);return t.set(e,c),c}}function o(e){const t={};return Object.keys(e.$state).forEach(function(n){Object.defineProperty(t,n,{enumerable:!0,get:function(){return e[n]},set:function(t){e[n]=t}})}),t}var c={definePageStore:n,storeToRefs:o,storeRegistry:t};e.default=c,e.definePageStore=n,e.storeRegistry=t,e.storeToRefs=o,Object.defineProperty(e,"__esModule",{value:!0})});
19
+ */var t=new Map;function n(e,n){if(!e||"function"!=typeof n.state)throw new Error("[vue-page-store] 需要 id 和 state 函数");var o=null;return function(i){if(t.has(e)){var r=t.get(e);return i&&r.bindTo(i),r}if(!o)try{(o=require("vue")).default&&(o=o.default)}catch(e){throw new Error("[vue-page-store] 无法自动获取 Vue,请确保 vue 已安装")}var c=function(e,n,o){var i=o.state(),r=o.getters||{},c=o.actions||{},u=o.lifecycle||{},f={},a={_disposed:!1};Object.keys(r).forEach(function(e){f[e]=function(){return r[e].call(a)}});var s=new e({data:function(){return{$$state:i,$$status:{mounted:!1,active:!1}}},computed:f}),d=s.$data.$$state,v=s.$data.$$status;Object.keys(i).forEach(function(e){Object.defineProperty(a,e,{enumerable:!0,get:function(){return d[e]},set:function(t){d[e]=t}})}),Object.keys(r).forEach(function(e){Object.defineProperty(a,e,{enumerable:!0,get:function(){return s[e]}})}),Object.keys(c).forEach(function(e){a[e]=c[e].bind(a)});var l=o.watch||{};Object.entries(l).forEach(function(e){var t=e[0],n=e[1],o="function"==typeof n?n:n.handler,i={deep:!0};"object"==typeof n&&n.immediate&&(i.immediate=!0),s.$watch(function(){return t.split(".").reduce(function(e,t){return e&&e[t]},a)},o.bind(a),i)}),a.$state=d,a.$status=v,a.$id=n,a.$patch=function(t){var n="function"==typeof t?t(d):t;Object.keys(n).forEach(function(t){e.set(d,t,n[t])})},a.$reset=function(){var e=o.state();Object.keys(e).forEach(function(t){d[t]=e[t]})};var p={};function y(e,t){var n=u[e];"function"==typeof n&&n.call(a,t),a.$emit("page:"+e,t)}return a.$emit=function(e,t){var n=p[e];n&&n.slice().forEach(function(e){e(t)})},a.$on=function(e,t){return p[e]||(p[e]=[]),p[e].push(t),function(){var n=p[e].indexOf(t);n>-1&&p[e].splice(n,1)}},a.$off=function(e,t){if(p[e])if(t){var n=p[e].indexOf(t);n>-1&&p[e].splice(n,1)}else delete p[e]},a.bindTo=function(e){return a._disposed||(e.$on("hook:mounted",function(){v.mounted=!0,v.active=!0,y("mount")}),e.$on("hook:activated",function(){v.active=!0,y("activate")}),e.$on("hook:deactivated",function(){v.active=!1,y("deactivate")}),e.$on("hook:beforeDestroy",function(){a.$destroy()})),a},a.$destroy=function(){a._disposed||(v.mounted=!1,v.active=!1,y("unmount"),a._disposed=!0,Object.keys(p).forEach(function(e){delete p[e]}),s.$destroy(),t.delete(n))},a._vm=s,a}(o,e,n);return t.set(e,c),i&&c.bindTo(i),c}}var o={definePageStore:n,storeRegistry:t};e.default=o,e.definePageStore=n,e.storeRegistry=t,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.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Vue 2.6 页面级 Store —— 状态、通信、生命周期,一个作用域全收",
5
5
  "author": "weijianjun",
6
6
  "license": "MIT",