pinia

60 阅读2分钟

修改数据的三种方式

第一种方式直接修改

countStore.sum = 6

第二种方式:批量修改(patch碎片化修改)

countStore.$patch({
    sum:9,
    school: 'atgu'
 })

第三种方式:借助action修改(action中可以编写一些业务逻辑)

import { defineStore } from pinia
export const useCountStore = defineStore('count', {
    actions: {
        increment(value: number) {
            if(this.sum < 20) {
                this.sum += value
            }
        }
    },
    //真正存储数据的地方
    state() {
        return {
            sum: 6,
            school: 'atgu'
        }
    }
})
Count.vue
<template>
    <div>
        <h2>求和: {{countStore.sum}}</h2>
        <button @click="add"></button>
    </div>
</template>
<script setup lang="ts" name="Count">
    import {ref, reactive } from 'vue'
    //引入useCountStore
    import { useCountStore } from '@/store/count'
    // 使用useCountStore, 得到一个专门保存count相关的store
    const countStore = useCountStore()
    //数据
    let n = ref(1) //用户选择的数字
    // 方法
    function add() {
        //第一种方式
        countStore.sum += 1
        //第二种方式
        countStore.$patch({
            sum:999,
            school: 'atgu'
        })
        //第三种方式
        countStore.increment(n.value)
    }
    
</script>

storeToRefs的使用

借助storeToRefs将store中的数据转为ref对象,方便在模板中使用 注意:pinia提供的storeToRefs只会将数据做转换,而vue的toRefs会转换store中数据

<template>
    <div>
        <h2>求和: {{sum}}</h2>
        <h2>学校: {{school}}</h2>
    </div>
</template>
<script setup lang="ts" name="Count">
    import {ref, reactive } from 'vue'
    import { storeToRefs } from 'pinia'
    //引入useCountStore
    import { useCountStore } from '@/store/count'
    // 使用useCountStore, 得到一个专门保存count相关的store
    const countStore = useCountStore()
    // storeToRefs只会关注store中的数据,不会对方法进行ref包裹
    const { sum, school }  storeToRefs(countStore)
    
</script>

getters

1.概念:当state中的数据,需要经过处理后再使用时,可以使用getters配置 2.追加getters配置

count.ts
//引用defineStore用于创建store
import { defineStore } from 'pinia'
// 定义并暴露一个store
export const useCountStore = defineStore('count', {
    //动作
    action: {
    
    },
    //状态
    state() {
        return {
            sum: 1,
            school: 'atgu'
        }
    },
    //计算
    getters: {
        bigSum:(state):number => state.sum * 10,
        upperSchool():string {
            return this.school.toUpperCase()
        }
    }
})
Count.vue
<template>
    <div>
        <h2>当前求和: {{sum}},放大10倍后: {{bigSum}}</h2>
        <h2>学校: {{school}},大写的学校名称:{{upperSchool}}</h2>
    </div>
</template>
<script setup lang="ts" name="Count">
    import {ref, reactive } from 'vue'
    import { storeToRefs } from 'pinia'
    //引入useCountStore
    import { useCountStore } from '@/store/count'
    // 使用useCountStore, 得到一个专门保存count相关的store
    const countStore = useCountStore()
    // storeToRefs只会关注store中的数据,不会对方法进行ref包裹
    const { sum, school,bigSum, upperSchool }  storeToRefs(countStore)
    
</script>

subscribe(订阅使用)

Talk.vue
<script setup lang="ts" name="Talk">
import {useTalkStore} from '@/store/talk'
import { storeToRefs } from 'pinia'
const talkStore = useTalkStore()
const { talkList} = storeToRefs(talkStore)
talkStore.$subscribe((mutate, state) => {
    console.log('talkStore里面保存的数据发生了变化', mutate, state)
    localStore.setItem('talkList', JSON.stringify(state.talkList))
})
//方法
function getTalk() {
    talkStore.getATalk()
}
</script>
talk.ts
import { defineStore } from pinia
import axios from 'axios'
import { nanoid } from 'nanoid'
//选项式写法
export const useTalkStore = defineStore('talk', {
    actions: {
        async getATalk() {
            //发请求,下面这行的写法是:连续解构赋值+重命名
            let {data:{content:title}} = await axios.get('https:// ...')
            // 把请求回来的字符串,包装成一个对象
            let obj = {id: nanoid(), title}
            //放在数组中
            this.talkList.unshift(obj)
        }
    },
    //真正存储数据的地方
    state() {
        return {
            talkList: JSON.parse(localStorage.getItem('talkList') as string) || []
        }
    }
})
//组合式写法
import { reactive } from 'vue'
export 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('https:// ...')
        // 把请求回来的字符串,包装成一个对象
        let obj = {id: nanoid(), title}
        //放在数组中
        this.talkList.unshift(obj)
    }
    return  {talkList, getATalk}
})