Pinia
Pinia 是 Vue 的状态管理库,允许在跨组件/页面之间共享状态,由 Vue 核心团队维护,对 Vue 2 和 Vue 3 都可用。类似于react中的mobx和redux。Vuex是 Vue 之前的官方状态管理库。由于 Pinia 在生态系统中能够承担相同的职责且能做得更好,因此 Vuex 现在处于维护模式。它仍然可以工作,但不再接受新的功能。对于新的应用,建议使用 Pinia。
安装与使用
安装
yarn add pinia
# 或者使用 npm
npm install pinia
使用
- 引入到
main.ts
中
main.ts
import { createPinia } from 'pinia'
app.use(createPinia())
- 定义一个store
./src/stores/counterStore.ts
import { defineStore } from 'pinia',
const useCounterStore = defineStore('counterStore', {
state: () => ({
counter: 0
})
})
- 访问store
<template>
<div>
{{ counterStore.counter }}
</div>
</template>
<script setup lang="ts">
import useCounterStore from '../stores/counterStore'
const counterStore = useCounterStore()
</script>
核心概念: state、getters、actions
state
state 是 store 的核心部分。 在 Pinia 中,状态被定义为返回初始状态的函数。
import { defineStore } from 'pinia'
const useStore = defineStore('storeId', {
// 推荐使用 完整类型推断的箭头函数
state: () => {
return {
// 所有这些属性都将自动推断其类型
counter: 0,
name: 'Eduardo',
isAdmin: true,
}
},
})
访问 state
默认情况下,您可以通过 store
实例访问状态来直接读取和写入状态:
const store = useStore()
store.counter++
重置状态
您可以通过调用 store 上的 $reset()
方法将状态 重置 到其初始值:
const store = useStore()
store.$reset()
tip
: 可以在 pinia
实例上查看整个状态:
watch(
pinia.state,
(state) => {
// 每当它发生变化时,将整个状态持久化到本地存储
localStorage.setItem('piniaState', JSON.stringify(state))
},
{ deep: true }
)
更多用法查看官网: https://pinia.vuejs.org/core-concepts/state.html
getter
Getter 完全等同于 Store 状态的计算值。 它们可以用 defineStore()
中的 getters
属性定义。 他们接收“状态”作为第一个参数:
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
})
然后可以在store 实例上访问 getter:
<template>
<p>Double count is {{ store.doubleCount }}</p>
</template>
<script lang="ts" setup>
import useStore from '../stores/counterStore'
const store = useStore()
</script>
更多用法查看官网:https://pinia.vuejs.org/core-concepts/getters.html
actions
Actions 相当于组件中的methods。它们可以使用 defineStore()
中的 actions
属性定义,并且它们非常适合定义业务逻辑:
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
actions: {
increment() {
this.counter++
},
randomizeCounter() {
this.counter = Math.round(100 * Math.random())
},
},
})
actions
可以是异步的,您可以在其中await
任何 API 调用甚至其他操作。
import { mande } from 'mande'
const api = mande('/api/users')
export const useUsers = defineStore('users', {
state: () => ({
userData: null,
// ...
}),
actions: {
async registerUser(login, password) {
try {
this.userData = await api.post({ login, password })
showTooltip(`Welcome back ${this.userData.name}!`)
} catch (error) {
showTooltip(error)
return error
}
},
},
})
更多用法查看官网:https://pinia.vuejs.org/core-concepts/actions.html
Q.E.D.