Pinia的使用

366 阅读3分钟

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,useStoredefineStore 返回的函数,它会自动提供当前 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() 获取了定义的 counter store。
  • 你可以直接通过 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 或执行异步操作。