当前位置: 首页 > article >正文

Vue - pinia

Pinia 是 Vue 3 的官方状态管理库,旨在替代 Vuex,提供更简单的 API 和更好的 TypeScript 支持。Pinia 的设计遵循了组合式 API 的理念,能够很好地与 Vue 3 的功能结合使用。

Pinia 的基本概念

  • Store: Pinia 中的核心概念,类似于 Vuex 中的 Store。它是一个用于管理状态的中心地点。
  • State: 存储的数据,可以在多个组件之间共享。
  • Getters: 类似于计算属性,用于从状态派生出新的信息。
  • Actions: 用于包含逻辑的方法,可以用于修改状态或处理异步操作。

步骤一:下载 pinia :

npm install pinia
// 或者
pnpm install pinia

步骤二:设置 pinia :

步骤三:创建 store 文件夹

// person.ts 船舰一个新的 store

import { defineStore } from "pinia";

export const usePersonStore = defineStore('person', {
    // 真正存储数据的地方
    state() {
        return {
            sum:20
        }
    }
})
import axios from "axios";
import { nanoid } from "nanoid";
import { defineStore } from "pinia";

export const useTalkStore = defineStore('talk', {
    actions: {
        async getATalk() {
            // 发送请求
            const res = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
            // 把请求回来的字符串,包装成一个对象
            // pnpm i nanoid 自动生成id
            const obj = { id: nanoid(), title: res.data.content }
            // 放入数组当中
            this.talkList.unshift(obj);
      }  
    },
    // 真正存储数据的地方
    state() {
        return {
            talkList: [
                { id: '001', title: '星期一' },
                { id: '002', title: '星期二' },
                { id: '003', title: '星期三' },
            ]
        }
    }
})

 

步骤四:使用 store  (存储和读取数据)

// Person.vue  使用 pinia 前

<template>
    <div class="person">
       <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="changeSum1">加</button>
       <button @click="changeSum2">减</button>
    </div>

    
</template>
    
<script setup lang='ts' >
import { ref } from 'vue'

const sum = ref(1);
// 选择的数字
const n = ref(1);

const changeSum1 = ()=>{
    sum.value += n.value;
}
const changeSum2 = ()=>{
    sum.value -= n.value;
}

</script>
<style scoped>

