【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 关键字。
相关推荐
唯之为之1 小时前
# Vue3.5常用特性整理
vue3·ssr
于指尖飞舞7 小时前
在vue3中使用datav完整引入时卡在加载页面的解决方法
vue3·报错·datav
寰宇软件14 小时前
PHP CRM售后系统小程序
微信小程序·小程序·vue·php·uniapp
猫猫村晨总1 天前
基于 Vue3 + Canvas + Web Worker 实现高性能图像黑白转换工具的设计与实现
前端·vue3·canvas
寰宇软件1 天前
PHP校园助手系统小程序
小程序·vue·php·uniapp
是梦终空1 天前
JAVA毕业设计210—基于Java+Springboot+vue3的中国历史文化街区管理系统(源代码+数据库)
java·spring boot·vue·毕业设计·课程设计·历史文化街区管理·景区管理
上官熊猫1 天前
nuxt3项目打包部署到服务器后配置端口号和开启https
前端·vue3·nuxt3
璇璇吴2 天前
vue3 el-form表格滚动
javascript·vue3·elementplus
寰宇软件2 天前
PHP同城配送小程序
微信小程序·vue·php·uniapp
℡52Hz★2 天前
如何正确定位前后端bug?
前端·vue.js·vue·bug