pinia符合直觉的vue状态管理库
集中式状态(数据)管理
安装:
npm i pinia
main.ts
import {createApp} from 'vue'
//第一步:引入pinia
import {createPinia} from 'pinia'
const app=createApp(App)
//第二步:创建pinia
const pinia=createPinia()
//第三步:安装pinia
app.use(pinia)
app.mount('#app')
存储和读取数据
store是一个保存:状态、业务逻辑的实体,每个组件都可以读取、写入它
他有三个概念:state、getter、action,相当于组件中的:data、computed和methods
store/count.ts
import {definStore} from 'pinia'
//useCountStore命名使用hook方式,第一个参数count是id
export const useCountStore=defineStore('count',{
//真正存储数据的地方
state(){
return{
sum:6,
school:'atg',
address:'ddd'
}
}
})
count.vue
<script setup lang="ts">
import {useCountStore} from '@/store/count'
const countStore=useCountStore()
//以下两种方式都可以拿到state中的数据
console.log(countStore.sum)
console.log(countStore.$state.sum)
</script>
修改数据(三种方式)
1)第一种修改方式,直接修改
vuex中数据不可以直接修改,在pinia中可以直接修改
直接修改:countStore.sum=666
实例:
count.vue
<template>
<button @click="add">+</button>
<button @click="minus">-</button>
</template>
<script setup lang="ts" name="Count">
import {useCountStore} from '@/store/count'
const countStore=useCountStore()
function add(){
countStore.sum+=1
}
</script>
2)第二种修改方式:批量修改
countStore.$patch({ //patch碎片
sum:999,
school:'atgu'
})
实例:
count.vue
<template>
<button @click="add">+</button>
<button @click="minus">-</button>
</template>
<script setup lang="ts" name="Count">
import {useCountStore} from '@/store/count'
const countStore=useCountStore()
function add(){
//可以直接修改 修改时,修改几次执行几次mutation
countStore.sum=999
//建议多个使用下面
countStore.$patch({ 修改时,执行一次patch更新
sum:999,
school:'atgu'
})
}
</script>
3)第三种修改方式:借助action修改(action中可以编写一些业务逻辑)
store/count.ts
import {definStore} from 'pinia'
export const useCountStore=defineStore('count',{
state(){
return{
sum:6,
school:'atg',
address:'ddd'
}
},
acitons:{
//加
increament(value:number){
if(this.sum<10){
this.sum+=value
}
}
}
})
count.vue
<template>
<button @click="add">+</button>
<button @click="minus">-</button>
</template>
<script setup lang="ts" name="Count">
let n=ref(1)
import {useCountStore} from '@/store/count'
const countStore=useCountStore()
function add(){
countStore.increament(n.value)
}
</script>
storeToRefs
<script setup lang="ts">
import {storeToRefs} from 'pinia'
import {useCountStore} from '@/store/count'
const countStore=useCountStore()
//toRef会处理所有的数据,包括increament方法,有些不必要,所有引入pinia中storeToRefs
//storeToRefs只关注store里的数据,而不关注里面的方法进行ref包裹
//const {sum,school,address}=toRefs(countStore)
const {sum,school,address}=storeToRefs(countStore)
</script>
getters
概念:当state中的数据,需要经过处理后在使用时,可以使用getters配置
追加getters配置
import {defineStore} from 'pinia'
export const useCountStore=definStore('count',{
//动作
actions:{
increament(value:number){
this.sum+=value
}
},
//状态
state(){
return{
sum:1,
school:'atg'
}
},
getters:{
bigSum(state){
return state.sum*10 //放大10倍
},等价于:
bigSum:state=>state.sum*10,
upperSchool(state):string{
return state.school.toUpperCase() 等价于:
return this.school.toUpperCase()
}
}
})
$subscribe
通过store的$subscribe()方法侦听state及其变化
<script setup lang="ts">
import {useTalkStore} from '@/store/loveTalk'
let talkStore=useTalkStore()
//mutate本次修改信息
//state真正数据
//类似watch
talkStore.$subscribe((mutate,state)=>{
console.log('talkStore里面保存的数据发生了变化')
localStorege.setItem('talkList',JSON.stringify(state.talkList))
})
</script>
//store/loveTalk.ts
import {defineStore} from 'pinia'
export const useTalkStore=defineStore('talk',{
state(){
return{
//刷新数据不丢失
talkList:JSON.parse(localStorage.getItem('talkList') as string)||[]
}
}
})
store组合式写法
//store/loveTalk.ts
import {reactive} from 'vue'
exprot const useTalkStore=defineStore('talk',()=>{
//talkList就是state
const talkList=reactive(JSON.parse(localStorage.getItem('talkList') as string)||[])
//getATalk函数相当于action
async function getATalk(){
let {data:{content:title}}=await axios.get('地址')
let obj={id:nanoid(),title}
talkList.unshift
}
return {talkList,getATalk}
})