【问题标题】:Quasar Framework with VueXQuasar 框架与 VueX
【发布时间】:2021-05-26 18:30:35
【问题描述】:

我遇到了一个似乎无法解决的问题。首先是一些代码:

<template>
  <div>
    <q-input name="email" v-model="user.email" />
    <q-input name="userName" v-model="user.userName" />
  </div>
</template>

<script>
export default {
  name: 'UserDetail',
  props: {
    id: String
  },
  computed: {
    user: {
      get () {
        return this.$store.state.users.user
      },
      set (value) {
        this.$store.dispatch('users/updateUser', this.id, value)
      }
    }
  }
}
</script>

这里是商店操作:

export function updateUser ({ commit }, id, user) {
  if (id !== user.id) {
    console.log('Id und User.Id stimmen nicht überein')
  } else {
    api.put(`/User/${id}`, user).then(response => {
      commit('upsertUser', response.data)
    }).catch(error => {
      console.log(error)
    })
  }
}

变异:

export const upsertUser = (state, user) => {
  const idx = state.userList.findIndex(x => x.id === user.id)
  if (idx !== -1) {
    state.userList[idx] = user
  } else {
    state.userList.push(user)
  }
  if (state.user?.id === user.id) {
    state.user = user
  }
}

现在据我所知,这符合 vuex 推荐的方式来做这样的事情 (https://vuex.vuejs.org/guide/forms.html#two-way-computed-property)

但我总是收到错误:do not mutate vuex store state outside mutation handlers

我不知道该怎么做。有人能指出我正确的方向吗?

【问题讨论】:

  • 澄清一下:在 set 函数中,我调用了一个存储操作,它将更改保存到后端,然后将它们提交到状态。我也试过$store.commit('user/upsertUser', value),但这也会引发同样的错误。

标签: vuex quasar-framework


【解决方案1】:

Dispatching Actions:只允许一个输入参数,此时你可以读取状态但不能修改它

Mutations:它只允许一个输入参数,从这里你可以读写状态,但是如果你想让监听对象变化的变量“监听变化”,你必须使用 使用对象时的 Object.assign 或 Vue.set

我没看懂你的数据,所以给你一个类似的解决方案,希望对你有帮助

let users = {
    namespaced: true,
    state: {
        userList: {
            'ID43769906': {
            id: 'ID43769906',
            email: 'manueltemple@gmail.com',
            username: 'mtemple'
          }
        }
    },
    mutations: {
        upsertUser(state, payload) {
        
            if (state.userList.hasOwnProperty(payload.id)) {
                Object.assign(state.userList[payload.id], payload)
          } else {
                Vue.set(state.userList, payload.id, payload)
          }
        }
    },
    actions: {
        updateUser({ commit }, payload) {
                        console.log('api put')
            commit('upsertUser', payload)
            /*
            api.put(`/User/${id}`, user).then(response => {
              commit('upsertUser', response.data)
            }).catch(error => {
              console.log(error)
            })
            */
        }
    },
    getters: {
                getUser: (state) => (id) => {
                let result = null
                let data = state.userList || {}
                    Object.keys(data).forEach((key) => {
                        if (key === id) {
                    result = data[key]
                  return false
                }
                
            })
            return result
        }
    }
}

const store = new Vuex.Store({
    modules: {
        users
    },
})

//import { mapGetters } from 'vuex'

new Vue({
    store,
  el: '#q-app',
  data: function () {
    return {
      id: 'ID43769906'
    }
  },
  mounted () {
    window._this = this
  },
  computed: {
    ...Vuex.mapGetters('users', ['getUser']),
    user: {
      get () {
            return this.getUser(this.id)
          // return _this.$store.getters['users/getUser'](this.id)
      },
      set (value) {
            this.$store.dispatch('users/updateUser', value, { root: true })
      }
    }
  }
})
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@quasar/extras/material-icons/material-icons.css">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/quasar/dist/quasar.min.css">
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar/dist/quasar.umd.min.js"></script>

<div id="q-app">
  <div>
    <q-input name="email" v-model="user.email" />
    <q-input name="userName" v-model="user.username" />
  </div>
</div>

https://jsfiddle.net/idkc/Lu21eqv9/46/

【讨论】:

    猜你喜欢
    • 2019-05-16
    • 2020-02-17
    • 2018-10-22
    • 2021-05-21
    • 2019-02-11
    • 1970-01-01
    • 2020-10-03
    • 2020-01-06
    • 2019-12-06
    相关资源
    最近更新 更多