1. 状态的缓存策略
- 局部缓存:对于不经常变化且计算成本高的状态,在组件内使用
computed
缓存。例如,在一个电商应用中计算购物车总价,可以通过 computed
缓存,只有购物车商品变化时才重新计算。
<template>
<div>Total: {{ totalPrice }}</div>
</template>
<script setup>
import { useCartStore } from '@/stores/cart'
const cartStore = useCartStore()
const totalPrice = computed(() => {
let total = 0
cartStore.items.forEach(item => {
total += item.price * item.quantity
})
return total
})
</script>
- 全局缓存:在 Pinia store 中,对于整个应用级别不常变化的数据,使用
readonly
进行缓存。如应用的配置信息,可以在 store 中这样定义:
import { defineStore } from 'pinia'
export const useConfigStore = defineStore('config', () => {
const config = reactive({
// 配置项
apiBaseUrl: 'https://example.com/api'
})
return {
config: readonly(config)
}
})
2. 数据清理机制
- 监听路由变化:当用户切换页面时,清理与当前页面相关的状态。例如,在一个多页面应用中,使用 Vue Router 的
beforeEach
守卫,在切换路由前清理特定 store 中的状态。
import { createRouter, createWebHistory } from 'vue-router'
import { usePageStore } from '@/stores/page'
const router = createRouter({
history: createWebHistory(),
routes: [
// 路由配置
]
})
router.beforeEach((to, from) => {
const pageStore = usePageStore()
// 清理与 from 页面相关的状态
if (from.name === 'oldPage') {
pageStore.clearOldPageState()
}
})
export default router
- 手动清理:在组件销毁时,手动清理在 Pinia store 中创建的临时数据。在 Vue 组件的
beforeUnmount
钩子中调用 store 的清理方法。
<template>
<div>Component with state</div>
</template>
<script setup>
import { onBeforeUnmount } from 'vue'
import { useTempStore } from '@/stores/temp'
const tempStore = useTempStore()
// 创建临时数据
tempStore.createTempData()
onBeforeUnmount(() => {
tempStore.clearTempData()
})
</script>
3. 优化状态存储
- 精简状态:只存储必要的状态数据,避免存储无用或可以通过其他状态推导出来的数据。例如,在一个用户信息管理系统中,如果用户的年龄可以通过出生日期计算得出,那么就不应该单独存储年龄状态。
- 合理使用数据结构:对于大量状态数据,选择合适的数据结构。如果状态数据具有层级关系,可以使用树状结构;如果需要快速查找,可以使用 Map 或 Set。比如,在管理用户权限时,使用 Map 存储权限信息可以快速根据权限名查找权限值。
import { defineStore } from 'pinia'
export const useAuthStore = defineStore('auth', () => {
const permissions = new Map()
permissions.set('read', true)
permissions.set('write', false)
return {
permissions
}
})
4. 批量处理状态更新
- 使用事务:在 Pinia 中,利用
store.$patch
方法进行批量状态更新,减少不必要的重新渲染。例如,在一个待办事项应用中,当完成多个任务时,使用 $patch
一次性更新任务状态。
import { useTodoStore } from '@/stores/todo'
const todoStore = useTodoStore()
const completedTaskIds = [1, 2, 3]
todoStore.$patch(state => {
completedTaskIds.forEach(id => {
const task = state.tasks.find(t => t.id === id)
if (task) {
task.completed = true
}
})
})