pinia使用方法

1. 安装 Pinia

首先,确保你已经安装了 Pinia。

npm install pinia

2. 配置 Pinia

在你的 main.tsmain.js 中,创建 Pinia 实例并将其注册到 Vue 应用中。

// main.ts 或 main.js
import { createApp } from 'vue';
import { createPinia } from 'pinia'; // 导入 Pinia
import App from './App.vue';

const app = createApp(App);

const pinia = createPinia(); // 创建 Pinia 实例
app.use(pinia);  // 将 Pinia 添加到 Vue 应用中

app.mount('#app');

3. 定义 Pinia Store

src/stores 目录下创建一个 authStore.ts 文件,用于管理用户的登录状态和账户信息。

// src/stores/authStore.ts
import { defineStore } from 'pinia';

// 定义 User 类型
interface User {
  id: number;
  username: string;
  email: string;
  score: number;
}

export const useAuthStore = defineStore('auth', {
  state: () => ({
    isLoggedIn: false,  // 用户是否登录
    user: {} as User,   // 存储用户信息
  }),

  getters: {
    // getter 用于从 state 中派生数据
    userName: (state) => state.user.username, // 获取用户的用户名
    userScore: (state) => state.user.score,   // 获取用户的积分
  },

  actions: {
    // actions 用于修改 state 中的数据
    login(userData: User) {
      this.user = userData;       // 更新用户信息
      this.isLoggedIn = true;     // 更新登录状态
    },
    
    logout() {
      this.user = {} as User;     // 清空用户信息
      this.isLoggedIn = false;    // 更新登录状态
    },

    // 示例:增加用户积分的 action
    increaseScore(amount: number) {
      if (this.isLoggedIn) {
        this.user.score += amount; // 增加积分
      }
    }
  }
});

4. 使用 Pinia Store

在 Vue 组件中,可以通过 useAuthStore() 引入并使用 store。在登录时调用 login 方法更新状态,获取用户数据时可以直接使用 getters。

<!-- src/components/Login.vue -->
<template>
  <div>
    <h1 v-if="!authStore.isLoggedIn">Login</h1>
    <h1 v-else>Welcome, {{ authStore.userName }}!</h1>

    <div v-if="!authStore.isLoggedIn">
      <input v-model="username" placeholder="Username" />
      <input v-model="email" placeholder="Email" />
      <button @click="login">Login</button>
    </div>

    <div v-else>
      <button @click="logout">Logout</button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { useAuthStore } from '@/stores/authStore';

const authStore = useAuthStore();
const username = ref('');
const email = ref('');

// 登录操作
function login() {
  const user = {
    id: 1,
    username: username.value,
    email: email.value,
    score: 100,
  };
  authStore.login(user);  // 调用 store 的 login 方法
}

// 登出操作
function logout() {
  authStore.logout();  // 调用 store 的 logout 方法
}
</script>

5. Pinia中的 Getters 和 Actions 的区别

  • Getters
    • 目的:用来从 state 中派生或计算数据。
    • 特点:是 只读的,不直接修改 state,通常用于对 state 中的数据进行处理或者返回某种计算结果。
    • 使用场景:计算派生状态(例如,获取用户的用户名、积分等)。
  • Actions
    • 目的:用来 修改 state执行异步操作(如 API 请求)。
    • 特点:通过 this 访问 stategetters,并可以修改 state 或执行副作用(比如调用 API 或者增加积分)。
    • 使用场景:修改应用状态,触发异步操作(如用户登录、登出等)。
示例:Getters 和 Actions 的区别
export const useAuthStore = defineStore('auth', {
  state: () => ({
    isLoggedIn: false,
    user: {} as User,
  }),

  getters: {
    // Getter 用于从 state 派生信息,不能修改 state
    userName: (state) => state.user.username,
    userScore: (state) => state.user.score,
  },

  actions: {
    // Action 用于修改 state,执行异步操作
    login(userData: User) {
      this.user = userData;   // 修改 state
      this.isLoggedIn = true; // 更新登录状态
    },

    logout() {
      this.user = {} as User; // 清空用户数据
      this.isLoggedIn = false; // 设置为未登录
    },

    increaseScore(amount: number) {
      if (this.isLoggedIn) {
        this.user.score += amount; // 修改 state
      }
    },
  }
});

6. Pinia 持久化状态(可选)

如果你希望在页面刷新时保持用户的登录状态,可以使用插件将状态持久化到 localStoragesessionStorage

首先安装持久化插件:

npm install pinia-plugin-persistedstate

然后在 main.ts 中启用该插件:

// main.ts
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import piniaPersist from 'pinia-plugin-persistedstate'; // 导入插件
import App from './App.vue';

const app = createApp(App);

const pinia = createPinia();
pinia.use(piniaPersist); // 启用持久化插件

app.use(pinia);

app.mount('#app');

在 store 中启用持久化:

// src/stores/authStore.ts
import { defineStore } from 'pinia';

interface User {
  id: number;
  username: string;
  email: string;
  score: number;
}

export const useAuthStore = defineStore('auth', {
  state: () => ({
    isLoggedIn: false,
    user: {} as User,
  }),

  actions: {
    login(userData: User) {
      this.user = userData;
      this.isLoggedIn = true;
    },

    logout() {
      this.user = {} as User;
      this.isLoggedIn = false;
    },
  },

  persist: true,  // 启用持久化
});

