【Pinia状态管理】Pinia和Vuex的对比;创建Pinia的Store;Pinia核心概念State、Getters、Actions

目录

  • 1_Pinia和Vuex的对比
    • 1.1_介绍pinia
    • 1.2_Pinia和Vuex的区别
  • 2_创建Pinia的Store
    • 2.1_安装使用
    • 2.2_Store
    • 2.3_定义一个Store
  • 3_Pinia核心概念State
    • 3.1_认识和定义State
    • 3.2_操作State
  • 4_Pinia核心概念Getters
    • 4.1_认识
    • 2.2_访问Getters
  • 5_Pinia核心概念Actions
    • 5.1_认识
    • 5.2_Actions执行异步操作

1_Pinia和Vuex的对比

1.1_介绍pinia

Pinia(发音为/piːnjʌ/,如英语中的“peenya”)是最接近piña(西班牙语中的菠萝)的词;

  • Pinia开始于大概2019年,最初是作为一个实验为Vue重新设计状态管理,让它用起来像组合式API(Composition API)。
  • 从那时到现在,最初的设计原则依然是相同的,并且目前同时兼容Vue2、Vue3,也并不要求使用Composition API;
  • Pinia本质上依然是一个状态管理的库,用于跨组件、页面进行状态共享(这点和Vuex、Redux一样);

访问官网


1.2_Pinia和Vuex的区别

有Vuex,为什么还要用Pinia?

  • Pinia 最初是为了探索 Vuex 的下一次迭代会是什么样子,结合了 Vuex 5 核心团队讨论中的许多想法;
  • 最终,团队意识到Pinia已经实现了Vuex5中大部分内容,所以最终决定用Pinia来替代Vuex;
  • 与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的仪式,提供了 Composition-API 风格的 API;
  • 最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持;

和Vuex相比,Pinia有很多的优势:

  • 比如mutations消失,减少冗长的步骤
  • 更友好的TypeScript支持,Vuex之前对TS的支持很不友好;
  • 不再有modules的嵌套结构,可以灵活使用每一个store,它们是通过扁平化的方式来相互使用的;
  • 也不再有命名空间的概念,不需要记住它们的复杂关系;

【Pinia状态管理】Pinia和Vuex的对比;创建Pinia的Store;Pinia核心概念State、Getters、Actions_第1张图片


2_创建Pinia的Store

2.1_安装使用

执行安装命令,二选一

yarn add pinia

npm install pinia

在src/store/路径下,或者src/pinia/路径下,创建index.js文件,写入下方的代码,然后就成功创建一个pinia并可导出使用

import { createPinia } from 'pinia'

const pinia = createPinia()

export default pinia

2.2_Store

什么是Store?

  • 一个 Store (如 Pinia)是一个实体,它会持有为绑定到组件树的状态和业务逻辑,也就是保存了全局的状态;
  • 比较像始终存在,并且每个人都可以读取和写入的组件;
  • 可以在应用程序中定义任意数量的Store来管理的状态;

Store有三个核心概念:

  • state、getters、actions;
  • 等同于组件的data、computed、methods;
  • 一旦 store 被实例化,就可以直接在 store 上访问 state、getters 和 actions 中定义的任何属性;

2.3_定义一个Store

Store在它被使用之前是不会创建的,可以通过调用use函数来使用Store。

比如下面,counter.js是已经定义好的一个状态管理文件

<template>
  <div class="home">
    <h2>Home View</h2>
    <h2>count: {{ counterStore.count }}</h2>
    <h2>count: {{ count }}</h2>
    <button @click="incrementCount">count+1</button>
  </div>
</template>

<script setup>
  import { storeToRefs } from 'pinia'
  import useCounter from '@/stores/counter';

  const counterStore = useCounter()

  const { count } = storeToRefs(counterStore)

  function incrementCount() {
    counterStore.count++
  }

</script>

