Pinia 保姆级快速入门介绍文章

前言:

在现代 Web 开发中,状态管理是一个非常重要的问题。虽然 Vue.js 框架内置了 Vuex 状态管理库,但随着应用程序规模和复杂性的不断增加,Vuex 有时候也会遇到一些难以解决的问题,比如代码冗长、维护困难等。为了解决这些问题,社区中不断涌现出新的状态管理库,其中 Pinia 就是一个备受欢迎的选择。

Pinia 是一个现代化的基于 Vue.js 的状态管理库,它与 Vuex 的差异在于其代码更加简洁、易于维护,同时更好地支持 Typescript 和 SSR。此外,Pinia 还具有单独的 Store 实例和可插拔的插件体系,使得开发者能够更好地控制状态管理逻辑流程,并在应用程序不断变化时保持灵活性和可扩展性。本篇文章将从 Pinia 库的基础架构、核心概念、特点和应用场景等方面对这一库进行全面介绍,希望能够帮助读者深入理解 Pinia 的设计思想和工作原理,并在实际的开发环境中运用到实践当中。

官网地址如下: 

 Pinia | The intuitive store for Vue.jsIntuitive, type safe, light and flexible Store for Vuehttps://pinia.vuejs.org/


Pinia的诞生
Pinia从2019年11月左右,开始尝试重新使用Composition API设计Vue Store。Pinia 试图尽可能接近 Vuex 的理念,旨在测试 Vuex 下一次选代的一个方案。目前,Vuex 5的open RFC,AP与Pinia的API非常相似,这说明pinia成功了。
注意,Pinia的作者(Eduardo),也是Vuejs核心团队的一员,积极参与 Router 和 Vuex 等AP的设计。设计 Pinia 的目的是想重新设计使用store的体验,同时保持Vue的容易理解的理念。将Pinia的API与Vuex保持尽可能的接近因为它不断向前发展,使人们能够方便地迁移到Vuex,甚至在未来融合两个项目。


Pinia 特性

Pinia具有以下几点特性

  • 直观,像定义components一样地定义 store
  • 完整的Typescript支持
  • 去除 mutations,只有 state,getters,actions
  • actions支持同步和异步
  • Vue Devtools支持Pinia,提供更好的开发体验
  • 能够构建多个 stores ,并实现自动地代码拆分
  • 极其轻量 (1kb),甚至感觉不到它的存在
  • Pinia 支持插件扩展自身功能
  • 支持服务端渲染

 Pinia 是 vue 的存储库,它允许您跨组件/页面共享状态。


 Pinia 基础使用

1. 安装Pinia命令:

yarn add pinia
# 或者使用 
npmnpm install pinia

创建一个根存储传递给应用程序(创建一个存储数据的数据桶,放到应用程序中去)
修改 main.js ,引入 pinia 提供的 createpinia 方法,创建根存储。

// main.ts
import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
const pinia = createPinia();

const app = createApp(App);
app.use(pinia);
app.mount("#app");

2.创建store

 store 数据仓库 类似一个公共组件但只存放数据,这些数据其它所有的组件都能够访问且可以修改。

使用 pinia 提供的 definestore() 方法来创建一个 store,该 store 用来存放需要全局使用的数据。

在项目 src 目录下新建 store 文件夹用来存放创建的各种 store ,然后在该目录下新建 user.ts 文件,主要用来存放与 user 相关的 store 。 

/src/store/user.ts

