【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 关键字。
相关推荐
Lysun00135 分钟前
[less] Operation on an invalid type
前端·vue·less·sass·scss
程序视点8 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
刚刚好ā9 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
ZwaterZ12 小时前
vue el-table表格点击某行触发事件&&操作栏点击和row-click冲突问题
前端·vue.js·elementui·c#·vue
西凉河的葛三叔12 小时前
vue3+elementui-plus el-dialog全局配置点击空白处不关闭弹窗
前端·vue3·elementui-plus
xiaohuatu12 小时前
CSRF保护--laravel进阶篇
vue3·laravel·csrf
ZwaterZ14 小时前
el-table-column自动生成序号&&在序号前插入图标
前端·javascript·c#·vue
木子七17 小时前
vue2-vuex
前端·vue
小小黑00718 小时前
uniapp+vue3+ts H5端使用Quill富文本插件以及解决上传图片反显的问题
uni-app·vue
Ztiddler21 小时前
【npm设置代理-解决npm网络连接error network失败问题】
前端·后端·npm·node.js·vue