Vue3的Pinia详解

Pinia 是由 Vue 官方团队开发的轻量级状态管理库,旨在为 Vue 应用提供更简洁、模块化的状态管理方案。

`Store`是一个保存:''状态''、''业务逻辑'' 的实体,每个组件都可以''读取''、''写入''它。 它有三个概念:`state`、`getter`、`action`,相当于组件中的: `data`、 `computed` 和 `methods`。

创建pinia

在src文件夹下创建store文件,及store文件里的具体文件名.ts文件

javascript 复制代码
import { defineStore } from 'pinia'

//创建一个求和的pinia,count可随意
export const useCountStore = defineStore('count',{
    //真正存储数据的地方,state需要以函数的形式返回
    state(){
        return{
            sum:6
        }
    }
})

存储读取pinia

javascript 复制代码
<template>
    <div> {{countStore.sum}} </div>
    <button>加</button>
    <button>减</button>
</template>

<script setup lang="ts">
    
    import { useCountStore } from '@/store/count' //引入写好的store数据
    
    let countStore = useCountStore()

    //此时的countStore中的sum是一个ref,你可能会就觉得使用countStore.sum.value就可以拿到值
    //其实不然,这是一个坑,之后再说
    console.log(countStore.sum)//拿取值
    console.log(countStore.$state.sum)//拿取值
    
</script>
javascript 复制代码
let sum = reactive({
    a:1,
    b:3,
    c:ref(4)
})

sum.c.value //undefind
sum.c   // 4


let count = ref(4)

count.value  //4

修改Pinia数据

javascript 复制代码
<template>
    <div> {{countStore.sum}} </div>
    <button @click="add">加</button>
    <button>减</button>
</template>

<script setup lang="ts">
    import { ref } from 'vue'
    import { useCountStore } from '@/store/count' //引入写好的store数据
    
    let countStore = useCountStore()

    function add(){
        //第一种修改方式,直接更改,而且store里的数据也是同步更改的。
        //不像Vue2需要action和mutation                                   
        countStore.sum +=1 

        //第二种修改方式 适用于批量更改,如果要更改的store的数据过多,一行一行更改不够优雅
        //countStore.sum +=1;countStore.xx +=1;countStore.yy +=1;
    
        countStore.$patch({
            sum:2,
            xx:3,
            yy:4
        })

        //第三种方式 需要使用actions,要在配置store中,怎么配置稍后
        let n = ref(2)
        countStore.increment(n.value)
        
    }
    
</script>

配置pinia的actions

javascript 复制代码
import { defineStore } from 'pinia'

export const useCountStore = defineStore('count',{
    //actions里面放置的是一个一个的方法,用于响应组件中的动作
    actions:{
        increment(value){ //value为传递的数据
            //this.sum  访问state的值 this指的是 当前的store,也就是 CountStore
            this.sum += value
        }
    },
    state(){
        return{
            sum:6
        }
    }
})

storeToRefs

优雅获取处理store数据

javascript 复制代码
<template>
    //这样countStore.sum获取值不够优雅
   //<div> {{countStore.sum}} </div>
    //<div> {{countStore.xx}} </div>

    <div> {{sum}} </div>
    <div> {{xx}} </div>
</template>

<script setup lang="ts">
    import { ref } from 'vue'
    import { useCountStore } from '@/store/count' //引入写好的store数据

    import { storeToRefs } from 'pinia' //引入storeToRefs
    
    let countStore = useCountStore()

    let { sum,xx } = storeToRefs(countStore)

    //如果使用 toRefs 的话,会获取countStore的所有东西,代价太大
    //而storeToRefs 只会关注store中的数据,不会对方法进行ref包裹

</script>

getters的使用

当`state`中的数据,需要经过处理后再使用时,可以使用`getters`配置

配置getters

javascript 复制代码
import { defineStore } from 'pinia'

//创建一个求和的pinia,count可随意
export const useCountStore = defineStore('count',{
    //真正存储数据的地方,state需要以函数的形式返回
    state(){
        return{
            sum:6
        }
    },
    getters:{
        bigSum(state){
            return state.sum *10
        },
        //bigSum:state => state.sum *10

        //bigSum():number{
            //return state.sum *10
        //}
    }
})

使用getters

javascript 复制代码
<template>
    <div> {{sum}} 放大十倍是{{ bigSum }}</div>
    <div> {{xx}} </div>
</template>

<script setup lang="ts">
    import { ref } from 'vue'
    import { useCountStore } from '@/store/count' //引入写好的store数据

    import { storeToRefs } from 'pinia' //引入storeToRefs
    
    let countStore = useCountStore()

    let { sum,xx,bigSum } = storeToRefs(countStore)

</script>

$subscribe的使用

通过 store 的 $subscribe() 方法侦听 state 及其变化

javascript 复制代码
<template>
    <div> {{countStore.sum}} </div>
    <button @click="add">加</button>
    <button>减</button>
</template>

<script setup lang="ts">
    import { ref } from 'vue'
    import { useCountStore } from '@/store/count' //引入写好的store数据
    
    let countStore = useCountStore()

    countStore.$subscribe((mutate,state)=>{
        //参数mutate,state类似于watch的参数
    }) 

    function add(){                                  
        countStore.sum +=1 
    }
    
</script>

store组合式写法

javascript 复制代码
import { defineStore } from 'pinia'
import { ref } from 'vue'

export const useCountStore = defineStore('count',()=>{
    let sum = ref(0)

    increment(value){ //value为传递的数据
       sum.value += value
    }
    return { sum,increment } 
})
相关推荐
兰亭妙微UI设计公司6 分钟前
兰亭妙微软件界面设计公司的解锁按钮设计10大密码
开发语言·前端·javascript
迪幻29 分钟前
封装自己的 npm 依赖并存储到个人 GitHub
前端·npm·github
u0111026751 小时前
WebP 转成 PNG 后为什么更大?图片格式转换不等于压缩
前端·javascript·vue.js
万少1 小时前
Qoder sonus模型 20分钟,复刻 马斯克 飞天汽车
前端·后端·算法
seconp1 小时前
基于Spring Boot和Vue 3的智慧旅游网站:住宿预订、行程规划与千问接入
vue.js·spring boot·毕业设计·软件工程·课程设计·旅游·毕设
java1234_小锋1 小时前
【技术专题】HTML5 网页技术 - HTML5 列表标签
前端·html·html5
强二小哥帅1 小时前
Kotlin 协程复习笔记
前端
不可能片场1 小时前
工程实践 原子替换改了 ctime 怎么修
前端·electron
暧暧内含光1 小时前
HTTP 文件传输体系全解:从协议标头、OSS 架构到流媒体分片
前端
静默回滚1 小时前
浏览器能显示AVIF,却导不出一张AVIF
前端