Vue2 + Vuex - 不渲染在存储中成功设置的数组

时间:2018-04-29 06:24:07

标签: vue.js vuejs2 vuex

我正在尝试渲染209,579个选项,我认为我没有正确使用Vuex生命周期+ axios

  • 我在控制台中看到通过Vuex在商店状态中设置的所有选项。
  • 未显示错误
  • 选项为空,不呈现状态cityNames数组
  • main.js正在将商店导出到所有组件

我认为我没有正确应用这个生命周期,我应该在这里使用getter,有人可以为我的生命周期带来秩序吗?

store.js

import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';

Vue.use(Vuex);

export default new Vuex.Store({
state: {
        isTrue: true,
        cityNames: [],
    },

    getters:{
        getCityNames(state){
            return state.cityNames;
        }
    },
    mutations: {
        SetCityNames(state, cityNames){
            state.cityNames = cityNames
    },
    actions: {
        loadData({commit}){
            axios.get('http://localhost:3000/allCities')
                .then(function (response) {
                    commit('SetCityNames', response.data)
                }).catch(function (error) {
                    console.log(error);
            });

        }
    },
});

脚本

export default {
    name: "Weather",
    methods: {
        allCityNames() {
            this.$store.dispatch('loadData')
        }
    },
    created() {
        this.allCityNames();
    }
}

模板

<select>
    <option disabled value="">Please select one</option>
    <option v-for="cityName in $store.cityNames">{{cityName}}</option>
</select>

谢谢, 芽

2 个答案:

答案 0 :(得分:2)

我已经将我的代码改为从计算执行,只是为了找出错误(最后!):maximum stacksize exceeded,此时我明白Vue不会让我渲染如此巨大的数组(209,579项)进入视野。

第I部分 - 代码更改:

我创建了一个isLoaded状态,一旦axios提交了它,就会设置为true

  

我仍然不确定这是否是最好的方法,因为axios的调用具有异步特性,它可能还没有完成commit('SetCityNames', response.data);并且在调用提交之后,它会调用下一个:commit('changeLoadedState');

所以我已添加到州:isLoaded: false

添加了一个getter:didItLoad(state){return state.isLoaded}

添加了一个变异:changeLoadedState(state){state.isLoaded = true}

在操作中为我的axios调用添加了一个提交(commit('changeLoadedState');):

loadData({commit}) {
            axios.get('http://localhost:3000/allCities')
                .then(function (response) {
                    commit('SetCityNames', response.data);
                    commit('changeLoadedState');
                }).catch(function (error) {
                console.log(error);
            });
        }

在我的组件中,我仍在调用方法中的axios调用,因为它首先被调用,并为渲染方添加了computed方法,如下所示:

computed:{
          isLoaded(){
              return this.$store.getters.didItLoad;
          },
            renderCities(){
                return this.$store.getters.getCityNames;

            }
        }

在我的渲染模板中,我首先检查我选择加载的状态,然后填充选项:

<select v-if="isLoaded">
    <option disabled value="">Please select one</option>
    <option v-for="cityName in renderCities">{{cityName}}</option>
</select>

第二部分 - 更改有效载荷大小

因此,在设置我的代码之后,我进入了我的节点快速服务器并改变了我的路由循环以停止1000个项目,并且一切都很好。

此时我很好奇如果我开始添加零会发生什么,所以在10K项目,加载选项需要1-2秒,打开下拉列表开始显示由于压力导致的延迟迹象,在50K项目它大约花5秒钟打开下拉列表。

底线

问题不在于数组的大小,Vuex的工作效果令人惊讶,在800毫秒内获得209,579个项目数组,其中包括Express.js的后端解析(我的整个堆栈是本地的,因此没有网络延迟)。

我将尝试创建一个自动填充程序,该代码将从第2个或第3个字符开始列出。

感谢回复成员。

答案 1 :(得分:1)

您有一个名为getCityNames的getter。$store.getters.getCityNames而不是$store.cityNames

所以改变

<option v-for="cityName in $store.cityNames">{{cityName}}</option>

<option v-for="cityName in $store.getters.getCityNames">{{cityName}}</option>

最好重构使用计算属性而不是在模板中内联。

<option v-for="cityName in cityNames">{{cityName}}</option>

//script
computed: {
    cityNames() {
        return this.$store.getters.getCityNames;
    }
}