# 一、pinia 详细用法
# (1)安装 pinia
| yarn add pinia | |
| # 或者 | |
| npm install pinia | 
# (2)创建状态仓库
- 先得知道 pinia 是用
defineStore()定义的,它的第一个参数要求是一个独一无二的名字
defineStore()的第二个参数可接受两类值:Setup 函数或 Option 对象。
pinia 传入 Option 对象的核心概念包括:
- state: 用来定义一些变量
- getters: 类似于计算属性
- actions:里面是一些方法,在里面可以请求接口操作
| import {defineStore} from 'pinia' | |
| const useUser = defineStore("user",{ | |
| state:() => ({ // 用来定义一些变量 | |
| mycount: 1, | |
| }), | |
| getters: { // 类似于计算属性 | |
| double: (state) => state.mycount * 2, | |
| }, | |
| actions: { // 里面是一些方法,在里面可以请求接口操作 | |
| increment() { | |
| this.mycount++ | |
| }, | |
| async registerUser(login, password) { // 异步操作 | |
| await api.post({ login, password }) | |
|         } | |
|     } | |
| }) | |
| export default useUser | 
# (3)项目在 main.js 文件中引入并注册使用
在 main.js 中引用,挂载为全局对象
| import { createPinia } from "pinia"; | |
| const pinia = createPinia() | |
| app.use(pinia) | 
# (4)获取 pinia 的变量
引入后直接使用即可,对比 vuex 会方便很多
| <template> | |
|   <div> | |
| 看看state中的值: | |
| 使用getters里面的计算属性: | |
|   </div> | |
| </template> | |
| <script setup> | |
| // 需要引入刚刚创建的store | |
| import useUser from '@/stores/index' | |
| // 得调用一下 | |
| const useUser = useUser() | |
| </script> | 
注意: 不能对 useUser 进行解构否则会失去响应式, 但官方提供了 storeToRefs 这个方法用来解构,如下所示:
| // 用官方提供 storeToRefs 解构 | |
| const {mycount} = storeToRefs(useUser) | 
# (5)更新变量
方法一: pinia 可以直接修改 state 里面的变量,这是和 vuex 区别最大的地方,也是使的 pinia 使用起来更加灵活方便
| <template> | |
|   <div> | |
| 看看pinia的值: | |
| <button @click="update">修改pinia数据</button> | |
|   </div> | |
| </template> | |
| <script setup> | |
| import useUser from '@/stores/index' | |
| const useUser = useUser() | |
| // 直接就能修改 | |
| function update(){  | |
| useUser.mycount++ | |
| } | 
缺点: 如果一次修改很多个不方便
方法二: $patch 函数修改
| function update(){ | |
|     // 一次性修改多个状态 | |
| useUser.$patch({ | |
| name:"天天鸭", | |
| age:20 | |
| }) | |
| } | 
# 二、vuex 详细用法
# (1)安装 vuex
| npm install vuex@next --save | |
| # 或者 | |
| yarn add vuex@next --save | 
# (2)创建状态仓库
vuex 的核心概念包括:
- state: 用来定义一些变量
- getters: 类似于计算属性
- mutations: 是用来触发事件 (必须是同步函数),通过这个事件修改 state 里面的变量
- Actions:用于提交 mutations,可以包含任意异步操作,在里面可以请求接口操作
- Modules:将 store 分割成模块,每个模块拥有自己的 state、getters、mutations 和 actions。
创建一个 store 文件夹,里面创建 index.js 文件
| import Vue from "vue" | |
| import Vuex from "vuex" | |
| Vue.use(Vuex); | |
| export default new Vuex.Store({ | |
| state:{ // 用来定义一些变量 | |
| userName: "", | |
| count: 1, | |
| }, | |
| getters: { // 类似于计算属性 | |
| doneTodos (state) { | |
| return state.count*2 | |
|         } | |
| }, | |
| mutations:{ // 是用来触发事件,修改 userName | |
| saveName (state,userName){ | |
| state.userName = userName; | |
| }, | |
| }, | |
| actions: { // 用于提交 mutations,可以包含任意异步操作,, 在里面可以请求接口操作 | |
| increment (context) { | |
| context.commit('saveName') | |
|         } | |
|     } | |
| }) | 
# (3)项目在 main.js 文件中引入并注册使用
| import store from './store/index'; | |
| new Vue({ | |
| el: '#app', | |
|       router, | |
|       store, | |
| render: h => h(App) | |
| }); | 
# (4)获取 vuex 的变量
例如在项目某个地方获取用户名称
方法一: 语法是 this.$store.state. 变量名
| this.$store.state.userName | |
| // 获取里面 getters 的内容 | |
| this.$store.getters.doneTodos | 
方法二:可以用计算属性解构出来,能直接使用 this.userName
| import { mapGetters } from 'vuex' | |
| computed:{ | |
| ...mapGetters(['userName']), | |
| doneTodosCount () { // // 获取里面 getters 的内容 | |
| return this.$store.getters.doneTodos | |
|     } | |
| }, | 
# (5)更新变量
即我想修改 vuex 中的一个变量,
方法一:语法 this.$store.commit (触发的方法,修改成什么内容)
| methods:{ | |
| myclick(){ | |
| this.$store.commit('saveName', this.newName) | |
|     } | |
| } | 
方法二:解构出来用
| methods: { | |
| ...mapActions(['saveName']) | |
| } | |
| this.saveName() | 
# 三、小结
如果你认真看完全部内容,你会发现 pinia 比 vuex 更加简洁更加灵活,甚至能直接修改 state 里面的变量,但其实并不是简单就绝对更好,我个人认为总的来说,认识 vuex 适合于大型项目或需要复杂状态管理的场景,而 pinia 则更适合于中小型项目或对状态管理需求不是很复杂的情况。选择使用哪个取决于项目的具体需求和开发团队的偏好。
纯用法上最主要差异:
- pinia 能直接使用 state, 并且能直接修改;vuex 要通过 mutation 去修改
- pinia 处理方法只有 action, 不区分同步异步;vuex 在 mutation 处理同步,在 action 处理异步
- pinia 没有 modules 嵌套结构,是一个平面的结构,可创建不同的 Store
