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
    }
}
相关文章
|
12天前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
28 1
vue学习第四章
|
12天前
|
JavaScript 前端开发
vue学习第九章(v-model)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生,自学前端2年半,正向全栈进发。此篇介绍v-model在不同表单元素中的应用及修饰符的使用,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
25 1
vue学习第九章(v-model)
|
12天前
|
JavaScript 前端开发 开发者
vue学习第十章(组件开发)
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文深入讲解Vue组件的基本使用、全局与局部组件、父子组件通信及数据传递等内容,适合前端开发者学习参考。持续更新中,期待您的关注!🎉🎉🎉
27 1
vue学习第十章(组件开发)
|
18天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
18天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
18天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
18天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
17天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
26 3
|
19天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
17天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
36 2