# 一、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