简体   繁体   English

Vue-js和Vuex:视图未更新

[英]Vue-js and Vuex: View not being updated

I am using Vuejs and Vuex to play around with. 我正在使用Vuejs和Vuex一起玩。 Currently i have an issue updating the view (vuejs) after an AJAX call has been fired. 目前,在触发AJAX调用后,我在更新视图(vuejs)时遇到问题。 The view should update but it does not work if i use arrays, objects and booleans. 该视图应该更新,但是如果我使用数组,对象和布尔值,它将无法正常工作。 If i update a string via the store commit this will get updated properly in the view. 如果我通过商店提交更新字符串,则将在视图中正确更新。 I do see in the vue develop tool the vuex / store getting updated properly. 我确实在vue开发工具中看到vuex /商店正在正确更新。 Once i make a change to the part of example.vue hot reloading kicks in and the data is being shown. 一旦我对example.vue的部分进行了更改,就会开始进行热重装,并显示数据。

I think i really mis a small thing but cannot figure out what is needed to trigger the update. 我认为我确实错了一件小事,但无法弄清楚触发更新需要什么。

Currently i have set this up using the vue-cli tool and added Axios and Vuex via npm. 目前,我已经使用vue-cli工具进行了设置,并通过npm添加了Axios和Vuex。

This is my code: store.js 这是我的代码: store.js

import Vue from 'Vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

export const StoreExample = new Vuex.Store({
    state: {
        customers: [],
        isLoading: false,
    },

    getters: {
        getCustomers: state => state.customers,
        isLoading: state => state.isLoading,
    },

    mutations: {
        setCustomers(state, payload) {
            state.customers.push(payload)
        },

        setLoading(state, payload) {
            state.isLoading = payload
        }
    },

    actions: {
        fetchCustomers({state, commit}) {
            commit('setLoading', true)
            axios.get('https://api.myjson.com/bins/rkyih')
            .then(response => {
                commit('setCustomers', response.data)
                commit('setLoading', false)
            })
            .catch(e => {
                console.error(e)
                commit('setLoading', false)
            })
        }
    },

    strict: process.env.NODE_ENV !== 'production'
})

main.js main.js

import Vue from 'vue'
import Vuex from 'vuex'
import { StoreExample } from './store/store.js'
import App from './App'

Vue.use(Vuex)
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  store: StoreExample,
  components: { App },
  template: '<App/>'
})

example.vue example.vue

<template>
    <div>
        {{isLoading}}
        {{getCustomers}}
    </div>

</template>

<script>
    import { mapGetters } from 'vuex'

    export default {
        name: 'example',

        created() {
            this.$store.dispatch('fetchCustomers')
        },

        computed: {
            ...mapGetters([
                'getCustomers',
                'isLoading'
            ])
        }
    }
</script>

App.vue 应用程序

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

<script>
import example from './components/example'

export default {
  name: 'App',

  components: {
    example
  }
}
</script>

I can't seem to replicate your problem, however, I made use of your code and created a fully working example, which is basically 90% of your code. 我似乎无法复制您的问题,但是,我利用了您的代码并创建了一个完全正常的示例,该示例基本上占您代码的90%。

In this example: 在此示例中:

  • I verified there's no difference between using getters or accessing the state directly. 我验证了使用getter或直接访问状态之间没有区别。
  • I also verified your problem has nothing to do with array.push(), as Vue's already wrapped around Array.push() to trigger updates. 我还验证了您的问题与array.push()无关,因为Vue已经包装在Array.push()以触​​发更新。
  • Instead of using axios, I used fetch for simplicity, which should work the same. 为了简单起见,我使用了fetch而不是使用axios,该方法应该相同。

 const store = new Vuex.Store({ state: { customers: [], isLoading: false, }, getters: { gCustomers: state => state.customers, gIsLoading: state => state.isLoading, }, mutations: { setCustomers(state, payload) { state.customers = payload }, setLoading(state, payload) { state.isLoading = payload }, addCustomer(state, payload) { state.customers.push(payload) }, resetCustomers(state) { state.customers = []; } }, actions: { fetchCustomers({ state, commit }) { return fetch('https://api.myjson.com/bins/rkyih') .then(res => res.json()) .then(response => { commit('setCustomers', response) commit('setLoading', false) }) .catch(e => { console.error(e) commit('setLoading', false) }); } }, }); const app = new Vue({ store, el: '#app', data: { dataId: '', isActive: '', age: '', firstName: '', lastName: '' }, computed: { ...Vuex.mapGetters([ 'gIsLoading', 'gCustomers' ]), ...Vuex.mapState([ 'customers', 'isLoading' ]) }, methods: { ...Vuex.mapActions({ getData: 'fetchCustomers' }), ...Vuex.mapMutations({ resetData: 'resetCustomers' }), addCustomer() { this.$store.commit('addCustomer', { id: this.dataId, isActive: this.isActive, age: this.age, first_name: this.firstName, last_name: this.lastName, }); this.resetInputs(); }, resetInputs() { this.dataId = '' this.isActive = '' this.age = '' this.firstName = '' this.lastName = '' } } }); 
 .container { display: flex; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script> <div id="app"> <button v-on:click="getData()">Get Data from API</button> <button v-on:click="resetData()">Reset Data</button> <div> <div>Id: <input v-model="dataId"/></div> <div>isActive: <input v-model="isActive" type="checkbox"/></div> <div>Age: <input v-model="age"/></div> <div>First Name: <input v-model="firstName"/></div> <div>Last Name: <input v-model="lastName"/></div> <div><button v-on:click="addCustomer()">Add Data</button></div> </div> <div class="container"> <div class="column"> <h3>mapState</h3> <div>Loading? {{isLoading}}</div> <ul> <li v-for="customer in customers"> {{customer}} </li> </ul> </div> <div class="columns"> <h3>magGetters</h3> <div>Loading? {{gIsLoading}}</div> <ul> <li v-for="customer in gCustomers"> {{customer}} </li> </ul> </div> </div> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM