Pinia 替代 localStorage 的常规使用场景

在现代 Vue 工程化项目中,通常推荐使用 Pinia(或 Vuex)来管理状态,而不是直接使用 localStorage。我来解释下具体原因和使用方式:

1、为什么使用 Pinia 替代 localStorage:

// 使用 Pinia 的优势:
- 状态集中管理,更容易维护
- 支持响应式
- 支持开发工具调试
- 支持 TypeScript
- 可以配合 localStorage 实现数据持久化
- 状态变更可追踪

2、一个典型的用户认证 Store 示例:

// stores/auth.js
import { defineStore } from 'pinia'

export const useAuthStore = defineStore('auth', {
  state: () => ({
    isAuthenticated: false,
    token: null,
    user: null
  }),
  
  actions: {
    login(credentials) {
      // 登录逻辑
      // ...
      this.isAuthenticated = true;
      this.token = 'token-value';
      // 如果需要持久化,可以同时存储到 localStorage
      localStorage.setItem('token', this.token);
    },
    
    logout() {
      this.isAuthenticated = false;
      this.token = null;
      this.user = null;
      localStorage.removeItem('token');
    },
    
    // 初始化状态,比如页面刷新后
    initializeAuth() {
      const token = localStorage.getItem('token');
      if (token) {
        this.token = token;
        this.isAuthenticated = true;
      }
    }
  },
  
  getters: {
    // 计算属性
    isUserLoggedIn: (state) => state.isAuthenticated,
    currentUser: (state) => state.user
  }
})

3、在路由守卫中使用:

// router/index.js
import { useAuthStore } from '@/stores/auth'

router.beforeEach((to, from, next) => {
  const authStore = useAuthStore()
  
  // 需要认证的路由
  if (to.meta.requiresAuth && !authStore.isAuthenticated) {
    next({ name: 'login' })
  } else {
    next()
  }
})

4、在组件中使用:

<template>
  <div>
    <h1>Admin Dashboard</h1>
    <div v-if="authStore.isUserLoggedIn">
      Welcome, {{ authStore.currentUser?.name }}
    </div>
  </div>
</template>

<script setup>
import { useAuthStore } from '@/stores/auth'

const authStore = useAuthStore()

// 组件内使用
const handleLogout = () => {
  authStore.logout()
}
</script>

5、配合插件实现自动持久化(可选):

// 使用 pinia-plugin-persistedstate 插件
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

// 在 store 中启用持久化
export const useAuthStore = defineStore('auth', {
  state: () => ({
    // ...
  }),
  persist: true // 启用持久化
})

6、最佳实践:

// 1. 分层管理
// api/auth.js - API 请求
export const authApi = {
  login: (credentials) => axios.post('/api/login', credentials),
  logout: () => axios.post('/api/logout')
}

// stores/auth.js - 状态管理
export const useAuthStore = defineStore('auth', {
  // ...store 配置
})

// 2. 错误处理
actions: {
  async login(credentials) {
    try {
      const response = await authApi.login(credentials)
      this.setUser(response.data.user)
      return Promise.resolve('Success')
    } catch (error) {
      return Promise.reject(error)
    }
  }
}

// 3. 类型支持
interface User {
  id: number
  name: string
  email: string
}

interface AuthState {
  user: User | null
  isAuthenticated: boolean
  token: string | null
}

使用 Pinia 的主要好处是:

  1. 状态管理更规范
  2. 数据响应式,自动更新视图
  3. 可以配合 TypeScript 获得更好的类型支持
  4. 支持开发工具,方便调试
  5. 可以实现状态持久化
  6. 便于测试和维护
  7. 状态变更可追踪,便于调试

当然,在某些简单的场景下,直接使用 localStorage 也是可以的。选择哪种方式主要取决于:

  • 项目规模和复杂度
  • 团队规模和开发规范
  • 是否需要状态响应式
  • 是否需要更好的开发体验
  • 是否需要类型支持

在中大型项目中,推荐使用 Pinia 来管理状态,可以获得更好的可维护性和开发体验。

posted @ 2025-01-14 16:06  非法关键字  阅读(492)  评论(0)    收藏  举报