注意Store获取到后不能被解构,那会失去响应式,为了从 Store 中提取属性同时保持其响应式,需要使用storeToRefs()


3_Pinia核心概念State

3.1_认识和定义State

state 是 store 的核心部分,因为store是用来帮助管理状态的。 在 Pinia 中,状态被定义为返回初始状态的函数;

比如下面/src/store/user.js的代码

import { defineStore } from 'pinia'

const useUser = defineStore("user", {
  state: () => ({
    name: "coder",
    age: 18,
    level: 100
  })
})

export default useUser

3.2_操作State

读取和写入 state, 默认情况下,可以通过 store 实例访问状态来直接读取和写入状态;

import useUser from '@/stores/user';
const userStore = useUser()

userStore.age++
userStore.name = "xixi"

重置 State,可以通过调用 store 上的 $reset() 方法将状态 重置 到其初始值;

const userStore = useUser()
userStore.$reset()

改变State

  • 除了直接用 store.age++ 修改 store,还可以调用 $patch 方法;
  • 它允许使用部分“state”对象同时应用多个更改;
const userStore = useUser()

userStore.$patch({
  name: "hhh",
  age: 25,
  leval: 50
})

替换State, 可以通过将其 $state属性设置为新对象来替换 Store 的整个状态:

userStore.$state({
  name: "hehe",
  age: 10,
  leval: 2
})

4_Pinia核心概念Getters

4.1_认识

Getters相当于Store的计算属性computed:

  • 它们可以用 defineStore() 中的 getters 属性定义;
  • getters中可以定义接受一个state作为参数的函数;

比如src/store/counter.js

// 定义关于counter的store
import { defineStore } from 'pinia'

import useUser from './user'

const useCounter = defineStore("counter", {
  state: () => ({
    count: 99,
    friends: [
      { id: 111, name: "xixi" },
      { id: 112, name: "kobe" },
      { id: 113, name: "james" },
    ]    
  }),
  getters: {
    // 基本使用
    doubleCount(state) {
      return state.count * 2
    }
})  
export default useCounter                             

2.2_访问Getters

访问当前store的Getters

const conterStore = useCouter()
console.log(counterStore.doubleCount)
console.log(counterStore.doubleCountAddOne)

Getters中访问自己的其他Getters, 可以通过this来访问到当前store实例的所有其他属性;

  getters: {
   // 1.基本使用
    doubleCount(state) {
      return state.count * 2
    },
    // 2.一个getter引入另外一个getter
    doubleCountAddOne() {
      // this是store实例
      return this.doubleCount + 1
    },
  }  

访问其他store的Getters

  getters: {
  // getters中用到其他的store中的数据
    showMessage(state) {
      // 1.获取user信息
      const userStore = useUser()

      // 2.获取自己的信息

      // 3.拼接信息
      return `name:${userStore.name}-count:${state.count}`
    }
  }  

Getters也可以返回一个函数,这样就可以接受参数

  getters: {
    // getters也支持返回一个函数
    getFriendById(state) {
      return function(id) {
        for (let i = 0; i < state.friends.length; i++) {
          const friend = state.friends[i]
          if (friend.id === id) {
            return friend
          }
        }
      }
    }
  }  

5_Pinia核心概念Actions

5.1_认识

Actions 相当于组件中的 methods,可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑;

和getters一样,在action中可以通过this访问整个store实例的所有操作;

  actions: {
    increment() {
      this.count++
    },
    incrementNum(num) {
      this.count += num
    }
  }    

5.2_Actions执行异步操作

Actions中是支持异步操作的,且可以编写异步函数,在函数中使用await;

【Pinia状态管理】Pinia和Vuex的对比;创建Pinia的Store;Pinia核心概念State、Getters、Actions_第2张图片


在action中可以通过`this`访问整个store实例的所有操作;
  actions: {
    increment() {
      this.count++
    },
    incrementNum(num) {
      this.count += num
    }
  }    

你可能感兴趣的:(Vue,vue.js,vue,前端)