</style>
// Person.vue 使用 pinia 后
<template>
    <div class="person">
       <h2>当前求和为:{
  
  {personStore.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="changeSum1">加</button>
       <button @click="changeSum2">减</button>
    </div>

    
</template>
    
<script setup lang='ts' >
import { ref } from 'vue'
import { usePersonStore } from '../store/person'

const personStore = usePersonStore();
// 以下两种方式都可以拿到state中的数据
// console.log('@',personStore.sum);
// console.log('@@@',personStore.$state.sum);

// 选择的数字
const n = ref(1);

// const changeSum1 = ()=>{
// }
// const changeSum2 = ()=>{
// }

</script>
<style scoped>

</style>
// Talk.vue 使用 pinia 前
<template>
    <div class="talk">
        <button @click="getTalk">获取一句话</button>
        <ul>
            <li v-for="talk in talkList" :key="talk.id">
                {
  
  {talk.title}}
            </li>
        </ul>
    </div>
</template>
    
<script setup lang='ts'>
import axios from 'axios';
import { nanoid } from 'nanoid';
import { reactive } from 'vue';

const talkList = reactive([
    { id: '001', title: '星期一' },
    { id: '002', title: '星期二' },
    { id: '003', title: '星期三' },

]);
const getTalk = async () => {
    // 简单写法:连续解构赋值 + 重命名
    // const {data:{content:title}} = await axios.get('https://api.uomg.com/api/rand/qinghua?format=json')
    // const obj = { id: nanoid(), title };
     // 发送请求
    const res = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')
    // 把请求回来的字符串,包装成一个对象
    // pnpm i nanoid 自动生成id
    const obj = { id: nanoid(), title: res.data.content }
    // 放入数组当中
    talkList.unshift(obj);
}
</script>
    
<style>
    
</style>
<template>
    <div class="talk">
        <button @click="getTalk">获取一句话</button>
        <ul>
            <li v-for="talk in talkStore.talkList" :key="talk.id">
                {
  
  {talk.title}}
            </li>
        </ul>
    </div>
</template>
    
<script setup lang='ts'>

import { useTalkStore } from '../store/talk';
// import { storeToRefs } from 'pinia';

const talkStore = useTalkStore();

// const { talkList } = storeToRefs(talkStore)

// 与 watch 类似
talkStore.$subscribe((mutate,state) => {
    console.log('talkStore 里面保存的数据发生了变化',mutate,state);
    
})
const getTalk=() => {
    talkStore.getATalk();
}

</script>
    
<style>
    
</style>

步骤五:修改数据(三种方式)

// person.ts

import { defineStore } from "pinia";

export const usePersonStore = defineStore('person', {
    // 真正存储数据的地方
    state() {
        return {
            sum: 20,
            name: '8520',
            age:20
        }
    },
    // actions 里面放的是一个个方法,用于响应组件中的“动作”
    actions:{
        increment(value){
            console.log('increment 被调用了', value);
            // 修改数据(this 是当前的 store)
            this.sum += value;
        }
    },
    getters: {
        // 可以对数据进行加工
        bigSum(state) {
            return state.sum * 10;
        },
        // 也可以被解构 调用
    }
})
<template>
    <div class="person">
       <h2>当前求和为:{
  
  {personStore.sum}}</h2>
       <h2>姓名:{
  
  {personStore.name}},年龄:{
  
  {personStore.age}}</h2>
       <select v-model.number="n">
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
       </select>
       <button @click="changeSum1">加</button>
       <button @click="changeSum2">减</button>
    </div>

    
</template>
    
<script setup lang='ts' >
import { ref } from 'vue'
// 引入 usePersonStore
import { usePersonStore } from '../store/person'
import { storeToRefs } from 'pinia';

// 使用 usePersonStore ,得到一个专门保存 person 相关的 store
const personStore = usePersonStore();

// storeToRefs 只会关注 store 中的数据,不会对方法进行 ref 包裹
const { sum, name, age, bigSum } = storeToRefs(personStore)

// 选择的数字
const n = ref(1);

// 加
const changeSum1 = () => {
    // 第一种修改方式
    // personStore.sum += n.value;

    // 第二种修改方式 批量修改
    // personStore.$patch({
    //     sum: 858,
    //     name: '5632',
    //     age:55
    // })

    // 第三种修改方式 利用 actions
    personStore.increment(n.value)

}
// 减
const changeSum2 = () => {
    personStore.sum -= n.value;
}
</script>


http://www.kler.cn/a/525354.html

相关文章:

  • 一文讲解Java中的BIO、NIO、AIO之间的区别
  • iperf 测 TCP 和 UDP 网络吞吐量
  • LNMP架构
  • js小游戏---2048(附源代码)
  • 【张雪峰高考志愿填报】合集
  • 开源 OA 办公系统
  • Qt调用ffmpeg库录屏并进行UDP组播推流
  • 实验四---基于MATLAB的根轨迹绘制与性能分析---自动控制原理实验课
  • DeepSeek R1中提到“知识蒸馏”到底是什么
  • 「 机器人 」扑翼飞行器控制策略浅谈
  • 国内AI芯片厂商的计算平台概述
  • NLP深度学习 DAY4:Word2Vec详解:两种模式(CBOW与Skip-gram)
  • AI助力精准农业:从数据到行动的智能革命
  • 帕金森患者:科学锻炼,提升生活质量
  • 面向对象设计(大三上)--往年试卷题+答案
  • 多线程【入门】
  • 【学术会议征稿-第二届生成式人工智能与信息安全学术会议(GAIIS 2025)】人工智能与信息安全的魅力
  • ESP32和STM32在处理中断方面的区别
  • Midjourney中的垫图、角色一致、风格一致到底区别在哪
  • Oracle Primavera P6 最新版 v24.12 更新 1/2
  • web前端10--变化
  • jQuery的系统性总结
  • 梯度提升用于高效的分类与回归
  • 55. 常用UDP端口号及其功能
  • lanqiaoOJ 2145:求阶乘 ← 二分法
  • 10.6.1 文本文件读、写和追加