Vue3.0(七):Pinia状态管理

Pinia状态管理

最初是作为一个实验为 Vue重新设计状态管理,让它用起来像组合式API

Pinia和Vuex的对比

  • 为什么要用 Pinia
    • Pinia 最初是为了 探索Vuex的下一次迭代 会是什么样子,结合了 Vuex5核心团队讨论中的很多想法
    • 最终,团队意识到 Pinia已经实现了Vuex5中大部分的内容 ,所以最终决定 使用Pinia来代替Vuex
    • 与Vuex相比,Pinia提供了一个更加简单的API,具有更少的仪式 ,提供了 Composition-API风格的API
    • 最重要的是,能够更好的支持TypeScript
  • 与Vuex相比,Pinia的优势
    • 比如mutations不再存在
    • 更友好的支持TypeScript
    • 不再有modules
    • 不再有命名空间的概念,不需要记住复杂的关系

如何使用Pinia

  • 首先通过 npm install pinia安装pinia
  • 安装完成后,在src文件夹下面创建store文件夹
  • 创建index.js的入口文件
js 复制代码
import { createPinia } from "pinia";

export default createPinia();
  • 在main.js使用pinia插件
js 复制代码
import { createApp } from "vue";
import App from "./App.vue";
import pinia from "./store";

const app = createApp(App);
app.use(pinia);

app.mount("#app");
  • 在store文件夹下面创建不同的store
    • 创建一个counter.js的store文件,用于保存计数的状态
js 复制代码
import { defineStore } from "pinia";

//defineStore创建store,可以创建多个store
//第一个参数是用于命名store的
//第二个参数是store的具体内容
const useCounter = defineStore("counter", {
  state: () => ({
    count: 199,
  }),
});

//返回值是一个函数,将函数暴露出去
export default useCounter;
  • 而后在具体的组件中引入暴露的函数,完成调用即可
html 复制代码
<template>
  <!-- 直接访问store中的变量即可 -->
  {{ counterStore.count }}
</template>

<script setup>
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();
</script>

<style scoped></style>

认识Store

  • 什么是Store
    • 一个store(如pinia)是一个实体(通过defineStore()创建 ),它会持有组件树种的 状态和业务逻辑(业务逻辑主要是网络请求等内容),也就是保存了全局的状态
    • 有点像始终存在,并且 每个人都可以读取和写入的组件
    • 可以在项目种,定义 任意数量的Store来管理状态
  • Stroe有三个核心概念
    • state、getters、actions
    • 等同于组件的 data、computed、methods
    • 一旦 store被实例化,可以直接在store上访问 state、getters、actions种定义的任何属性

定义一个store

在上面的例子中有讲过store的定义

  • 使用 defineStore 进行定义
    • 第一个参数:是store的唯一名称,也成为id,是必要的
    • 第二个参数是具体的store对象
  • 返回的函数同一使用useX进行命名
js 复制代码
import { defineStore } from "pinia";

//defineStore创建store,可以创建多个store
//第一个参数是用于命名store的
//第二个参数是store的具体内容
const useCounter = defineStore("counter", {
  state: () => ({
    count: 199,
  }),
});

//返回值是一个函数,将函数暴露出去
export default useCounter;

认识和定义State

  • state是store的核心部分
js 复制代码
import { defineStore } from "pinia";

//defineStore创建store,可以创建多个store
//第一个参数是用于命名store的
//第二个参数是store的具体内容
const useCounter = defineStore("counter", {
  state: () => ({
    count: 199,
  }),
});

//返回值是一个函数,将函数暴露出去
export default useCounter;

操作State

  • 读取和写入state:
    • 默认情况下,可以通过store实例访问状态来直接读取和写入状态
js 复制代码
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();

//读取
counterStore.count
//修改
counterStore.count++
  • 重置State
    • 可以通过调用store上的**$reset()**方法讲状态重置到初始值
js 复制代码
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();

