Vue | Vue.js 全家桶 Pinia状态管理

简介: Vue | Vue.js 全家桶 Pinia状态管理

一、Pinia和Vuex的对比

什么是Pinia呢?

       Pinia开始于2019年,最初作为一个实验为Vue重新设计状态管理,让它用起来像 组合式API(Composition API)


       从那时到现在,最初的设计原则依然相同,并且同时兼容Vue2 Vue3 也不要求你使用 Composition API


       Pinia本质上 依然是一个 状态管理的库 用于 跨组件 页面进行状态共享(和Vuex Redux一样)

Pina和Vuex的区别

       pinia最初是为了探索Vuex的下一次迭代会是什么样的,结合了Vuex5核心团队讨论中的许多想法


       最终,团队意识到Pinia已经实现了Vuex5中大部分内容,所以决定用Pinia来替代Vuex


       与Vuex比,Pinia提供了一个 更简单的API 具有更少的仪式,提供了CompositionAPI风格的API


       最重要的是,与TypeScript一起使用时具有可靠的类型推断支持;


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


       如:mutation不再存在:


               经常被认为是 非常冗长; 最初带来了devtools集成,但这不再是问题.


       更友好的TypeScript支持,Vuex之前对TS的支持不是很友好


       不再有modules的嵌套结构:


               可以灵活使用每一个store,是通过扁平化的方式来相互使用的


       不再有命名空间的概念,不需要记住它们的复杂关系

如何使用Pinia

安装Pinia

JavaScript
yarn add pinia
// or with npm
npm i pinia

创建一个pinia并且将其传递给应用程序:

JavaScript
import { createPinia } from 'pinia'
const pinia = createPinia()
export default pinia
JavaScript
// main.js文件中定义
import pinia from './stores/index'
createApp(App).use(pinia).mount('#app')

二、创建Pinia的Store

认识Store

什么是Store?


       一个Store(如pinia)是一个实体,它会持有为绑定到你组件树的状态和业务逻辑,也就是保存了全局的状态;


       有点像始终存在,并且 每个人都可以读取和写入的组件


       可以在你的应用程序中 定义任意数量的Store来管理你的状态


Store有三个核心概念:


       State getters actions


       等同于组件的 data computed  methods


       一旦store被实例化,就可以直接在store上访问state getters 和 actions中定义的任何属性

定义一个Store

定义一个Store:


       需要知道Store是使用defineStore()定义的


       并且需要一个唯一名称,作为第一个参数传递

JavaScript
import { defineStore } from 'pinia'
// defineStore 本身的返回值是一个函数
// 习惯用useXXX来命名 => 规范
const useCounter = defineStore("counter",{
    state:()=> ({
        count:999
    })
})
export default useCounter

308ddc710ff14244923b6295e7e7047c.png

这个name,也称为id 是必要的的,Pinia使用它来将store连接到devtools


返回的函数统一使用useXXX作为命名方案,这是约定的规范

使用定义的Store

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

JavaScript
<template>
  <div class="home">
    <h2>Home view</h2>
    <h2>count: {{ counterStore.count }}</h2>
  </div>
</template>
<script setup>
import useCounter from '@/stores/counter';
const counterStore = useCounter()
</script>
<style scoped>
</style>

注意Store获取到后不能被解构,不然会失去响应式!


       为了从Store中提取属性同时保持其响应式 需要使用storeToRefs()

三、Pinia核心概念 State

认识和定义State

state是store的核心部分,因为store是用来帮助我们管理状态的


在Pinia中,状态被定义为返回初始状态的函数

97bb87434e004043a3a5b4c1baf07dcd.png

操作State(一)

读取和写入state:


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

JavaScript
const counterStore = useCounter()
counterStore.count++
counterStore.name = "xiong"

重置State:


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

JavaScript
const counterStore = useCounter()
counterStore.$reset()

操作State(二)

改变State:


       除了直接使用store.counter++修改store,还可以调用$patch方法


       它允许你使用部分"state"对象 同时应用多个更改

JavaScript
function changeStateClick(){
    // 1 一个一个修改状态
    // userStore.name = "xiaoxiong"
    // userStore.age = 18
    // userStore.level = 9999
    // 2 一次性修改多个状态
    userStore.$patch({
      name:"xx",
      age:20
    })
  }

替换State:


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

JavaScript
counterStore.$state = {
    counter:1,
    name:"xxiong"
}

四、Pinia核心概念 Getters

认识和定义Getters

Getters相当于Store的计算属性:


       可以用defineStore()中的getters属性定义


       getters中可以定义接受一个state作为参数的函数

8dacf62dd69449778aafcaa96ec8e4c6.png

JavaScript
const useCounter = defineStore("counter",{
    state:()=> ({
        count:999,
        friends:[
            { id:1,name:"xiong" },
            { id:2,name:"xx" },
            { id:3,name:"xxiong" },
        ]
    }),
    getters:{
        // 1 基本使用
        doubleCount(state){
            return state.count * 2
        },
        // 2 一个getter引入另外一个getter
        doubleCountAddOne(){
            // 通过this访问 this绑定store实例
            return this.doubleCount + 1
        },
        // 3 getters也支持返回一个函数
        getFriendById(state){
            return function(id) {
                // 高阶js写法
                return state.friends.find(item => item.id === id )
                // 普通写法
                // for(let i = 0;i<state.friends.length;i++){
                //     const friend = state.friends[i]
                //     if(friend.id === id){
                //         return friend
                //     }
                // }
            }
        },
        // 4 getters中使用到别的store中的数据
        showMsg(state){
            // 展示 count  和 user内的信息
            // 在上面 导入 user包
            // 1 获取user信息
            const useStore = useUser()
            // 2 获取自己信息 state
            // 3 拼接信息
            return `name:${useStore.name}-count:${state.count}`
        }
    }
})

