Pinia

学习总结

一、简介

  1. 概念:Pinia是Vue的存储库,它允许您跨组件/页面共享状态,与 vuex 功能一样
  2. 安装:npm i pinia

二、搭建Pinia环境

import { createPinia } from 'pinia'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)

三、存储+读取数据

  1. store是一个保存:状态、业务逻辑的实体,每个组件都可以读取、写入它
  2. 有三个概念:state、getter、action,相当于组件中的:data、computed和methods
  3. store是一个用reactive包裹的对象,这意味着不需要在getter之后写.value,但是,就像setup中的props一样,不能对其进行解构
  4. 具体编码:
// src/store/count.ts
import { defineStore } from "pinia";
export const useCountStore = defineStore("count", {
    // 动作
    actions: {},
    state: () => {
        return {
            sum: 0,
        };
    },
    // 计算
    getters: {}
});


// src/store/talk.ts
import { defineStore } from "pinia";
export const useTalkStore = defineStore("talk", {
    // 动作
    actions: {},
    // 状态
    state() {
        return {
            talkList: [
                { id: 'tuwei01', title: '今天你有点怪,哪里怪?怪好看的!' },
                { id: 'tuwei02', title: '草莓、蓝莓、蔓越莓,今天你想我了没?' },
                { id: 'tuwei03', title: '心里给你留了一块地,我的死心塌地' }
            ]
        };
    },
    // 计算
    getters: {}
});

四、三种修改数据的方式

import { ref } from 'vue'
// 引入store
import { useCountStore } from '@/store/count'
// 使用
const countStore = useCountStore()

// 数据
let n = ref(1)  // 用户选择的数字

// 方法
function add() {
    // 第一种修改方式:直接修改
    countStore.sum += Number(n.value)

    // 第二种修改方式:批量修改
    countStore.$patch({
        sum: countStore.sum + Number(n.value),
        address: '中国'
    })

    // 第三种修改方式:借助action修改(action中可以编写一些业务逻辑)
    countStore.increment(n.value)
}

function minus() {
    countStore.sum -= n.value
}
<div class="count">
        <h3>欢迎来到:{{ countStore.school }},坐落于{{ countStore.NewYork }}</h3>
        <h2>当前求和为:{{ countStore.sum }}</h2>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="add">+</button>
        <button @click="minus">-</button>
    </div>
import { defineStore } from "pinia";
export const useCountStore = defineStore("count", {
    // 第三种
    // actions里面放置的是一个一个方法,用于响应组件中的“动作”
    actions: {
        increment(value) {
            if (this.sum < 10) {
                // 修改数据(this是当前的store对象)
                this.sum++
            }
        }
    },
    // 真正存储数据的地方
    state: () => {
        return {
            sum: 0,
            school: 'HIST',
            address: 'NewYork'
        };
    },
    // 计算
    getters: {}
});

五、storeToRefs

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

import { ref } from 'vue'
import { storeToRefs } from 'pinia'
// 引入store
import { useCountStore } from '@/store/count'
// 使用
const countStore = useCountStore()
const { sum, school, address } = storeToRefs(countStore)


// 数据
let n = ref(1)  // 用户选择的数字

// 方法
function add() {
    // 第三种修改方式
    countStore.increment(n.value)
}

function minus() {
    countStore.sum -= n.value
}
 <div class="count">
        <h3>欢迎来到:{{ school }},坐落于{{ NewYork }}</h3>
        <h2>当前求和为:{{ sum }}</h2>
        <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
        </select>
        <button @click="add">+</button>
        <button @click="minus">-</button>
    </div>

六、getters

  1. 概念:当state中的数据,需要经过处理后再使用时,可以使用getters配置
  2. 追加getters配置
import { defineStore } from "pinia";

export const useCountStore = defineStore("count", {
    // actions里面放置的是一个一个方法,用于响应组件中的“动作”
    actions: {
        increment(value:number) {
            if (this.sum < 10) {
                // 修改数据(this是当前的store对象)
                this.sum++
            }
        }
    },
    // 真正存储数据的地方
    state: () => {
        return {
            sum: 0,
            school: 'HIST',
            address: 'NewYork'
        };
    },
    // 计算
    getters: {
        bigSum(state){
            return state.sum * 10
        },
        upperSchool():string{
            return this.school.toUpperCase()
        }
    }
});
import { ref } from 'vue'
import { storeToRefs } from 'pinia'
// 引入store
import { useCountStore } from '@/store/count'
// 使用
const countStore = useCountStore()
const { sum, school, address, bigSum, upperSchool } = storeToRefs(countStore)


// 数据
let n = ref(1)  // 用户选择的数字

// 方法
function add() {
    // 第三种修改方式
    countStore.increment(n.value)
}

function minus() {
    countStore.sum -= n.value
}

七、action

  1. action相当于组件中的methods,可以使用defineStore()中的actions属性定义,并且他们非常适合定义业务逻辑
  2. actions支持异步操作的,可以编写异步函数

八、$subscribe订阅

<div class="talk">
    <button @click="getLoveTalk">获取一个土味情话</button>
    <ul>
        <li v-for="talk in talkStore.talkList" :key="talk.id">{{ talk.title }}</li>
    </ul>
</div>
import { reactive } from 'vue'
import { useTalkStore } from '@/store/loveTalk';

const talkStore = useTalkStore()
// const talkList = reactive(useTalkStore().talkList)

talkStore.$subscribe((mutate, state) => {
    console.log('talkStore里保存的数据发生了变化', mutate, state);
    localStorage.setItem('talkList',JSON.stringify(state.talkList))
})

function getLoveTalk() {
    talkStore.getATalk()
}
import { defineStore } from "pinia";
import axios from 'axios'
import { nanoid } from "nanoid";

export const useTalkStore = defineStore("talk", {
    // 动作
    actions: {
        async getATalk() {
            let { data } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
            this.talkList.unshift({ id: nanoid(), title: data.content })
        }
    },
    // 状态
    state() {
        return {
            talkList: JSON.parse(localStorage.getItem('talkList') as string) || []
        };
    },
    // 计算
    getters: {}
});

九、store组合式写法

import { defineStore } from "pinia";
import axios from 'axios'
import { nanoid } from "nanoid";
import { reactive } from "vue";

// export const useTalkStore = defineStore("talk", {
//     // 动作
//     actions: {
//         async getATalk() {
//             let { data } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
//             this.talkList.unshift({ id: nanoid(), title: data.content })
//         }
//     },
//     // 状态
//     state() {
//         return {
//             talkList: JSON.parse(localStorage.getItem('talkList') as string) || []
//         };
//     },
//     // 计算
//     getters: {}
// });

export const useTalkStore = defineStore('talk', () => {
    // talkList就是state
    const talkList = reactive(
        JSON.parse(localStorage.getItem('talkList') as string) || []
    )

    // getATalk函数相当于action
    async function getATalk() {
        let { data } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
        this.talkList.unshift({ id: nanoid(), title: data.content })
    }

    return {
        talkList,
        getATalk
    }
})

下周计划

下周开始小组官网,vue感觉学的不是很好,还需要多复习复习

本周总结

本周就一个字忙!小组和纪检部两边都需要带新生,各种事情忙的团团转,今天去看了一下社团招新领到了小玩意
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值