counterStore.$reset()//会将counter恢复到初始定义的状态
  • 一次性修改多个State
    • 通过 $patch
js 复制代码
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();

counterStore.$patch({
    name:"zhangcheng",
    age:"18"
})
  • 替换state
    • 通过 $state方法进行替换
js 复制代码
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();

counterStore.$state = {
    name:"zhangcheng",
    age:"18"
}

认识和定义Getters

  • 基本使用,获取本store实例下的state
js 复制代码
import { defineStore } from "pinia";


const useCounter = defineStore("counter", {
  state: () => ({
    count: 199,
  }),
  getters:{
      doubleCount(state){
          //通过传参的方式进行访问
          return state.count
      },
      doubleCountAddOne(){
          //可以通过this进行访问
          return this.count*2+1
      }
  }
});

//返回值是一个函数,将函数暴露出去
export default useCounter;

//使用方法同state,先引入暴露的函数,执行,通过.的方式进行访问
  • 使用getters中的数据
    • 可以通过 this直接访问
js 复制代码
import { defineStore } from "pinia";


const useCounter = defineStore("counter", {
  state: () => ({
    count: 199,
  }),
  getters:{
      doubleCount(state){
          //通过传参的方式进行访问
          return state.count
      },
      doubleCountAddOne(){
          //可以通过this访问getters中的变量
          return this.doubleCount+1
      }
  }
});

//返回值是一个函数,将函数暴露出去
export default useCounter;
  • 用到别的store中的数据
js 复制代码
import { defineStore } from "pinia";
//引入其他的store
import userInfo from "./store/user.js";

const useCounter = defineStore("counter", {
  state: () => ({
    count: 199,
  }),
  getters:{
      getMessage(){
          //实例化而后使用
          const userStore = userInfo()
    		
          return userInfo.name + count
      }
  }
});

//返回值是一个函数,将函数暴露出去
export default useCounter;

认识和定义Actions

  • Actions相当于组件中的methods
  • 与getters一样,可以通过this访问store中的变量,但是没有传入state参数
js 复制代码
import { defineStore } from "pinia";
//引入其他的store
import userInfo from "./store/user.js";

const useCounter = defineStore("counter", {
  state: () => ({
    count: 199,
  }),
	actions:{
        countAdd(num){
            //可以传入参数
            //直接通过this进行访问state中的状态
            this.count += num
        }
    }
});


//具体使用
//引入暴露的store函数
import useCounter from "./store/counter.js";
const counterStore = useCounter();

//直接调用方法即可
counterStore.countAdd(10)

执行异步操作

js 复制代码
import { defineStore } from "pinia";
//引入其他的store
import userInfo from "./store/user.js";

const useCounter = defineStore("counter", {
	actions:{
      async getData(){
          const res = await fetch(xxxx)
          const data = await res.json()
          //改变state状态
          this.list = data
          //返回data
          retrun data
      }
    }
});
相关推荐
程序员海军6 分钟前
2024 Nuxt3 年度生态总结
前端·nuxt.js
m0_7482567816 分钟前
SpringBoot 依赖之Spring Web
前端·spring boot·spring
web135085886351 小时前
前端node.js
前端·node.js·vim
m0_512744641 小时前
极客大挑战2024-web-wp(详细)
android·前端
若川1 小时前
Taro 源码揭秘:10. Taro 到底是怎样转换成小程序文件的?
前端·javascript·react.js
潜意识起点1 小时前
精通 CSS 阴影效果:从基础到高级应用
前端·css
奋斗吧程序媛1 小时前
删除VSCode上 origin/分支名,但GitLab上实际上不存在的分支
前端·vscode
IT女孩儿1 小时前
JavaScript--WebAPI查缺补漏(二)
开发语言·前端·javascript·html·ecmascript
m0_748256564 小时前
如何解决前端发送数据到后端为空的问题
前端
请叫我飞哥@4 小时前
HTML5适配手机
前端·html·html5