【Vue3】Pinia修改数据

【Vue3】Pinia修改数据

背景

随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。本文内容并非完全原创,大多是参考其他文章资料整理所得,感谢每位技术人的开源精神。

简介

本文介绍 Vue3 中如何修改 Pinia 中数据。

Pinia 是 Vue 专属的状态管理库,允许跨组件或页面共享数据。

开发环境

分类 名称 版本
操作系统 Windows Windows 11
IDE Visual Studio Code 1.91.1

开发步骤及源码

1> 在 【Vue3】Pinia存储及读取数据 基础上新增一个功能组件 Reader.vue,展示修改 Pinia 数据的第一种方法。

复制代码
<template>
    <div class="reader">
        <button @click="borrow">借阅</button>
        <br>
        <h2>借阅图书</h2>
        <ol>
            <li v-for="book in books" :key="book.id">
                {{ book.title }} : {{ book.author }}
            </li>
        </ol>
    </div>
</template>

<script setup lang="ts">
import { useBookStore } from '@/store/book'
import { reactive } from 'vue';

const bookStore = useBookStore()
const books = reactive<any>([])

function borrow() {
    bookStore.bookCount -= 1
    const book = bookStore.books.shift()
    books.push(book)
}
</script>

<style scoped lang="scss">
.reader {
    background-color: darkcyan;
    padding: 20px;
    button {
        font-size: 20px;
        height: 40px;
        line-height: 40px;
        margin-right: 10px;
        width: 120px;
    }
    li {
        color: white;
        font-size: 20px;
        height: 35px;
        line-height: 35px;
    }
}
</style>

2> 修改 src/App.vue,引入 Reader.vue

复制代码
<template>
  <div class="content">
    <Book />
    <hr>
    <Reader />
  </div>
</template>

<script setup lang="ts">
import Book from './components/Book.vue'
import Reader from './components/Reader.vue'
</script>

<style scoped lang="scss">
.content {
  background-color: darkgray;
  padding: 20px;
}
</style>

3> 执行命令 npm run dev 启动应用,浏览器访问:http://localhost:5173/,点击 Reader.vue 功能组件中 借阅 按钮观察修改 Pinia 数据的效果。

4> 新增一个功能组件 Keeper.vue,展示修改 Pinia 数据的第二种方法。

复制代码
<template>
    <div class="keeper">
        <h2>图书管理员</h2>
        <button @click="update">更新</button>
    </div>
</template>

<script setup lang="ts">
import { useBookStore } from '@/store/book'

const bookStore = useBookStore()

function update() {
    bookStore.$patch(state => {
        state.bookCount = 6
        state.books = [
            { id: '001', title: '太白金星有点烦', author: '马伯庸' },
            { id: '002', title: '长安的荔枝', author: '马伯庸' },
            { id: '003', title: '大医', author: '马伯庸' },
            { id: '004', title: '风起陇西', author: '马伯庸' },
            { id: '005', title: '长安十二时辰', author: '马伯庸' },
            { id: '006', title: '食南之徒', author: '马伯庸' },
        ]
    })
}
</script>

<style scoped lang="scss">
.keeper {
    background-color: gold;
    padding: 20px;
    button {
        font-size: 20px;
        height: 40px;
        line-height: 40px;
        margin-right: 10px;
        width: 120px;
    }
}
</style>

5> 修改 src/App.vue,引入 Keeper.vue

复制代码
<template>
  <div class="content">
    <Book />
    <hr>
    <Reader />
    <hr>
    <Keeper />
  </div>
</template>

<script setup lang="ts">
import Book from './components/Book.vue'
import Reader from './components/Reader.vue'
import Keeper from './components/Keeper.vue'
</script>

<style scoped lang="scss">
.content {
  background-color: darkgray;
  padding: 20px;
}
</style>

6> 浏览器刷新访问 http://localhost:5173/,点击 Keeper.vue 功能组件中 更新 按钮观察修改 Pinia 数据的效果。

7> 第三种修改 Pinia 中数据的方法:第一步修改 src/store/book.ts,新增 actions 配置。