在 Pinia 中,除了 stategettersactions 外,还可以使用 钩子Hooks)来处理特定的生命周期事件,类似于 Vue 的生命周期钩子。Pinia 提供了几个常用的钩子来增强 store 的功能,下面是如何使用这些钩子的完整示例。

7.Pinia 提供的钩子

  1. $onAction:监听 actions 被调用的事件。
  2. $patch:用来部分修改 store 的 state,类似于 Vuex 中的 mutation。
  3. $subscribe:监听 store 的变化,类似于 Vuex 中的 getter 和 mutation 订阅。
  4. $dispose:销毁 store。

示例:使用钩子

假设我们有一个用户登录状态的 store,下面演示如何使用钩子来监听 actions 和 state 的变化。

1. 在 store 中使用钩子
// src/stores/authStore.ts
import { defineStore } from 'pinia';

// 定义 User 类型
interface User {
  id: number;
  username: string;
  email: string;
  score: number;
}

export const useAuthStore = defineStore('auth', {
  state: () => ({
    isLoggedIn: false, // 用户是否登录
    user: {} as User,  // 存储用户信息
  }),

  getters: {
    userName: (state) => state.user.username,
    userScore: (state) => state.user.score,
  },

  actions: {
    login(userData: User) {
      this.user = userData;
      this.isLoggedIn = true;
    },

    logout() {
      this.user = {} as User;
      this.isLoggedIn = false;
    },

    increaseScore(amount: number) {
      if (this.isLoggedIn) {
        this.user.score += amount;
      }
    },
  },

  // 监听 action 的钩子
  persist: true,

  // 在 store 被创建时调用的钩子
  $onAction: (context) => {
    console.log('Action was called', context);
    // 可以使用 context 来获取 action 的名称和参数
  },

  // 在 store 的 state 发生变化时调用
  $subscribe: (mutation) => {
    console.log('Store changed', mutation);
    // mutation 包含了变化的类型和发生的状态
  },

  // 在 store 销毁时调用的钩子
  $dispose: () => {
    console.log('Store disposed');
  },
});
2. 在组件中使用钩子

在组件中调用 Pinia store 时,我们也可以利用钩子来处理一些业务逻辑,例如在登录成功后修改页面内容、发送消息等。

<!-- src/components/Login.vue -->
<template>
  <div>
    <h1 v-if="!authStore.isLoggedIn">Login</h1>
    <h1 v-else>Welcome, {{ authStore.userName }}!</h1>

    <div v-if="!authStore.isLoggedIn">
      <input v-model="username" placeholder="Username" />
      <input v-model="email" placeholder="Email" />
      <button @click="login">Login</button>
    </div>

    <div v-else>
      <button @click="logout">Logout</button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { useAuthStore } from '@/stores/authStore';

const authStore = useAuthStore();
const username = ref('');
const email = ref('');

// 登录操作
function login() {
  const user = {
    id: 1,
    username: username.value,
    email: email.value,
    score: 100,
  };
  authStore.login(user);  // 调用 store 的 login 方法
}

// 登出操作
function logout() {
  authStore.logout();  // 调用 store 的 logout 方法
}

// 组件挂载时触发
onMounted(() => {
  console.log('Component mounted');
  authStore.$subscribe((mutation) => {
    console.log('Mutation occurred:', mutation);
  });
});

// 组件卸载时触发
onBeforeUnmount(() => {
  console.log('Component will unmount');
  authStore.$dispose();  // 清理 store 的钩子
});
</script>
3. 使用 $onAction$subscribe
  • $onAction:它会在每次调用 store 中的 action 时触发,可以用来记录或执行副作用。
  • $subscribe:它会监听 store 的 state 变化,当 state 被修改时,$subscribe 会收到 mutation 通知,可以用来做额外的响应(如缓存、发送请求等)。
4. 使用持久化存储和钩子

如果你希望在应用重载时保留 store 状态(例如登录信息),可以结合 Pinia 的持久化插件使用。

// src/stores/authStore.ts
import { defineStore } from 'pinia';
import piniaPersist from 'pinia-plugin-persistedstate'; // 插件

export const useAuthStore = defineStore('auth', {
  state: () => ({
    isLoggedIn: false,
    user: {} as User,
  }),

  actions: {
    login(userData: User) {
      this.user = userData;
      this.isLoggedIn = true;
    },
    logout() {
      this.user = {} as User;
      this.isLoggedIn = false;
    },
  },

  // 启用持久化
  persist: true, // 状态持久化
  $onAction: (context) => {
    console.log('Action called:', context);
  },

  $subscribe: (mutation) => {
    console.log('Store changed:', mutation);
  },

  $dispose: () => {
    console.log('Store disposed');
  },
});
5. 总结:钩子的功能和使用

Pinia 提供的钩子机制可以帮助我们监听 store 的状态变化、捕获 action 的调用,以及处理一些副作用,增强了 store 的灵活性。

  • $onAction:监听 actions 的调用,可用于记录日志、调试等。
  • $subscribe:监听 store 的 state 变化,用于响应式操作。
  • $dispose:销毁 store 时触发,可以做一些清理工作。

在使用这些钩子时,可以帮助你更好地管理 store 的状态变化,并且便于扩展和维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值