Vue3 Pinia Store 生命周期管理
在 Vue 3 的 Pinia 中,defineStore
定义的 store 本身没有 onUnmounted
生命周期钩子。但你可以通过以下方式实现类似效果,具体执行机制如下:
1. 在组件中使用 onUnmounted
Pinia store 是独立于组件的,其生命周期不与组件绑定。推荐在组件中使用 onUnmounted
清理 store 相关逻辑:
vue
复制
下载
<script setup> import { useMyStore } from './store'; import { onUnmounted } from 'vue';const store = useMyStore();// 订阅状态变化(示例) const unsubscribe = store.$subscribe((mutation, state) => {console.log('状态变化', state); });// 组件卸载时清理 onUnmounted(() => {unsubscribe(); // 取消订阅store.$dispose?.(); // 手动调用 dispose 方法(如果存在) }); </script>
2. 在 Store 中模拟卸载逻辑
通过 $onAction
或自定义方法监听组件的卸载行为(需要组件主动触发):
ts
复制
下载
// store.js import { defineStore } from 'pinia';export const useMyStore = defineStore('myStore', {actions: {registerComponent() {// 模拟注册逻辑console.log('组件注册');return () => { console.log('执行清理') }; // 返回清理函数}} });
vue
复制
下载
<!-- 组件中 --> <script setup> import { useMyStore } from './store'; import { onUnmounted } from 'vue';const store = useMyStore(); const cleanup = store.registerComponent();onUnmounted(() => {cleanup(); // 手动触发清理 }); </script>
3. Store 的自动销毁机制
-
默认行为:Pinia store 是单例的,除非所有引用它的组件都卸载且没有其他引用,才会被垃圾回收。
-
手动销毁:调用
store.$dispose()
可主动销毁 store(重置状态、移除所有订阅):ts
复制
下载
// 在组件中 onUnmounted(() => {store.$dispose(); // 销毁 store 实例 });
调用后,该 store 实例的状态和订阅会被清除,下次调用
useMyStore()
会创建新实例。
执行机制总结
场景 | 执行方式 | 适用情况 |
---|---|---|
组件卸载时清理订阅 | 在组件 onUnmounted 中调用 unsubscribe() 或 store.$dispose() | 清理事件监听、定时器等 |
主动销毁 store 实例 | 调用 store.$dispose() 重置状态并移除所有订阅 | 组件完全不再需要该 store 时 |
Store 全局单例 | 默认所有组件共享同一实例,无显式销毁时一直存在 | 多数场景 |
最佳实践
-
优先在组件中清理:在
onUnmounted
中取消订阅(如$subscribe
、$onAction
返回的函数)。 -
避免直接操作 DOM:Store 应保持与 DOM 无关,清理逻辑交给组件。
-
谨慎使用
$dispose
:仅在确定该 store 实例完全不再需要时使用(如路由切换后组件完全销毁)。
关键点:Pinia store 本身无生命周期钩子,其存活时间由引用它的组件和手动管理决定。清理逻辑需开发者显式处理。