复制代码
import { defineStore } from "pinia"

export const useBookStore = defineStore('book', {
    // actions 中方法用于响应组件中动作
    actions: {
        giveBack(book: any) {
            this.bookCount += 1
            this.books.push(book)
        }
    },
    // state 必须写成函数形式,返回的对象即是集中存储的数据
    state() {
        return {
            bookCount: 5,
            books: [
                { id: '001', title: '坐天下', author: '张宏杰' },
                { id: '002', title: '明朝那些事儿', author: '当年明月' },
                { id: '003', title: '太白金星有点烦', author: '马伯庸' },
                { id: '004', title: '活着', author: '余华' },
                { id: '005', title: '饥饿的盛世', author: '张宏杰' },
            ]
        }
    }
})

8> 第三种修改 Pinia 中数据的方法:第二步修改 Reader.vue,新增一个调用 actions 中方法的功能。

复制代码
<template>
    <div class="reader">
        <button @click="borrow">借阅</button>
        <button @click="giveBack">归还</button>
        <br>
        <h2>借阅图书</h2>
        <ol>
            <li v-for="book in books" :key="book.id">
                {{ book.title }} : {{ book.author }}
            </li>
        </ol>
    </div>
</template>

<script setup lang="ts">
import { useBookStore } from '@/store/book'
import { reactive } from 'vue';

const bookStore = useBookStore()
const books = reactive<any>([])

function borrow() {
    bookStore.bookCount -= 1
    const book = bookStore.books.shift()
    books.push(book)
}

function giveBack() {
    bookStore.giveBack(books.shift())
}
</script>

<style scoped lang="scss">
.reader {
    background-color: darkcyan;
    padding: 20px;
    button {
        font-size: 20px;
        height: 40px;
        line-height: 40px;
        margin-right: 10px;
        width: 120px;
    }
    li {
        color: white;
        font-size: 20px;
        height: 35px;
        line-height: 35px;
    }
}
</style>

9> 浏览器刷新访问 http://localhost:5173/,点击 Reader.vue 功能组件中 借阅归还 按钮观察修改 Pinia 数据的效果。

总结

三种修改 Pinia 中数据的方法:

  1. 获取 Pinia 中存储的数据并直接修改;
  2. 使用 $patch 一次性批量修改,此方法适用于存在大量数据需要同时修改的场景;
  3. defineStore 中定义 actions 实现数据修改功能,在需要修改数据的组件中调用 actions 中对应的函数,这样做有利于统一封装数据修改的公共逻辑,供多处调用。注意:actions 中方法访问 Pinia 中数据需要使用 this 关键字。
相关推荐
钛态35 分钟前
AI 辅助:前端框架反模式:过度封装、状态滥用与副作用失控
前端·vue·react·web
by__csdn38 分钟前
Vue vs React vs Angular:前端框架终极对决
前端·vue.js·react.js·前端框架·vue·react·angular
钛态40 分钟前
前端框架选型决策框架:React、Vue、Svelte、Solid 的 2026 年横评
前端·vue·react·web
反正我还没长大1 小时前
Vue3响应式原理深度解析:揭秘现代前端框架的核心引擎
vue.js·前端框架·vue·proxy模式
布兰妮甜13 小时前
Vue 状态管理选型:Pinia 完整实战,对比 Vuex,模块化持久化
前端·javascript·vue.js·pinia·vuex
FeelTouch Labs14 小时前
Node.js 中的 spawn 和 exec:子进程执行的不同方式对比
node.js·编辑器·vue·vim
shawxlee18 小时前
vue3+elementplus+sass/scss安装配置教程:使用svg图标、引入外部字体、定义变量模块、修改组件样式、一键切换主题等
vue·sass·svg·字体·element·scss·主题样式
弹简特21 小时前
【Vue3速成】07-vue3异步请求之Axios-01
vue·axios
弹简特2 天前
【Vue3速成】06-vue3官方库路由机制之Pinia状态管理
vue·pinia
java1234_小锋2 天前
Vue3专题 - 响应式基础
vue·vue3·响应式