访问Getters(一)

访问当前Store的Getters:

7a23c00a24d44a2faede6e3c70b00b64.png

JavaScript
<h2>doubleCount: {{ countStore.doubleCount }}</h2>
<h2>doubleCountAddOne: {{ countStore.doubleCountAddOne }}</h2>
<h2>friend-2: {{ countStore.getFriendById(2) }}</h2>
<h2>拼接counter里面的count和user里面的名字: showMsg:{{ countStore.showMsg }}</h2>

Getters中访问自己的其他Getters:


       可以通过 this来访问到当前store实例的所有其他属性:

184598b27988497c954ea61114a36de4.png

JavaScript
doubleCountAddOne(){
    // 通过this访问 this绑定store实例
    return this.doubleCount + 1
},

访问其他store的Getters:

0361f2351e0645508685d7edbd9b1fde.png

JavaScript
// 4 getters中使用到别的store中的数据
showMsg(state){
    // 展示 count  和 user内的信息
    // 在上面 导入 user包
    // 1 获取user信息
    const useStore = useUser()
    // 2 获取自己信息 state
    // 3 拼接信息
    return `name:${useStore.name}-count:${state.count}`
}

访问Getters(二)

Getters也可以返回一个函数

8e768f49256b47f983b57a2a1ae4073c.png

46845533c20e40409d5231ec234e25c3.png

b4e23f1de9b84031a01d56e1d87be309.png

JavaScript
 // 3 getters也支持返回一个函数
getFriendById(state){
    return function(id) {
        // 高阶js写法
        return state.friends.find(item => item.id === id )
        // 普通写法
        // for(let i = 0;i<state.friends.length;i++){
        //     const friend = state.friends[i]
        //     if(friend.id === id){
        //         return friend
        //     }
        // }
    }
},

五、Pinia核心概念 Actions

认识和定义Actions

Actions相当于组件中的methods


       使用defineStore()中的actions属性定义,且它们非常适合业务逻辑

69bbfba055b44a72b748cb772d006615.png

b08d14b6817743fea324bda34d23a024.png

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

JavaScript
actions:{
    // 用来定义方法,这里不会给我们传进来一个state,
    // 他用来传递参数
    increment() {
        this.count++
    },
    // 如:下示例
    incrementAdd(num){
        this.count += num
    }
}

Actions执行异步操作

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

JavaScript
 actions:{
    async fetchHomeMultidata(){
        const res = await fetch("http://xxxx:8000/home/")
        const data = await res.json()
        // console.log(data) // 拿到数据
        this.banners = data.data.banner.list
        this.recommends = data.data.recommend.list
    }
}
相关文章
|
3月前
|
JavaScript 前端开发 开发者
VUE 开发——Node.js学习(一)
VUE 开发——Node.js学习(一)
93 2
|
10天前
|
JavaScript API 数据处理
vue3使用pinia中的actions,需要调用接口的话
通过上述步骤,您可以在Vue 3中使用Pinia和actions来管理状态并调用API接口。Pinia的简洁设计使得状态管理和异步操作更加直观和易于维护。无论是安装配置、创建Store还是在组件中使用Store,都能轻松实现高效的状态管理和数据处理。
39 3
|
2月前
|
JavaScript 前端开发 持续交付
构建现代Web应用:Vue.js与Node.js的完美结合
【10月更文挑战第22天】随着互联网技术的快速发展,Web应用已经成为了人们日常生活和工作的重要组成部分。前端技术和后端技术的不断创新,为Web应用的构建提供了更多可能。在本篇文章中,我们将探讨Vue.js和Node.js这两大热门技术如何完美结合,构建现代Web应用。
45 4
|
2月前
|
JavaScript 前端开发 开发者
JavaScript框架React vs. Vue:一场性能与易用性的较量
JavaScript框架React vs. Vue:一场性能与易用性的较量
40 0
|
3月前
|
存储 JavaScript 前端开发
深入理解 Vuex:Vue.js 状态管理的利器
【10月更文挑战第11天】 深入理解 Vuex:Vue.js 状态管理的利器
57 2
|
3月前
|
JavaScript 前端开发 API
探索Vue.js 3的组合式API:一种更灵活的组件状态管理方式
【10月更文挑战第5天】探索Vue.js 3的组合式API:一种更灵活的组件状态管理方式
|
3月前
|
监控 JavaScript 安全
vue3添加pinia
本文介绍了Pinia作为Vue 3的状态管理库的特点,包括其基于Vue 3的Composition API、响应式状态管理、零依赖设计、插件系统、Devtools集成、Tree-shakable特性以及对TypeScript的支持,并详细说明了如何在Vue 3项目中安装和初始化Pinia。
56 0
vue3添加pinia
|
4月前
|
JavaScript 前端开发 API
Vue学习笔记3:对比纯JavaScript和Vue实现数据更新的实时视图显示
Vue学习笔记3:对比纯JavaScript和Vue实现数据更新的实时视图显示
|
3月前
|
JavaScript 前端开发 应用服务中间件
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
212 0
|
3月前
|
JavaScript
深入解析:JS与Vue中事件委托(事件代理)的高效实现方法
深入解析:JS与Vue中事件委托(事件代理)的高效实现方法
62 0