Vue3/Vuex - 我在哪里 "mutating vuex store state outside mutation handlers"?

Vue3/Vuex - Where am I "mutating vuex store state outside mutation handlers"?

当调用 Vuex Action 时,Firebase 成功更新,然后在 state.profile 上调用 Vuex Mutation,Vue 触发在 watch().

save 出现以下错误

[Vue warn]: Unhandled error during execution of watcher callback

Error: [vuex] do not mutate vuex store state outside mutation handlers.

我已经通过 rfdc.

克隆并合并了 store.state.profileformData

表单值在它自己的 reactive() 数据对象 formData 中更新,而不是立即提交存储以便稍后提供 save()cancel() 选项。

模板

<template>
    <element-textarea
        id="about"
        title="About"
        :rows="10"
        v-model="about"
    ></element-textarea>
    <element-checkbox
        v-for="(specialty, i) in jSpecialties"
        :key="i"
        :id="specialty.toLowerCase()"
        :title="specialty"
        v-model="specialties[specialty]"
    >
        {{ specialty }}
    </element-checkbox>
</template>

脚本

...
const clone = require('rfdc/default')

export default defineComponent({
    ...
    setup(){
        ...
        let specialties: { [key: string]: boolean } = {}
        jSpecialties.map(name => (specialties[name] = false))
        const formData = reactive({
            about: '',
            specialties
        })

        watch(
            () => store.state.profile,
            () => {
                try {
                    Object.assign(formData, clone(store.state.profile))
                } catch (err) {
                    console.log('Error Appears Here', err)
                }
            }
        )

        const save = () =>
            store.dispatch('updateProfile', formData)
                .catch(err => console.log(err))

        return { ...toRefs(formData), save }
    }
})

vuex

export default createStore({
    strict: true,
    state: {
        profile: {}
    },
    mutations: {
        setProfile: (state, payload) => state.profile = payload,
    },
    actions: {
        updateProfile: ({state, commit}, data) => {
            const update = () =>
                db
                    .collection(...)
                    .doc(...)
                    .set(data, {merge: true})
                    .then(_ => commit('setProfile', data))
                    .catch(err => console.log(err))
            return update()
        }
    }
})

从 vuex 中删除 strict: true 时,我收到此错误:

Maximum recursive updates exceeded. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.


watchEffect() 替换 watch() 消除 超出最大递归更新 错误。

watchEffect(() => {
    try {
        Object.assign(formData, clone(store.state.profile))
    } catch (error) {
        console.log(error)
    }
})

但是,当使用 strict: true 更新 Vuex 时,我仍然收到以下信息:

Error: [vuex] do not mutate vuex store state outside mutation handlers.

我发现了这个问题。我忽略了我将引用对象复制回状态。

我需要在调度之前克隆 formData,因为同样的 data 对象也通过操作提交存储。

const save = () =>
    store.dispatch('updateProfile', clone(formData))
        .catch(err => console.log(err))