Yang's blog Yang's blog
首页
Java
密码学
机器学习
命令手册
关于
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

xiaoyang

编程爱好者
首页
Java
密码学
机器学习
命令手册
关于
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • SpringCloud

    • 微服务架构介绍
    • SpringCloud介绍
    • Spring Cloud:生产者与消费者
    • Spring Cloud Eureka:构建可靠的服务注册与发现
    • Spring Cloud Ribbon:负载均衡
    • Spring Cloud Fegin:服务调用
    • Spring Cloud Hystrix:熔断器
    • Spring Cloud Zuul:统一网关路由
    • Spring Cloud Config:配置中心
  • Java后端框架

    • LangChain4j

      • 介绍
      • 快速开始
      • Chat and Language Models
      • Chat Memory
      • Model Parameters
      • Response Streaming
      • AI Services
      • Agent
      • Tools (Function Calling)
      • RAG
      • Structured Outputs
      • Classification
      • Embedding (Vector) Stores
      • Image Models
      • Quarkus Integration
      • Spring Boot Integration
      • Kotlin Support
      • Logging
      • Observability
      • Testing and Evaluation
      • Model Context Protocol
  • 八股文

    • 操作系统
    • JVM介绍
    • Java多线程
    • Java集合框架
    • Java反射
    • JavaIO
    • Mybatis介绍
    • Spring介绍
    • SpringBoot介绍
    • Mysql
    • Redis
    • 数据结构
    • 云计算
    • 设计模式
    • 计算机网络
    • 锁核心类AQS
    • Nginx
  • 前端技术

    • 初识Vue3
    • Vue3数据双向绑定
    • Vue3生命周期
    • Vue-Router 组件
    • Pinia 集中式状态存储
      • 1. 理解状态
      • 2. Vuex 简单示例
        • 安装 Vuex
        • 创建 Vuex Store
        • 在 Vue 中使用 Vuex
      • 3. 创建 Pinia Store
        • 3.1 安装 Pinia
        • 3.2 创建 Store
        • 3.3 使用 Store 操作数据
      • 4. storeToRefs 声明响应式数据
      • 5. 修改 Store 数据
      • 6. Store 的混合式写法
      • 7. 总结
  • 中间件

    • RocketMQ
  • 开发知识

    • 请求参数注解
    • 时间复杂度和空间复杂度
    • JSON序列化与反序列化
    • Timestamp vs Datetime
    • Java开发中必备能力单元测试
    • 正向代理和反向代理
    • 什么是VPN
    • 正则表达式
  • Java
  • 前端技术
xiaoyang
2025-02-28
目录

Pinia 集中式状态存储

# Pinia 集中式状态存储

在现代前端开发中,尤其是在 Vue 3 中,Pinia 提供了一个简洁且功能强大的集中式状态管理解决方案。它被认为是 Vuex 的替代品,具有更简单的 API 和更好的 TypeScript 支持。让我们深入了解 Pinia 如何帮助我们管理全局状态。

# 1. 理解状态

在 Vue 中,状态(State) 是指在应用中需要共享的数据。举个例子,假设你有一个用户登录状态,这个状态在多个页面间共享。一旦用户登录成功,所有的页面都能够读取到当前登录的用户信息。

在 Vue 2 中,我们通常使用 Vuex 来实现集中式状态管理。而在 Vue 3 中,Pinia 是推荐的状态管理库,提供了更简洁、现代的 API。如果你在使用 Vue 2,那么 Vuex 和 Pinia 不能同时使用。

# 2. Vuex 简单示例

Vuex 是 Vue 官方的状态管理库,主要用于 Vue 2.x,但 Vue 3 也支持 Vuex。它的设计理念是集中式存储,所有的状态都存储在单一的 store 中,组件通过 commit 和 dispatch 来修改状态。Vuex 适合需要复杂状态管理和大型应用,但它的 API 相对繁琐,尤其是与 TypeScript 集成时。

让我们先来看看 Vuex 在 Vue 3 中的使用方式。

# 安装 Vuex

npm install vuex@next
1

# 创建 Vuex Store

// store/index.ts
import { createStore } from 'vuex';

const store = createStore({
  state: {
    username: '--',
  },
  getters: {
    getUsername(state) {
      return state.username.toUpperCase();
    },
  },
  mutations: {
    changeUsername(state, value: string) {
      if (value && value.length < 10) {
        state.username = value;
      }
    },
  },
  actions: {
    changeUsernameAsync({ commit }, value: string) {
      setTimeout(() => {
        commit('changeUsername', value);
      }, 1000);
    },
  },
});

export default store;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 在 Vue 中使用 Vuex

// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import store from './store';

const app = createApp(App);
app.use(store);
app.mount('#app');
<!-- App.vue -->
<template>
  <div>
    <h1>Hello {{ username }}</h1>
    <button @click="changeUsername">Change Username</button>
  </div>
</template>

<script lang="ts">
import { computed } from 'vue';
import { useStore } from 'vuex';

