Skip to content

Vuex 4 与 Pinia

Vuex 4 核心概念

Vuex 是 Vue 的官方状态管理库,采用集中式存储管理应用的所有组件的状态。

核心组成

概念作用示例
State单一状态树,存储数据源state: { count: 0 }
Getters从 state 派生的计算属性getters: { doubleCount: (state) => state.count * 2 }
Mutations同步修改 state 的方法mutations: { increment(state) { state.count++ } }
Actions提交 mutations,可包含异步操作actions: { asyncIncrement({ commit }) { setTimeout(() => commit('increment'), 1000) } }
Modules将 store 分割成模块modules: { user: userModule }

典型使用流程

javascript
// store/index.js
import { createStore } from 'vuex'

export default createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  },
  actions: {
    asyncIncrement({ commit }) {
      setTimeout(() => commit('increment'), 1000)
    }
  },
  getters: {
    doubleCount: state => state.count * 2
  }
})

// 组件中使用
import { useStore } from 'vuex'

export default {
  setup() {
    const store = useStore()
    
    // 访问 state
    console.log(store.state.count)
    
    // 触发 mutation
    store.commit('increment')
    
    // 触发 action
    store.dispatch('asyncIncrement')
    
    // 使用 getter
    console.log(store.getters.doubleCount)
    
    return {}
  }
}

优缺点

  • 优点:
    • 官方维护,稳定性高
    • 严格的流程控制(mutations必须是同步)
  • 缺点:
    • 样板代码较多
    • TypeScript 支持一般
    • 模块嵌套复杂

Pinia 核心概念

Pinia 是 Vue 官方推荐的新一代状态管理库,相比 Vuex 更简单直观。

核心改进

  • 去掉 mutations,只有 state/getters/actions
  • 完整的 TypeScript 支持
  • 更简洁的 API
  • 支持组合式 API 和选项式 API
  • 模块化设计开箱即用

核心组成

概念作用与 Vuex 对比
State存储数据源同 Vuex
Getters计算属性同 Vuex
Actions同步/异步操作合并了 Vuex 的 mutations 和 actions
Stores独立的状态单元替代 Vuex 的 modules,无需嵌套

典型使用流程

javascript
// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  },
  actions: {
    increment() {
      this.count++
    },
    async asyncIncrement() {
      setTimeout(() => this.increment(), 1000)
    }
  }
})

// 组件中使用
import { useCounterStore } from '@/stores/counter'

export default {
  setup() {
    const counter = useCounterStore()
    
    // 访问 state
    console.log(counter.count)
    
    // 调用 action
    counter.increment()
    counter.asyncIncrement()
    
    // 使用 getter
    console.log(counter.doubleCount)
    
    // 直接修改 state (不推荐)
    counter.count++
    
    return {}
  }
}

高级特性

组合式 Store

javascript
export const useUserStore = defineStore('user', () => {
  const user = ref(null)
  
  function login() {
    // 登录逻辑
  }
  
  return { user, login }
})

插件系统

javascript
// 持久化插件示例
pinia.use(({ store }) => {
  const saved = localStorage.getItem(store.$id)
  if (saved) {
    store.$patch(JSON.parse(saved))
  }
  store.$subscribe((mutation, state) => {
    localStorage.setItem(store.$id, JSON.stringify(state))
  })
})

优缺点

  • 优点:
    • 更简洁的 API
    • 完美的 TypeScript 支持
    • 自动代码分割
    • 更轻量
  • 缺点:
    • 相对较新,生态还在成长
    • 迁移成本(对已有 Vuex 项目)

Vuex 与 Pinia 对比

特性Vuex 4Pinia
API 复杂度高(mutations/actions分离)低(只有 actions)
TypeScript 支持一般优秀
代码组织需要 modules天然模块化
体积较大更轻量
学习曲线较陡峭平缓
DevTools 支持完善完善
Vue 官方推荐是(旧项目)是(新项目)

迁移建议

  1. 新项目:直接使用 Pinia
  2. 已有 Vuex 项目:
    • 小型项目:逐步迁移到 Pinia
    • 大型项目:继续使用 Vuex,新功能用 Pinia

最佳实践

通用模式

  • 将业务逻辑放在 store 中
  • 组件只负责展示和触发 actions
  • 复杂数据操作使用 getters

项目结构

src/
  stores/
    user.js       # 用户相关状态
    products.js   # 产品相关状态
    cart.js       # 购物车状态
    index.js      # Pinia 初始化

TypeScript 增强

typescript
interface UserState {
  name: string
  age: number
}

export const useUserStore = defineStore('user', {
  state: (): UserState => ({
    name: '',
    age: 0
  })
})
编程洪同学服务平台是一个广泛收集编程相关内容和资源,旨在满足编程爱好者和专业开发人员的需求的网站。无论您是初学者还是经验丰富的开发者,都可以在这里找到有用的信息和资料,我们将助您提升编程技能和知识。
专业开发
高端定制
售后无忧
站内资源均为本站制作或收集于互联网等平台,如有侵权,请第一时间联系本站,敬请谅解!本站资源仅限于学习与参考,严禁用于各种非法活动,否则后果自行负责,本站概不承担!