vue3.x教程-Pinia状态管理-修改数据:直接修改、批量修改、actions修改

介绍

修改数据分以下三种:

方式 适用场景 推荐度
直接修改 少量简单修改、临时页面 ⭐⭐
$patch 同时更新多个字段 ⭐⭐⭐
actions 业务逻辑、接口、复用、大型项目 ⭐⭐⭐⭐⭐

1.直接修改

在 vue3.x教程-Pinia状态管理-读取数据 例子的基础上,在 Rename.vue 直接修改

应用场景

修改一个、少量的值

添加代码

在 rename() 函数中增加下面代码:

function rename(){
    // 将用户名修改为 lili
    userStore.nickname = 'lili'
}

执行结果

点击【修改】按钮后,两个组件的昵称都改为 lili

完整代码

<template>
    <div class="c1">
        <h1>Rename组件</h1>
        昵称:<input type="text" v-model="userStore.nickname">
        <button @click="rename">修改</button>
    </div>
</template>

<script setup lang="ts">
    // 导入store
    import {useUserStore} from '@/stores/User.ts'
    // 创建store对象
    const userStore = useUserStore()
    // 使用store中的state状态中的数据
    console.log("Rename.vue----nickname:",userStore.nickname)
    function rename(){
        userStore.nickname = 'lili'
    }
</script>

<style>
    .c1{
        border: 1px solid red;
    }
</style>

$patch批量修改

$patch 批量修改(一次性改多个值)

应用场景

如下图,需要修改多个值:

修改User.vue

增加角色、部门

<template>
    <div class="c1">
        <h1>User组件</h1>
        昵称:{{userStore.nickname}}<br>
        角色:{{userStore.role}}<br>
        部门:{{userStore.dept}}<br>
    </div>
</template>

<script setup lang="ts">
    // 导入store
    import {useUserStore} from '@/stores/User.ts'
    // 创建store对象
    const userStore = useUserStore()
    // 使用store中的state状态中的数据
    console.log('nickname:',userStore.nickname)
</script>

<style scoped>
.c1{
    border: 1px solid green;
}
</style>

修改 Rename.vue(关键)

增加角色、部门

直接修改

修改 rename() 函数,增加下面代码:

function rename(){
    // 一个一个修改,需要执行n次修改,效率低
    userStore.nickname = 'lili'
    userStore.role = '普通员工'
    userStore.dept = '开发部'
}
批量修改(关键)

修改 rename() 函数,增加下面代码:

function rename(){
    // 批量修改,执行一次修改
    userStore.$patch({
        nickname:'lili',
        role:'普通员工',
        dept:'开发部',
    })
}
完整代码
<template>
    <div class="c1">
        <h1>Rename组件</h1>
        昵称:<input type="text" v-model="userStore.nickname"><br>
        角色:<input type="text" v-model="userStore.role"><br>
        部门:<input type="text" v-model="userStore.dept"><br>
        <button @click="rename">修改</button>
    </div>
</template>

<script setup lang="ts">
    // 导入store
    import {useUserStore} from '@/stores/User.ts'
    // 创建store对象
    const userStore = useUserStore()
    // 使用store中的state状态中的数据
    console.log("Rename.vue----nickname:",userStore.nickname)
    function rename(){
        // 一个一个修改,需要执行n次修改,效率低
        userStore.nickname = 'lili'
        userStore.role = '普通员工'
        userStore.dept = '开发部'
        // 批量修改,执行一次修改
        // userStore.$patch({
        //     nickname:'lili',
        //     role:'普通员工',
        //     dept:'开发部',
        // })
    }
</script>

<style>
    .c1{
        border: 1px solid red;
    }
</style>

修改 User.ts

增加角色、部门

选项式写法
import {defineStore} from 'pinia'
import {ref} from 'vue'

/*
 变量命名
 一般情况:use+文件名+Store
 复杂情况:use+业务名+Store
 */
/*
 定义store,vue2选项式写法
 第一个参数是唯一标识
 第二个参数是对象
 */
