首页 文章

Vue-js和Vuex:查看未更新

提问于
浏览
0

我正在使用Vuejs和Vuex来玩 . 目前我在触发AJAX调用后更新视图(vuejs)时出现问题 . 视图应该更新但如果我使用数组,对象和布尔值则不起作用 . 如果我通过商店提交更新字符串,这将在视图中正确更新 . 我确实在vue开发工具中看到vuex / store正确更新 . 一旦我对example.vue的部分进行了更改,就会启动热重新加载并显示数据 .

我认为我真的错了一件小事,但无法弄清楚触发更新所需的内容 .

目前我已经使用vue-cli工具进行了设置,并通过npm添加了Axios和Vuex .

这是我的代码: 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

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

<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>

1 回答

  • 0

    我似乎无法复制您的问题,但是,我使用了您的代码并创建了一个完全可用的示例,基本上是您的代码的90% .

    在这个例子中:

    • 我确认使用getter或直接访问状态没有区别 .

    • 我还验证了你的问题与array.push()没有任何关系,因为Vue已经包围 Array.push() 以触发更新 .

    • 为了简单起见,我使用 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>
    

相关问题