import { definestore }  from 'pinia'
// 第一个参数是应用程序中 store 的唯一 id
export const useUsersStore = defineStore('users',{
    // 其它配置项
}

 defineStore 函数  接收两个参数:

  • name : 一个字符串,必传项,该 store 的唯一 id 。
  • options : 一个对象, store 的配置项,比如配置 store 内的数据,修改数据的方法等等

可以定义任意数量的 store ,因为其实一个 store 就是一个函数,让代码扁平化了,和 vue3 的实现思想是一样的。


3.使用store

 创建了一个 store 即创建了一个方法,那么在 App.vue 里面使用它,该如何使用呢?

/src/App.vue
<script setup lang="ts">
import { useUsersstore } from "../src/store/user";
const store = useUsersStore();
console.log(store);
</script>

<script setup> 可以将组件选项(如 props、data、methods 等)声明为变量,并通过 defineComponent 函数将其导出为组件选项对象。这样可以使得组件选项与模板代码更加紧密地结合在一起,从而提高了代码的可读性和可维护性。

 直接引入声明的 useUsersstore 方法即可


4.添加state

store 是用来存放公共数据的,那么数据具体存在在哪里呢?  前面利用defineStore 函数创建了一个 store ,该函数第二个参数是一个 options 配置项,需要存放的数据就放在 options 对象中的 state 属性内。
假设我们往 store 添加一些任务基本数据,修改 user.ts 代码

export const useUsersStore = defineStore("users", {
 state:() => {
    return {
        name : "小猪课堂",
        age: 25,
        sex : "男"
    };
  },
});

上段代码中即给配置项添加了 state 属性,该属性就是用来存储数据的,同时往 state 中添加了3 条数据。⭕注意: state 接收的是一个箭头函数返回的值,它不能直接接收一个对象。


5.操作state

①读取 state 数据

往 store 存储数据的目的就是为了操作它,具体操作如下:

<template>
    <img alt="Vue logo" src="./assets/logo.png" />
    <p>姓名: {
   
   { name }}</p>
    <p>年龄: {
   
   { age }}</p>
    <p>性别: {
   
   { sex }}</p>
</template>

<script setup lang="ts">
import { ref } from import "vue";
import { useUsersStore } from "../src/store/user";
const store = useUsersStore();
const name = ref<string>(store.name);
const age = ref<number>(store.age);
const sex = ref<string>(store.sex);
</script>

解构代码如下:

import { useUsersStore } from "../src/store/user";
const store = useUsersStore();
const { name, age, sex } = store;

②多个组件使用state

使用 store 的最重要的目的就是为了组件之间共享数据。例:新建一个child.vue 组件,在该组件内部也使用 state 数据。

<template>
    <h1>我是child组件</h1>
    <p>姓名: {[ name }]</p
    <p>年龄:{
   
   { age }}</p>
    <p>性别: {[sex }}</p>
</template>
<script setup lang="ts">
import { useUsersstore } from "../src/store/user";
const store = useUsersstore();
const { name, age, sex } = store;
</script>

③修改state数据

想要修改 store 的数据,可以直接重新赋值即可。

import { storeToRefs } from 'pinia';
const store = useUsersStore();
const { name, age, sex } = storeToRefs(store);

利用 pinia 的 storeToRefs函数,将 state 中的数据变为了响应式的。


 ④重置state

 利用 stare 的 $reset( )方法将 state 数据还原,例:添加重置按钮

<button @click="reset">重置store</button>
// 重置store
const reset = () =>{
    store.$reset();
}


⑤批量更改state数据

用 store 的 $patch 方法,修改 app.vue代码,添加一个批量更改数据的方法 

<button @click="patchstore">批量修改数据</button>
// 批量修改数据
const patchstore = () => {
    store.$patch({
        name:"张三",
        age: 100,
        sex:"女",
    });
};


⑥直接替换整个state

 使用 store 的 $state 方法直接替换整个 state 对象

store.$state = { counter:666, name:'张三' }

6.getters属性

 getters 是 defineStore 参数配置项里面的另一个属性,getter属性值是一个对象,该对象里面是各种各样的方法。和 Vue 中的计算属性 computed 类似,作用就是返回一个新的结果。

 ①添加 getter

export const useUsersStore = defineStore("users", {
    state: () => [
        return {
            name:"小猪课堂"
            age:25,
            sex:"男",
        };
    },    
    getters: {
        getAddAge: (state) => {
            return state.age + 100;
        },
    },
});

 在配置项参数中添加了 getter 属性,该属性对象中定义了一个 getAddAge 方法该方法会默认接收一个 state 参数,也就是 state 对象,然后该方法返回的是一个新的数据。


②使用getter

 组件中使用getter

<template>
    <p>新年龄: [{ store.getAddAge }}</p>
    <button @click="patchstore">批量修改数据</button>
</template>
<script setup lang="ts">
import { useUsersStore } from "../src/store/user"
const store = useUsersStore();
// 批量修改数据
const patchstore = () => {
    store.$patch({
        name:"张三"
        age: 100,
        sex:"女"
    });
};
</script>

③ getter中调用其它getter

在这一个getter 方法中调用其它 getter 方法,这个时候如何调用呢?

直接在 getter 方法中调用 this,this 指向的便是 store 实例,所以理所当然的能够调用到其它 getter 。(不能使用箭头函数)


 7.actions属性

①添加action  

state 和 getters 属性都主要是数据层面的,并没有具体的业务逻辑代码,与们组件代码中的 data 数据和 computed 计算属性一样。

而卸载 actions 属性与 methods 相似,用来放置一些处理业务逻辑的方法。

actions 属性值同样是一个对象,该对象里面也是存储的各种各样的方法,包括同步方法和异步方法。

export const useUsersStore = defineStore("users",{
    state: () => {
        return {
             name:"小猪课堂" :
             age:25,
             sex :"男",
        };
    },
    getters: {
        getAddAge: (state) => {
            return (num: number) => {
                return (num:muber) => state.age + num;
        },
        getNameAndAge(): string {
            return this.name + this.getAddAge; // 调用其它getter
        },
    },

actions :{
    saveName(name : string){
        this .name = name ;
    },
 },
});

在实际场景中,该方法可以是任何逻辑,比方法当作一个普通的方法即可,特殊之处在于该如发送请求、存储 token 等等。可以把 actions方法内部的 this 指向的是当前 store。


②使用action

const saveName {
    store.saveName("我是小猪");
}

总结:

Pinia 是一种轻量级、用于 Vue.js 应用程序的状态管理库, 它可以帮助开发人员更好地组织和管理应用程序状态。与其他状态管理库相比,Pinia 具有更快的速度和更小的体积,同时具有可扩展性和易用性等优点。

使用 Pinia 可以轻松地实现状态管理,并对应用程序中的状态进行更好的组织和维护,从而提高代码的可读性和可维护性。它还支持 TypeScript,并且具有良好的文档、易懂的 API 设计和友好的社区支持。

猜你喜欢

转载自blog.csdn.net/m0_61662775/article/details/130980656
今日推荐