介绍
Pinia 是 Vue.js 团队成员专门为 Vue 开发的一个全新的状态管理库,也被认为是下一代的 Vuex,即 Vuex5.x,在 Vue3.0 的项目中使用也是备受推崇。Pinia 最初是在 2019 年 11 月左右重新设计使用 Composition API,从那时起,最初的原则仍然相同,但 Pinia 对 Vue 2 和 Vue 3 都有效,并且不需要您使用组合 API。 除了安装和 SSR 之外,两者的 API 都是相同的。
Pinia 和 Vuex
Vuex: State
、Gettes
、Mutations
(同步)、Actions
(异步)
Pinia: State
、Gettes
、Actions
(同步异步都支持)
安装
npm install pinia --save
使用
新建 src/store 目录并在其下面创建 index.js,导出 store
import { createPinia } from 'pinia'
const store = createPinia()
export default store
在 main.js 中引入并使用。
import store from './store'
app.use(store)
State
在 src/store 下面创建一个user.js,定义state
-
id就是模块的id,必填且唯一,多个模块不能重名,Pinia 会把所有的模块都挂载到根容器上
-
state
就是用来存储全局状态,它必须是箭头函数,为了在服务端渲染的时候避免交叉请求导致的数据状态污染所以只能是函数,而必须用箭头函数则为了更好的 TS 类型推导 -
getters
就是用来封装计算属性,它有缓存的功能 -
actions
就是用来封装业务逻辑,修改 state
import { defineStore } from 'pinia'
export const useUserStore = defineStore({
id: 'user', // id必填,且需要唯一
state: () => {
return {
name: '派大星'
}
}
})
获取state
<template>
<div class="name">哈喽~{{ userStore.name }}</div>
</template>
<script>
import { useUserStore } from '../store/user'
export default {
setup() {
const userStore = useUserStore()
return {
userStore,
}
}
}
</script>
Action
Pinia 没有 Mutations,统一在 actions 中操作 state,通过this.xx 访问相应状态,虽然可以直接操作 Store,但还是推荐在 actions 中操作,保证状态不被意外改变
修改state
import { defineStore } from 'pinia'
export const useUserStore = defineStore({
id: 'user', // id必填,且需要唯一
state: () => {
return {
name: '派大星'
}
},
actions: {
updateName(name) {
this.name = name
}
},
})
<template>
<div class="name">哈喽~{{ userStore.name }}</div>
<div class="name">
<el-button type="success" @click="updateName('海绵宝宝')">我是海绵宝宝</el-button>
<el-button type="warning" @click="updateName('派大星')">我是派大星</el-button>
</div>
</template>
<script>
import { useUserStore } from '../store/user'
export default {
setup() {
const userStore = useUserStore()
function updateName(name) {
userStore.updateName(name)
}
return {
userStore,
updateName,
}
}
}
</script>
Getters
import { defineStore } from 'pinia'
export const useUserStore = defineStore({
id: 'user', // id必填,且需要唯一
state: () => {
return {
name: '派大星'
}
},
actions: {
updateName(name) {
this.name = name
}
},
getters: {
nameSuffix: (state) => {
return state.name + '女士/先生'
}
}
})
<template>
<div class="name">哈喽~{{ userStore.name }}</div>
<div class="name">
<el-button type="success" @click="updateName('海绵宝宝')">我是海绵宝宝</el-button>
<el-button type="warning" @click="updateName('派大星')">我是派大星</el-button>
</div>
<div>Hi~{{userStore.nameSuffix}}</div>
</template>
效果: