Pinia 是 Vue 的存储库,用于跨组件/页面共享状态。
基本使用
-
安装:通过 npm 或 yarn 安装 pinia。
-
创建 Store:使用
defineStore
方法定义 Store,传入 store 的唯一 id 和配置属性,包括 state、getters 和 actions 等。 -
在组件中使用 Store:在组件中导入相应的 Store,然后直接访问 Store 实例的属性和方法。
API 使用代码示例
1. 使用 getters 获取状态
- 定义 Store:在 Store 中定义 getters,用于根据 state 计算并返回一些额外的数据。
- 在组件中使用:在组件中直接访问 Store 实例的 getter 属性即可获取计算后的状态。
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
getters: {
doubleCount: (state) => state.count * 2
}
})
<template>
<div>{{ counter.doubleCount }}</div>
</template>
<script setup>
import { useCounterStore } from './stores/counter'
const counter = useCounterStore()
</script>
2. 在另一个 Store 中依赖另一个 Store
- 定义 Store:在需要依赖其他 Store 的 Store 中,通过
useStore
函数引入被依赖的 Store,然后在 getters 或其他计算属性中引用其 state 或 getter。 - 在组件中使用:在组件中正常使用该 Store,当访问其依赖于其他 Store 的 getter 时,会自动获取到最新的值。
import { defineStore } from 'pinia'
import { useCounterStore } from './counter'
export const useAnotherStore = defineStore('another', {
getters: {
counterDouble: () => useCounterStore().doubleCount
}
})
<template>
<div>{{ another.counterDouble }}</div>
</template>
<script setup>
import { useAnotherStore } from './stores/another'
const another = useAnotherStore()
</script>
3. 在插件中注册 Store:
在插件中可以通过 app.use
方法将 Store 注册到 Vue 实例上,使其可以在全局范围内使用。
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import { useCounterStore } from './stores/counter'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.mount('#app')
4. 在组件外部使用 Store:
在组件外部,如在其他脚本文件或模块中,可以直接调用 useStore
函数来获取 Store 实例,并进行数据的读取或修改。
import { useCounterStore } from './stores/counter'
const counter = useCounterStore()
console.log(counter.count) // 输出当前 count 的值
counter.count++ // 修改 count 的值
5. 使用 LocalStorage:
在 Store 的 actions 中,可以编写代码实现与 LocalStorage 的交互,如在设置数据时将数据保存到 LocalStorage,在获取数据时从 LocalStorage 中读取。
import { defineStore } from 'pinia'
export const useLocalStorageStore = defineStore('localStorage', {
state: () => ({
count: JSON.parse(localStorage.getItem('count')) || 0
}),
actions: {
setCount(newCount) {
this.count = newCount
localStorage.setItem('count', JSON.stringify(newCount))
}
}
})
6.使用 action 的回调函数:
在 Store 的 actions 中,可以使用异步函数来进行一些异步操作,如网络请求等,并在操作完成后执行回调函数。
import { defineStore } from 'pinia'
export const useAsyncStore = defineStore('async', {
actions: {
async fetchData(callback) {
// 模拟异步操作,如网络请求
setTimeout(() => {
this.data = 'fetched data'
callback() // 执行回调函数
}, 1000)
}
}
})
7. 使用 mutation:
虽然 pinia 本身不推荐使用 mutation,但在一些特殊情况下,如果需要在 action 之外对 state 进行修改,可以使用 mutation。在 Store 中定义 mutations,然后在 actions 或其他需要的地方调用 this.$patch
方法来触发 mutation。
插件
Pinia 支持插件来扩展自身功能,例如持久化插件 pinia-plugin-persistedstate