export const useUserStore = defineStore('user',{
    // 定义State状态:存储初始数据,必须是函数且返回对象
    state(){
        return {
            // 选项式,不需要定义成ref,会自动处理
            nickname: '李雷',
            role:'管理员',
            dept:'人力资源部'
        }
    }
})
组合式写法
/*
 定义store,vue3组合式写法
 第一个参数是唯一标识
 第二个参数是对象
 */
export const useUserStore = defineStore('user',()=>{
    return {
        // 组合式,推荐定义成ref。不定义成ref,会自动处理,但可能出问题
        nickname: ref('李雷'),
        role: ref('管理员'),
        dept: ref('人力资源部'),
    }
})

3.actions修改

真正的项目中,不可能像上面例子做简单修改,而是修改后,还要 发 ajax 请求将修改发送到后端服务器,数据要保存起来,可能还要做校验等更多的操作,此时应该使用 actions 修改

修改 Rename.vue

<template>
    <div class="c1">
        <h1>Rename组件</h1>
        昵称:<input type="text" v-model="form.nickname"><br>
        角色:<input type="text" v-model="form.role"><br>
        部门:<input type="text" v-model="form.dept"><br>
        <button @click="rename">修改</button>
    </div>
</template>

<script setup lang="ts">
    import {reactive} from 'vue'
    // 导入store
    import {useUserStore} from '@/stores/User.ts'
    // 创建store对象
    const userStore = useUserStore()
    // 将 store 中的值赋给响应式变量,作用:输入框中修改值,就不会联动修改User组件的数据
    const form = reactive({
      nickname: userStore.nickname,
      role: userStore.role,
      dept: userStore.dept
    })

    function rename(){
        // 调用actions中的方法,传入表单数据
        userStore.modify(form)
    }
</script>

<style>
    .c1{
        border: 1px solid red;
    }
</style>

修改 User.ts

选项式写法
import {defineStore} from 'pinia'
import {ref} from 'vue'

/*
 变量命名
 一般情况:use+文件名+Store
 复杂情况:use+业务名+Store
 */
/*
 定义store,vue2选项式写法
 第一个参数是唯一标识
 第二个参数是对象
 */
export const useUserStore = defineStore('user',{
    // 定义State状态:存储初始数据,必须是函数且返回对象
    state(){
        return {
            // 选项式,不需要定义成ref,会自动处理
            nickname: '李雷',
            role:'管理员',
            dept:'人力资源部'
        }
    },
    // 薪增actions选项
    actions:{
        // 定义修改方法
        modify(value){
            console.log("modify:",value)
            // 模拟发送请求
            console.log("模拟发送ajax请求...")
            // 批量修改数据
            this.$patch(value)
        }
    }
})
组合式写法
import {defineStore} from 'pinia'
import {ref} from 'vue'

/*
 定义store,vue3组合式写法
 第一个参数是唯一标识
 第二个参数是对象
 */
export const useUserStore = defineStore(
    'user',
    ()=>{
        const nickname = ref('李雷')
        const role = ref('管理员')
        const dept = ref('人力资源部')
        // 定义修改方法
        const modify = (value) => {
            console.log("modify:",value)
            // 模拟发送请求
            console.log("模拟发送ajax请求...")
            // 组合式api没有this,不能用批量修改数据
            // this.$patch(value)
            nickname.value = value.nickname
            role.value = value.role
            dept.value = value.dept
        }
        return {
            // 组合式,推荐定义成ref。不定义成ref,会自动处理,但可能出问题
            nickname,
            role,
            dept,
            modify,
        }
    }
)

注意

这里可能会有疑问:完全不用 actions,因为 actions 方法中的代码,如:发送ajax请求,完全可以写在 Rename.vue 组件中

解释:确实可行,但不能复用代码,比如,多个组件都要修改,如果不将发ajax请求的代码定义在 actions 中,就需要在每个组件中定义,这是不合理的


原文出处:/show_1GW3iYtHcu5Z.html