@tianyio/quality-helper
Version:
A comprehensive quality helper tool for project scaffolding and management
227 lines (199 loc) • 6.03 kB
text/typescript
import { ref, computed, watch } from 'vue'
import { defineStore, acceptHMRUpdate } from 'pinia'
// 定义 Store 状态类型
interface CounterState {
count: number
name: string
history: number[]
lastUpdated: string | null
}
// 本地存储键名
const STORAGE_KEY = 'counter-store'
// 从本地存储恢复状态
function restoreFromStorage(): Partial<CounterState> {
try {
const stored = localStorage.getItem(STORAGE_KEY)
return stored ? JSON.parse(stored) : {}
} catch (error) {
console.warn('Failed to restore counter state from localStorage:', error)
return {}
}
}
// 保存状态到本地存储
function saveToStorage(state: CounterState) {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(state))
} catch (error) {
console.warn('Failed to save counter state to localStorage:', error)
}
}
/**
* 计数器 Store 示例 - 使用 Pinia 3.0.3 最佳实践
* 包含数据持久化、类型安全、HMR 支持等特性
*/
export const useCounterStore = defineStore('counter', () => {
// 从本地存储恢复初始状态
const restored = restoreFromStorage()
// 状态 (state) - 使用 ref 实现响应式
const count = ref(restored.count ?? 0)
const name = ref(restored.name ?? 'Vue3 + Pinia 3.0.3')
const history = ref<number[]>(restored.history ?? [])
const lastUpdated = ref<string | null>(restored.lastUpdated ?? null)
// 计算属性 (getters) - 使用 computed
const doubleCount = computed(() => count.value * 2)
const isEven = computed(() => count.value % 2 === 0)
const isPositive = computed(() => count.value > 0)
const historyLength = computed(() => history.value.length)
const averageValue = computed(() => {
if (history.value.length === 0) return 0
return history.value.reduce((sum, val) => sum + val, 0) / history.value.length
})
// 私有方法:更新历史记录和时间戳
function updateMetadata() {
history.value.push(count.value)
// 限制历史记录长度
if (history.value.length > 50) {
history.value = history.value.slice(-50)
}
lastUpdated.value = new Date().toISOString()
}
// 方法 (actions)
function increment() {
count.value++
updateMetadata()
}
function decrement() {
count.value--
updateMetadata()
}
function reset() {
count.value = 0
history.value = []
lastUpdated.value = new Date().toISOString()
}
function setCount(newCount: number) {
if (typeof newCount !== 'number' || !Number.isFinite(newCount)) {
throw new Error('Count must be a finite number')
}
count.value = newCount
updateMetadata()
}
function setName(newName: string) {
if (typeof newName !== 'string' || newName.trim().length === 0) {
throw new Error('Name must be a non-empty string')
}
name.value = newName.trim()
lastUpdated.value = new Date().toISOString()
}
// 批量操作
function addToCount(value: number) {
if (typeof value !== 'number' || !Number.isFinite(value)) {
throw new Error('Value must be a finite number')
}
count.value += value
updateMetadata()
}
function multiplyCount(multiplier: number) {
if (typeof multiplier !== 'number' || !Number.isFinite(multiplier)) {
throw new Error('Multiplier must be a finite number')
}
count.value *= multiplier
updateMetadata()
}
// 异步操作示例
async function incrementAsync(delay: number = 1000): Promise<void> {
if (delay < 0) {
throw new Error('Delay must be non-negative')
}
return new Promise<void>((resolve, reject) => {
const timeoutId = setTimeout(() => {
try {
increment()
resolve()
} catch (error) {
reject(error)
}
}, delay)
// 可以在这里添加取消逻辑
// 例如:store.cancelAsyncOperation = () => clearTimeout(timeoutId)
})
}
// 模拟 API 调用
async function fetchCountFromAPI(): Promise<void> {
try {
// 模拟 API 延迟
await new Promise(resolve => setTimeout(resolve, 1000))
// 模拟 API 响应
const apiResponse = Math.floor(Math.random() * 100)
setCount(apiResponse)
if (import.meta.env.DEV) {
console.log('📡 Fetched count from API:', apiResponse)
}
} catch (error) {
console.error('Failed to fetch count from API:', error)
throw error
}
}
// 清除历史记录
function clearHistory() {
history.value = []
lastUpdated.value = new Date().toISOString()
}
// 导出状态用于备份
function exportState(): CounterState {
return {
count: count.value,
name: name.value,
history: [...history.value],
lastUpdated: lastUpdated.value
}
}
// 导入状态用于恢复
function importState(state: Partial<CounterState>) {
if (state.count !== undefined) count.value = state.count
if (state.name !== undefined) name.value = state.name
if (state.history !== undefined) history.value = [...state.history]
if (state.lastUpdated !== undefined) lastUpdated.value = state.lastUpdated
}
// 数据持久化:监听状态变化并自动保存
watch(
() => ({ count: count.value, name: name.value, history: history.value, lastUpdated: lastUpdated.value }),
(state) => {
saveToStorage(state as CounterState)
},
{ deep: true, immediate: false }
)
return {
// 状态
count,
name,
history,
lastUpdated,
// 计算属性
doubleCount,
isEven,
isPositive,
historyLength,
averageValue,
// 基础方法
increment,
decrement,
reset,
setCount,
setName,
// 扩展方法
addToCount,
multiplyCount,
clearHistory,
// 异步方法
incrementAsync,
fetchCountFromAPI,
// 工具方法
exportState,
importState
}
})
// HMR 支持 (Hot Module Replacement)
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useCounterStore, import.meta.hot))
}