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 } 
})
相关推荐
浅影歌年8 小时前
vue3模块中引用公共css变量文件
前端
盼哥PyAI实验室9 小时前
从搭建到打磨:我的纯前端个人博客开发复盘
前端·javascript
前端初见9 小时前
2025前端面试题大合集
前端
用户904706683579 小时前
vue3.5新特性——useTemplateRef
前端
嘉琪00110 小时前
vue3+ts面试题(一)JSX,SFC
前端·javascript·react.js
何贤10 小时前
🪐 行星科技概念官网!Hero Section 回归!(Three.js ✨)
前端·javascript·three.js
前端拿破轮10 小时前
ReactNative从入门到性能优化(一)
前端·react native·客户端
码界奇点10 小时前
Java Web学习 第1篇前端基石HTML 入门与核心概念解析
java·前端·学习·xhtml
云枫晖10 小时前
Webpack系列-开发环境
前端·webpack