组件中映射的vuex吸气剂未更新

时间:2020-10-03 10:08:40

标签: javascript vue.js vuex

我在vuex商店中有一个吸气剂,它从商店状态返回一个数组列表。我正在通过从组件调用的操作中的突变来更新存储状态,即使商店getter被更新了,组件中的映射getter也没有使用最新数据进行更新。

软件包版本

“ vue”:“ 2.6.11”, “ vuex”:“ ^ 3.0.1”

index.js

import Vue from 'Vue'
import Vuex from 'vuex'
import '@styles/contact-list.scss'
import List from '@components/contactList'
import store from '@store'
Vue.use(EventBusPlugin)
Vue.use(Vuex)
let url = '/api/contacts'
let vueInstance = new Vue({
  el: '#contactContainer',
  components: { List },
  template: '<List/>',
  render (h) {
    return h(List, { props: { url: this.url, filter: this.filter, type: 'internal' } })
  },
  data () {
    return {
      url: url,
      filter: true
    }
  },
  store
}) 

组件

<template>
  <div>
    <div class="d-flex flex-row align-content-start flex-wrap">
      <contact-card
        v-for="(data) in displayList"
        :data="data"
        :key="data.unique_id"
      ></contact-card>
    </div>
  </div>
</template>

<script> 
 
import { mapActions, mapGetters, mapMutations } from 'vuex'
export default {
  name: 'ContactList',
  components: { 
    ContactCard 
  },
  props: {
    url: {
      required: true,
      type: String
    },
    filter: {
      type: Boolean,
      default: false
    },
    pageSize: {
      type: Number,
      default: 200
    },
    type: {
      type: String,
      default: 'external'
    }
  },
  computed: {
    ...mapGetters('contacts', ['displayList']),
    dataUrl () {
      return `${this.url}?type=${this.type}`
    }
  },
  mounted () {
    this.setType(this.type)
    this.loadData() 
  },
  data () {
    return {
      searchKey: '',
      sequence: 0
    }
  }, 
  methods: {
    ...mapActions('contacts', ['loadContacts', 'updateStatus']),
    ...mapMutations('contacts', ['setType']), 
    loadData () {
      this.loadContacts({ url: this.url })
    }
  }
}
</script>

商店

import Vue from 'vue'
import Vuex from 'vuex'
import contacts from './modules/contacts'

Vue.use(Vuex)

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

export default store

./模块/联系人


export default {
  namespaced: true,
  state : {
    type: 'external',
    externalList: [],
    internalList: []
  },
  mutations:{
    setContactList (state, list) {
      state.type === 'external' ? state.externalList = list : state.internalList = list
    },
    setType (state, type) {
      state.type = type
    }
  },
  getters:{
    displayList (state) {
      if (state.type === 'external') {
        return state.externalList
      } else {
        return state.internalList
      }
    }
  },
  actions:{
    loadContacts ({ commit, state }, payload) {
      const { url } = payload
      $.ajax({
        type: 'POST',
        url: url,
        data: {},
        contentType: 'application/json',
        success: (data) => {
          commit('setContactList', data)
        },
        error: (jqXHR, textStatus, errorThrown) => {
        }
      })
    }
  }
}

尽管在上面的代码中我可以在开发人员工具中看到vuex store getter已更新,但未反映在组件中的映射getter中。 谁能帮忙这里有什么问题谢谢?

2 个答案:

答案 0 :(得分:0)

必须要进行其他操作,因为它可以正常工作。

以下几乎是相同的代码(进行更改只是为了使它可以从CDN运行,而无需API)

我唯一奇怪的是,您的根实例上同时具有templaterender函数...但是它可以作为如果Vue选项中存在render函数,则该模板将被忽略。 Docs

Vue.use(Vuex)

const contacts = {
  namespaced: true,
  state : {
    type: 'external',
    externalList: [1, 2, 3],
    internalList: [4, 5, 6]
  },
  mutations:{
    setContactList (state, list) {
      state.type === 'external' ? state.externalList = list : state.internalList = list
    },
    setType (state, type) {
      state.type = type
    }
  },
  getters:{
    displayList (state) {
      if (state.type === 'external') {
        return state.externalList
      } else {
        return state.internalList
      }
    }
  },
  actions:{
    loadContacts ({ commit, state }, payload) {
      // to simulate Ajax loading...
      setTimeout(() => (commit('setContactList', [7, 8, 9])), 1500)
    }
  }
}

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

const list = Vue.component('List', {
  props: {
    url: {
      required: true,
      type: String
    },
    filter: {
      type: Boolean,
      default: false
    },
    pageSize: {
      type: Number,
      default: 200
    },
    type: {
      type: String,
      default: 'external'
    }
  },
  template: `
    <div>
      <div v-for="(data) in displayList"> {{ data }}</div>
    </div>
  `,
  computed: {
    ...Vuex.mapGetters('contacts', ['displayList']),
  },
  mounted () {
    this.setType(this.type)
    this.loadData() 
  },
  methods: {
    ...Vuex.mapActions('contacts', ['loadContacts', 'updateStatus']),
    ...Vuex.mapMutations('contacts', ['setType']), 
    loadData () {
      this.loadContacts()
    }
  }
})

const app = new Vue({
  store,
  components: { list },
  template: `<List :url="url" />`,
  render (h) {
    return h('List', { props: { url: this.url, filter: this.filter, type: 'internal' } })
  },
  data () {
    return {
      url: "some url",
      filter: true
    }
  },
})
app.$mount("#app")
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.5.1/vuex.min.js"></script>

<div id="app"> </div>

答案 1 :(得分:-1)

您的状态应包含您要同步的密钥(由您的手添加)。 基本上,您应该编写要同步的所有键的实际结构。

例如键(由您添加)=“反应性”有效:

a = [1,2,3,4,5]
b = [1,2,3,4,5]
matplotlib.pyplot.scatter(a,b)
matplotlib.pyplot.show()

例如“反应性”不起作用:

state:{
    externalList: null, // <--- added by you
    internalList: null  // <--- added by you
}

突变

state: {} // <--- externalList/internalList NOT added by you
相关问题