【问题标题】:Vuex: Computed Property Returns Undefined - asyc AxiosVuex:计算属性返回未定义 - asyc Axios
【发布时间】:2018-05-12 06:45:35
【问题描述】:

我对我的数据库有异步 axios 调用,我在站点加载时通过一个操作进行调度。 (我尝试在我的 Vue 路由器上调度 beforeEnter(),在我的 Form.Vue 上调度 beforeCreated() 和 Created())

我有一个计算属性使用 getter 返回信息。

我遇到的问题是数据在页面完成加载并返回 Undefined 后到达那里 - 页面上没有呈现任何内容。

如果我检查我的 Vue DevTools,所有数据都在状态中的正确位置。

如何让数据在页面之前完成加载?

//动作

async loadInputs({ state, getters, commit, dispatch }) {    
 if (!state.loading) {
  commit('setLoading', true)

  const inputLists = axios.get('/companyInputLists')
  const inputs = axios.get('/companyInputs')

  commit('setLoading', false)
  commit('loadInputs' , [await inputLists, await inputs])

 }
},

set ({commit}, value) {
  commit('updateValue', value)
},

//突变体

setLoading(state, value) {
  state.loading = value
},

 loadInputs(state, data){
  state.layout = {}
  state.data = {}
  data[0].data.map(list => {
    list['inputs'] = []
    state.layout[list.order] = list

    data[1].data.map(input => {
        if(input.list_id == list.id){
            state.layout[list.order].inputs.push(input)
            state.data[input.label] = ''
        }
     })
   })
 },

updateValue(state, value) {
  state.data[value.type] = value.value
},

//吸气剂

get(state) {
    console.log(state)
    return state
 },
}

//FORM.VUE

  <span>

    //LIST TEST and v-if test
    <div v-if="lists">
      {{lists}}
    </div>
    test
    {{ lists }}



<v-layout row wrap justify-center>

  <draggable class="dragArea layout row wrap justify-center" :options="{group:'lists'}">
    <v-flex v-for="list in lists" v-bind:key="list.index" :class="[list.label, flexBoxSize(list.size)]">

      <v-subheader v-text="list.label"></v-subheader>

      <draggable class="dragArea layout row wrap" :options="{group:'inputs'}">
        <v-flex v-for="item in list.inputs" v-bind:key="item.index" :class="[item.label, flexBoxSize(item.size)]">

          <textfield v-if="item.type_id == 1" formType="clientForm" :label="item.label" :required="item.required"></textfield>
          <email v-if="item.type_id == 2" formType="clientForm" :label="item.label"  :required="item.required"></email>
          <phone v-if="item.type_id == 3" formType="clientForm" :label="item.label"  :required="item.required"></phone>
          <calendar v-if="item.type_id == 4" formType="clientForm" :label="item.label"  :required="item.required"></calendar>
          <googleMap v-if="item.type_id == 5" formType="clientForm" :label="item.label"  :required="item.required"></googleMap>
          <autocomplete v-if="item.type_id == 6" formType="clientForm" :label="item.label"  :required="item.required"></autocomplete>


        </v-flex>
      </draggable>

    </v-flex>
  </draggable>


  <v-layout row wrap justify-center>
    <submitButton formType="clientForm" path="/clientForm" :references="this.$refs"></submitButton>
    <clearButton formType="clientForm" :references="this.$refs"></clearButton>
  </v-layout>

  </v-layout>
 </span>
</template>

<script>
export default {
  components: {
    draggable,
  },

  beforeCreate(){
    this.$store.dispatch('clientForm/loadInputs')
  },

  computed: {
    lists: {
      get() {
        return this.$store.getters['clientForm/get'].layout
      },
      set(value) {
        this.$store.commit('clientForm/updateInputList', value)
      }
    }
  },

Vuex Dev Tools Showing Data in State After Page Loads

【问题讨论】:

  • loadInputs mutator中list['inputs'] = []这行的目的是什么?
  • 在对象中创建一个数组,将输入推送到 ''''''''''''''' state.layout[list.order].inputs.push(input)跨度>
  • 好的。您可以添加 getter 定义来回答吗?
  • 好的,我添加了getter
  • 这条线return this.$store.getters['clientForm/get'].layout真的有效吗?

标签: asynchronous vue.js axios vuex


【解决方案1】:

我在去年的寒假里找到了答案,并意识到这里从来没有一个明确的结论。经过反复试验和阅读文档后,我在 Vue.js 文档中找到了答案。

https://vuejs.org/v2/api/#Vue-set

Vue.set(目标、键、值) 将属性添加到响应式对象,确保新属性也是响应式的,因此会触发视图更新。这必须用于向反应性对象添加新属性,因为 Vue 无法检测到正常的属性添加(例如 this.myObject.newProperty = 'hi')。

使用这个函数,我能够通过 axios 调用加载我的数据,并让 Vue 检测更改并更新 DOM。

您可能还需要注意 Vue.delete 以删除具有反应性的数据。

【讨论】:

  • 已经有一段时间了,但是您是否还记得您放置 Vue.set() 语句的位置的更多细节?
【解决方案2】:

我认为您可以简化您的 loadInputs 操作:

async loadInputs ({commit, state}) {
  if (!state.loading) {
    commit('setLoading', true)

    const inputLists = axios.get('/companyInputLists')
    const inputs = axios.get('/companyInputs')

    commit('setLoading', false)
    commit('loadInputs' , [await inputLists, await inputs])
   }
}

组件:

export default {
  components: {
    draggable,
  },
  computed: {
    lists: {
      get() {
        return this.$store.getters['clientForm/get'].layout
      },
      set(value) {
        this.$store.commit('clientForm/updateInputList', value)
      }
    }
  },
  created () {
    this.$store.dispatch('clientForm/loadInputs')
  },
}

【讨论】:

  • 这会导致 Uncaught (in promise) ReferenceError: inputLists is not defined
  • 没有。您只是忘记了重写常量名称。再试一次。
  • 是的,就是这样。我也错过了哈哈
猜你喜欢
  • 1970-01-01
  • 2020-08-23
  • 1970-01-01
  • 1970-01-01
  • 2013-04-25
  • 2020-08-11
  • 2020-01-17
  • 2017-10-17
  • 1970-01-01
相关资源
最近更新 更多