对 vuex 数据的更改未反映在 Quasar QTable 中

Changes to vuex data not reflected in Quasar QTable

我正在使用带有 Vuex 的 Quasar 将数据集加载到 QTable 中。它工作得很好,但我正在尝试使用 QPopupEdit 来更改项目的状态。数据是从一个Laravel API中拉取的,原始数据集是一个Laravel资源,所以我有项目,每个项目都有一个状态对象(item.status_id和状态:id , 状态:姓名等)

我已经在 q-table 之外公开了第一条记录的状态值,当我将更新推送到 API 时,我 return 更改了项目资源, 将它插入到 vuex mutation 中的 Vuex 数据中,它不会在 table.

中更新
<div v-if="items && items[0] && items[0].order">
  {{items[0].status.id}} | {{items[0].status.name}}
</div>

<q-table
  title="Projects"
  :data="items"
  :columns="columns"
  color="primary"
  row-key="id"
  :loading="loading"
  no-data-label="no projects with search prameters"
  :visible-columns="visibleColumns">
  <template v-slot:top="props">
    <q-btn
      flat round dense
      :icon="props.inFullscreen ? 'fullscreen_exit' : 'fullscreen'"
      @click="props.toggleFullscreen"
      class="q-ml-md"
    />
    <q-space />
    <q-select
      v-model="visibleColumns"
      multiple
      borderless
      dense
      options-dense
      emit-value
      map-options
      :options="columns"
      option-value="name"
      style="min-width: 150px"
    />
  </template>
  <template v-slot:body="props">
    <q-tr :props="props">
      <q-td key="user" :props="props">
        {{ props.row.order.user.firstname }} {{ props.row.order.user.lastname }}
      </q-td>
      <q-td key="name" :props="props">
        {{ props.row.service.name }}
      </q-td>
      <q-td key="status" :props="props">
        <q-badge v-if="props.row.status" :color="props.row.status.color" outline>
          {{ props.row.status.name }}
        </q-badge>
        <q-popup-edit v-model="props.row.status.id" :key="item">
          <q-select fill-input color="primary" v-model="props.row.status.id" :key="props.row" :options="statuses" label="Status" emit-value map-options option-label="name" @input="(val) => saveStatus(val, props.row, index)" />
        </q-popup-edit>
        {{props.row.status.id}} | {{props.row.status_id}}
      </q-td>
      <q-td key="updated_at" :props="props">
        {{ formatDate(props.row.updated_at, 'MMM D, YYYY HH:mm A')}}
      </q-td>
      <q-td key="notes" :props="props">
        <div class="table-description cursor-pointer">
          <q-icon v-if="!props.row.notes" name="fal fa-comment-alt" class="float-right" />
          {{ props.row.notes }}
          <q-popup-edit
            buttons
            v-model="props.row.notes"
          >
            <q-input
              type="textarea"
              v-model="props.row.notes"
              autofocus
              counter
              @keyup.enter.stop
            />
          </q-popup-edit>
        </div>
      </q-td>
      <q-td key="id" :props="props">
        <q-btn icon="fal fa-arrow-right" :to="'/item/' + props.row.id" class="cursor-pointer" />
      </q-td>
    </q-tr>
  </template>
</q-table>

脚本节选

import { mapState } from 'vuex'
import { date } from 'quasar'
export default {
data () {
  return {
    inFullscreen: false,
    visibleColumns: [ 'user', 'name', 'status', 'updated_at', 'notes', 'id' ],
    columns: [
      { name: 'user', align: 'left', label: 'Client', field: row => row.order.user.firstname, format: (val, row) => `${val}`, sortable: false },
      { name: 'name', required: true, label: 'Name', align: 'left', field: row => row.service.name, format: val => `${val}`, sortable: true },
      { name: 'status', align: 'left', label: 'Status', field: row => row.status.name, format: val => `${val}`, sortable: true },
      { name: 'updated_at', align: 'left', label: 'Last Updated', field: row => row.status.updated_at, format: val => `${val}`, sortable: true },
      { name: 'notes', align: 'left', label: 'Notes', field: 'notes', sortable: false },
      { name: 'id', align: 'right', label: 'Actions', field: 'id', sortable: false }
    ]
  }
},
mounted () {
  this.fetch()
  if (!this.statuses || this.statuses.length < 1) {
    this.$store.dispatch('items/fetchStatuses')
  }
},
computed: {
  ...mapState({
    loading: state => state.auth.loading,
    authuser: state => state.auth.user,
    pagination: state => state.items.pagination,
    items: state => state.items.items,
    statuses: state => state.items.statuses
  })
},
methods: {
  saveStatus (value, item, index) {
    console.log(value + ' | ' + index)
    console.log(item)
    let payload = { 'status_id': value, 'item_id': item.id, 'index': index }
    this.$store.dispatch('items/saveStatus', payload)
  },
  formatDate (dt, mask) {
    return date.formatDate(date.extractDate(dt, 'YYYY-MM-DDTHH:mm:ss.SSSSSSZ'), mask)
  },
  fetch () {
    this.$store.dispatch('auth/statusLoading', true)
    this.$store.dispatch('items/fetchItems', this.id).then((res) => {
      this.$store.dispatch('auth/statusLoading', false)
    }).catch(error => {
      if (error) {
        console.log(error)
      }
    })
  },
}
}

我的动作和来自 vuex 项目模块的变异

export function saveStatus ({ state, commit, getters }, payload) {
  return new Promise((resolve, reject) => {
    axiosInstance.post('/api/status/update/Item/' + payload.item_id, payload)
      .then(response => {
        // alert(JSON.stringify(response, null, 4))
        let pl = { 'item': response.data.data }
        commit('setIndexItem', pl)
        resolve(null)
        // console.log(response)
        // commit('setItems', response.data.data)
      })
      .catch(err => {
        reject(err)
      })
  })
}

export function setIndexItem (state, payload) {
  var index = state.items.findIndex(i => i.id === payload.item.id)
  state.items[index] = payload.item
}

我知道 Laravel API 部分正在工作 - 数据库中的值正在更新,更新状态的项目正在 returned 到 vuex 商店,这就是正在 vuex 存储库中更新,如公开的第一个调试元素所示,但在 QTable 中,它不会更新。

也许 Array Change Detection leads the view not updated. You can use the Vue.set 更新视图

import Vue from 'vue'

// ...

export function setIndexItem (state, payload) {
  var index = state.items.findIndex(i => i.id === payload.item.id)
  Vue.set(state.items, index, payload.item)
}

来自:

您不应该使用组件的观察器来监听状态变化。我建议您使用 getter 函数,然后将它们映射到您的组件中。

import { mapGetters } from 'vuex'

export default {
  computed: {
    ...mapGetters({
      myState: 'getMyState'
    })
  }
}

在您的商店中:

const getters = {
  getMyState: state => state.my_state
}

您应该能够通过在您的组件中使用 this.myState 来收听对您的商店所做的任何更改。

https://vuex.vuejs.org/en/getters.html#the-mapgetters-helper