export default {
  setup() {
    const store = useStore();

    const username = computed(() => store.getters.getUsername);

    const changeUsername = () => {
      store.dispatch('changeUsernameAsync', 'NewUser');
    };

    return { username, changeUsername };
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 3. 创建 Pinia Store

Store 在 Pinia 中类似于 Vuex 中的 store,它用于保存应用的全局状态。我们可以在创建 Vue 应用时引入 Pinia,或者手动引入。

# 3.1 安装 Pinia

首先,需要安装 Pinia:

npm install pinia
1

然后,在 main.ts 文件中创建并引入 Pinia:

import { createApp } from 'vue';
import App from './App.vue';
import { createPinia } from 'pinia';

// 创建 Pinia 实例
const pinia = createPinia();

// 使用 Pinia
const app = createApp(App);
app.use(pinia);
app.mount('#app');
1
2
3
4
5
6
7
8
9
10
11

# 3.2 创建 Store

使用 defineStore 函数来定义一个 Store。Store 中包含三个主要部分:

  • state:存储数据,相当于 Vuex 中的 state。
  • getter:计算属性,用于获取或计算派生状态,相当于 Vuex 中的 getters。
  • action:方法,用于改变 state,处理业务逻辑,相当于 Vuex 中的 actions。

下面是一个创建用户信息管理的例子:

// store/user.ts
import { defineStore } from 'pinia';

export const useUserStore = defineStore('userStore', {
  // state - 用于存储数据
  state: () => ({
    username: '--'
  }),
  // getters - 用于读取计算的值
  getters: {
    getUsername: (state) => state.username.toUpperCase()
  },
  // actions - 用于修改 state 的方法
  actions: {
    changeUsername(value: string) {
      if (value && value.length < 10) {
        this.username = value;
      }
    }
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  • state 用于存储数据,这里存储了 username。
  • getter 用于计算并返回 username 的大写版本。
  • action 用于修改 username。

# 3.3 使用 Store 操作数据

Pinia 的使用非常简洁。在 Vue 组件中,我们只需要通过 useUserStore 获取 Store 实例,然后可以通过 state、getter 和 action 来操作数据。

<template>
  <div id="app">
    <h1>Hello {{ userInfo.username }}</h1>
  </div>
</template>

<script lang="ts" setup>
import { useUserStore } from "@/store/user";

// 获取 store
const userStore = useUserStore();

// 直接修改 state
userStore.username = 'Roy';

// 使用 action 修改 state
userStore.changeUsername('Alice');

// 获取 getter
console.log(userStore.getUsername); // 输出:ALICE
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 4. storeToRefs 声明响应式数据

当你需要在 Vue 模板中访问 Pinia Store 的状态时,可以使用 storeToRefs 来将 Store 中的数据转化为响应式数据。这样做可以确保 Vue 模板能够正确地反应数据的变化。

import { storeToRefs } from 'pinia';
import { useUserStore } from "@/store/user";

// 获取 store
const userStore = useUserStore();

// 使用 storeToRefs 将 store 转为响应式数据
const { username } = storeToRefs(userStore);

console.log(username.value); // 输出 'Roy'
1
2
3
4
5
6
7
8
9
10

storeToRefs 与 Vue 中的 toRefs 函数类似,但它只会把 store 中的状态部分转为响应式数据,而 toRefs 会将整个对象转为响应式。

# 5. 修改 Store 数据

在实际应用中,通常我们会通过 action 来修改数据,因为它可以确保业务逻辑的一致性。你可以使用 patch 方法直接修改 state,或者使用 action 来修改。

// 通过 action 修改数据
userStore.changeUsername('Roy');

// 直接修改 state
userStore.username = 'Alice';

// 使用 patch 批量修改
userStore.$patch({
  username: 'New User'
});
1
2
3
4
5
6
7
8
9
10

# 6. Store 的混合式写法

除了传统的对象式 API 外,Pinia 还支持 组合式 API 的写法。这种方式让你可以更灵活地使用 Pinia,尤其是在处理复杂状态管理时。

import { defineStore } from 'pinia';
import { reactive } from 'vue';

// 使用组合式 API 定义 store
export const useUserStore = defineStore('userStore', () => {
  // state
  const userInfo = reactive({ username: '---' });

  // action
  function changeUsername(value: string) {
    if (value && value.length < 10) {
      userInfo.username = value;
    }
  }

  // getter
  function getUsername(): string {
    return userInfo.username.toUpperCase();
  }

  return { userInfo, changeUsername, getUsername };
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

在 Vue 组件中使用时,可以直接解构返回的对象:

<script lang="ts" setup>
import { useUserStore } from "@/store/user2";

// 获取 store
const { userInfo, changeUsername, getUsername } = useUserStore();

// 修改 store 数据
changeUsername('Roy');

// 获取 store 数据
console.log(getUsername()); // 输出:ROY
</script>
1
2
3
4
5
6
7
8
9
10
11
12

# 7. 总结

Pinia 是一个简单且直观的状态管理库,它提供了:

  • state 用于存储应用的状态。
  • getter 用于获取计算后的状态。
  • action 用于修改 state 并处理业务逻辑。

它非常适合与 Vue 3 一起使用,相比 Vuex,它的 API 更加简洁,易于使用,且对 TypeScript 支持更好。在大型应用中,Pinia 也能够轻松地扩展和维护状态逻辑。

编辑 (opens new window)
上次更新: 2025/04/01, 01:48:12

← Vue-Router 组件 RocketMQ→

最近更新
01
操作系统
03-18
02
Nginx
03-17
03
后端服务端主动推送消息的常见方式
03-11
更多文章>
Theme by Vdoing | Copyright © 2023-2025 xiaoyang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式