1.搭建pinia环境
yarn add pinia
// 或者
npm install pinia
2.配置 src/main.ts
/* src/main.ts */
import { createApp } from 'vue'
import App from './App.vue'
/* 引入createPinia,用于创建pinia */
import { createPinia } from 'pinia'
/* 创建pinia */
const pinia = createPinia()
const app = createApp(App)
/* 使用插件 */
app.use(pinia)
app.mount('#app')
3.存储+读取数据
-
Store
是一个保存:状态、业务逻辑 的实体,每个组件都可以读取、写入它。 -
它有三个概念:
state
、getter
、action
,相当于组件中的:data
、computed
和methods
。 -
具体编码:
src/store/user.ts
// 引入defineStore用于创建store
import {defineStore} from 'pinia'
// 定义并暴露一个store
export const useUserStore = defineStore('user',{
// 状态 为了完整类型推理,推荐使用箭头函数
state: () => ({
count:6,
talkList:[
{id:'1',content:'嘻嘻嘻'},
{id:'2',content:'哈哈哈'},
{id:'3',content:'嘿嘿嘿'}
]
}),
// 也可以这样写
//state:()=>{
// return{
// count:0,
// talkList:[
// {id:'1',content:'嘻嘻嘻'},
// {id:'2',content:'哈哈哈'},
// {id:'3',content:'嘿嘿嘿'}
// ]
// }
// },
// 动作
actions:{},
// 计算
getters:{}
})
/* 组件中使用state中的数据 */
<template>
<ul>
<li v-for="talk in userStore.talkList" :key="talk.id">
{{ talk.content }}
</li>
</ul>
</template>
<script setup lang="ts">
// 引入对应的useXxxxxStore
import {useUserStore} from '@/store/user'
// 调用useXxxxxStore得到对应的store
const userStore = useUserStore()
</script>
借助storeToRefs
将store
中的数据转为ref
对象,方便在模板中使用。
<template>
<ul>
<li v-for="talk in talkList" :key="talk.id">
{{ talk.content }}
</li>
</ul>
</template>
<script lang="ts" setup>
import { ref, reactive, toRefs, toRef } from 'vue'
import { useUserStore } from '@/store/user'
/* 引入storeToRefs */
import { storeToRefs } from 'pinia'
const userStore = useUserStore()
/*
使用storeToRefs转换countStore,随后解构
pinia提供的storeToRefs只会将数据转换为ref对象,而Vue中的`toRefs`会转换`store`中的数据。
*/
const { talkList } = storeToRefs(userStore)
</script>
4、修改state里的数据(三种方式)
1.第一种修改方式,直接修改
<script lang="ts" setup>
import { ref, reactive, toRefs, toRef } from 'vue'
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
// 把 user.ts 里的 count 改为66
userStore.count = 66
</script>
2.第二种修改方式:$patch 批量修改
userStore.$patch({
count: userStore.count + 2,
talkList: [
{ id: '1', content: 'xixixi' },
{ id: '2', content: 'hahaha' },
{ id: '3', content: 'hhh' }
]
})
3.第三种修改方式:action
修改(action
中可以编写一些异步业务逻辑)
<template>
<el-button @click="add">{{ userStore.count }}</el-button>
</template>
<script lang="ts" setup>
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
function add (){
userStore.incrementOdd(2)
}
</script>
// user.ts
actions:{
incrementOdd(value:number) {
//操作useUserStore中的count
this.count += value
},
},
5、getters
当state
中的数据,需要经过处理后再使用时,可以使用getters
配置。追加getters配置:
// 引入defineStore用于创建store
import { defineStore } from 'pinia'
import { loginApi, getInfoApi, loginOutApi } from '@/api/user'
// export interface State {
// token: string,
// info: object
// }
// 定义并暴露一个store
export const useUserStore = defineStore('user', {
state: () => ({
token: '',
info: {},
count:6,
school:'qinghua',
talkList:[
{id:'1',content:'嘻嘻嘻'},
{id:'2',content:'哈哈哈'},
{id:'3',content:'嘿嘿嘿'}
]
}),
// 动作
actions: {
incrementOdd(value:number) {
//操作useUserStore中的count
this.count += value
},
},
// 计算
getters: {
bigCount:(state):number => state.count*10,
upperSchool():string{
return this.school.toUpperCase()
}
}
}
})
// 组件中读取数据:
const {incrementOdd} = countStore
let {sum,school,bigSum,upperSchool} = storeToRefs(countStore)
6、通过 store 的$subscribe()
方法侦听 state
及其变化
countStore.$subscribe((mutate,state)=>{
console.log('LoveTalk',mutate,state)
localStorage.setItem('talk',JSON.stringify(talkList.value))
})