1、安装Pinia
首先,你需要安装 Pinia:
npm install pinia
然后,在 main.js 中创建并挂载 Pinia 实例:
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
const app = createApp(App);
app.use(createPinia()); // 注册 Pinia
app.mount('#app');
2、定义Store
在 Pinia 中,store 是一个包含状态(state)、计算属性(getters)和行为(actions)的一组逻辑单元。你可以通过 defineStore() 函数来定义一个 store。
基础的store定义:
Pinia 提供了 defineStore 函数来创建 store,store 中的状态(state)、计算属性(getters)和方法(actions)都是响应式的。
// store/counter.js
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
getters: {
doubleCount: (state) => state.count * 2, // 计算属性,类似于 Vue 的 computed
},
actions: {
increment() {
this.count++; // 通过 actions 修改 state
},
decrement() {
this.count--; // 通过 actions 修改 state
},
async fetchData() {
// 示例:通过 actions 执行异步操作
const data = await fetch('https://api.example.com/data');
const result = await data.json();
console.log(result);
},
},
});
Store 使用说明:
state: 存储响应式数据。getters: 类似于 Vue 中的 computed,用于计算基于 state 的派生数据。actions: 用于定义方法,修改 state 或执行异步操作。
3. 使用 Store
在组件中,使用 useStore 来访问 Pinia store,useStore 是 defineStore 返回的函数,它会自动提供当前 store 的实例。
在组件中使用 store
<template>
<div>
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="increment">Increment</button>
<button @click="decrement">Decrement</button>
</div>
</template>
<script>
import { useCounterStore } from '../store/counter';
export default {
setup() {
const counterStore = useCounterStore(); // 获取 store 实例
return {
count: counterStore.count,
doubleCount: counterStore.doubleCount,
increment: counterStore.increment,
decrement: counterStore.decrement,
};
},
};
</script>
在上面的例子中:
useCounterStore()获取了定义的counterstore。- 你可以直接通过
counterStore.count访问 state。 - 通过
counterStore.increment()或counterStore.decrement()来修改 state。
4. 响应式数据(State)
Pinia 的 state 是响应式的。你可以直接在 store 中访问和修改它。Pinia 会自动将其转化为 Vue 响应式的数据对象。
state: () => ({
count: 0,
})
你也可以通过 $patch 方法批量更新多个状态字段,避免逐个更新。
counterStore.$patch({ count: 10 }); // 批量更新
5. 计算属性(Getters)
getters 是基于 state 的计算值,类似于 Vue 中的 computed。在 getters 中,你可以对 state 做各种处理,并返回一个新的值。
getters: {
doubleCount: (state) => state.count * 2, // 返回 count 的两倍
}
在组件中,可以直接访问 getter 的值:
<p>Double Count: {{ doubleCount }}</p>
6. 行为方法(Actions)
actions 是 store 中的函数,用于修改 state 或执行异步操作。你可以在 actions 中直接访问和修改 state,也可以使用异步操作。
同步方法:
actions: {
increment() {
this.count++; // 直接修改 state
}
}
异步方法:
actions: {
async fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
this.count = data.value; // 修改 state
}
}
在组件中使用异步方法:
<template>
<div>
<button @click="fetchData">Fetch Data</button>
</div>
</template>
<script>
import { useCounterStore } from '../store/counter';
export default {
setup() {
const counterStore = useCounterStore();
return {
fetchData: counterStore.fetchData,
};
},
};
</script>
7. Persisted State(持久化状态)
Pinia 可以通过插件支持状态持久化,即保存 state 到浏览器的 localStorage 或 sessionStorage,或其他存储机制。这个功能需要通过插件扩展来实现。
npm install pinia-plugin-persistedstate
在 store 中启用持久化:
import { defineStore } from 'pinia';
import piniaPersist from 'pinia-plugin-persistedstate';
const store = createPinia();
store.use(piniaPersist);
const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
persist: true, // 启用持久化
});
8. Store 的模块化
Pinia 支持通过不同的文件组织多个 store。你可以将 store 分割成不同的模块,每个模块都是一个 defineStore()。
例如,可以创建多个文件来定义不同的 store,如 counter.js, user.js 等,并在组件中按需导入。
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
name: 'John Doe',
}),
actions: {
setName(newName) {
this.name = newName;
},
},
});
总结
- Store:通过
defineStore()定义每个 store,包含状态、计算属性和行为方法。 - State:响应式数据,存储在
state中,可以直接修改或通过$patch批量更新。 - Getters:类似于 Vue 的
computed,用于对state进行计算。 - Actions:定义方法,类似于 Vue 的
methods,用于修改state或执行异步操作。