【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 关键字。
相关推荐
Yaml43 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
清灵xmf7 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
CherishTaoTao1 天前
Vue3 keep-alive核心源码的解析
前端·vue3
琴~~1 天前
前端根据后端返回的文本流逐个展示文本内容
前端·javascript·vue
程序员徐师兄2 天前
基于 JavaWeb 的宠物商城系统(附源码,文档)
java·vue·springboot·宠物·宠物商城
shareloke2 天前
让Erupt框架支持.vue文件做自定义页面模版
vue
你白勺男孩TT3 天前
Vue项目中点击按钮后浏览器屏幕变黑,再次点击恢复的解决方法
vue.js·vue·springboot
虞泽3 天前
鸢尾博客项目开源
java·spring boot·vue·vue3·博客
工业互联网专业3 天前
Python毕业设计选题:基于django+vue的4S店客户管理系统
python·django·vue·毕业设计·源码·课程设计