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
    }
}
相关文章
|
4天前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
58 1
|
3月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
516 0
|
3月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
2月前
|
JavaScript 安全
在 Vue 中,如何在回调函数中正确使用 this?
在 Vue 中,如何在回调函数中正确使用 this?
96 0
|
2月前
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
221 1
|
3月前
|
JavaScript 前端开发 开发者
Vue 自定义进度条组件封装及使用方法详解
这是一篇关于自定义进度条组件的使用指南和开发文档。文章详细介绍了如何在Vue项目中引入、注册并使用该组件,包括基础与高级示例。组件支持分段配置(如颜色、文本)、动画效果及超出进度提示等功能。同时提供了完整的代码实现,支持全局注册,并提出了优化建议,如主题支持、响应式设计等,帮助开发者更灵活地集成和定制进度条组件。资源链接已提供,适合前端开发者参考学习。
357 17
|
3月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
198 1
|
3月前
|
JavaScript API 开发者
Vue框架中常见指令的应用概述。
通过以上的详细解析,你应该已经初窥Vue.js的指令的威力了。它们是Vue声明式编程模型的核心之一,无论是构建简单的静态网站还是复杂的单页面应用,你都会经常用到。记住,尽管Vue提供了大量预定义的指令,你还可以创建自定义指令以满足特定的需求。为你的Vue应用程序加上这些功能增强器,让编码变得更轻松、更愉快吧!
67 1
|
3月前
|
存储 JavaScript 前端开发
如何高效实现 vue 文件批量下载及相关操作技巧
在Vue项目中,实现文件批量下载是常见需求。例如文档管理系统或图片库应用中,用户可能需要一次性下载多个文件。本文介绍了三种技术方案:1) 使用`file-saver`和`jszip`插件在前端打包文件为ZIP并下载;2) 借助后端接口完成文件压缩与传输;3) 使用`StreamSaver`解决大文件下载问题。同时,通过在线教育平台的实例详细说明了前后端的具体实现步骤,帮助开发者根据项目需求选择合适方案。
271 0
|
3月前
|
JavaScript 前端开发 UED
Vue 项目中如何自定义实用的进度条组件
本文介绍了如何使用Vue.js创建一个灵活多样的自定义进度条组件。该组件可接受进度段数据数组作为输入,动态渲染进度段,支持动画效果和内容展示。当进度超出总长时,超出部分将以红色填充。文章详细描述了组件的设计目标、实现步骤(包括props定义、宽度计算、模板渲染、动画处理及超出部分的显示),并提供了使用示例。通过此组件,开发者可根据项目需求灵活展示进度情况,优化用户体验。资源地址:[https://pan.quark.cn/s/35324205c62b](https://pan.quark.cn/s/35324205c62b)。
125 0