Vue2 + Vuex - не рендеринг массива, который успешно установлен в хранилище - PullRequest
0 голосов
/ 29 апреля 2018

Я пытаюсь отобразить 209 579 опций и думаю, что я неправильно использую Vuex lifecycle + axios

  • Я вижу все опции, установленные в состоянии магазина через Vuex в консоли.
  • Ошибки не отображаются
  • Параметры пусты и не отображают состояние cityNames массив
  • main.js экспортирует магазин для всех компонентов

Я думаю, что не правильно применяю этот жизненный цикл, где я должен использовать геттеры, может кто-нибудь навести порядок в моем жизненном цикле?

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>

Спасибо, Bud

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

Я изменил свой код для выполнения из вычислений, только чтобы выяснить ошибку (наконец-то!), Которая была: maximum stacksize exceeded, в этот момент я понял, что Vue не позволяет мне отображать такой огромный массив (209 579) элементы) в поле зрения.

часть I - изменение кода:

Я создал состояние isLoaded, установленное на true после того, как axios подтвердит свой ответ,

Я до сих пор не уверен, что это лучший метод из-за асинхронной природы вызова axios, он мог не завершиться с commit('SetCityNames', response.data);, и сразу после вызова commit, он вызвал бы следующее: commit('changeLoadedState');

так что я добавил к состоянию: isLoaded: false

добавил геттер: didItLoad(state){return state.isLoaded}

добавлена ​​мутация: changeLoadedState(state){state.isLoaded = true}

добавил коммит (commit('changeLoadedState');) к моему вызову axios в действиях:

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>

Часть II - Изменение размера полезной нагрузки

Так что после того, как я исправил свой код, я зашел на свой сервер экспресс-узла и изменил цикл моего маршрута, чтобы он останавливался на 1000 элементов, и все работало отлично.

В этот момент мне было любопытно, что произойдет, если я начну добавлять нули, поэтому при 10КБ элементы загружаются через 1-2 секунды, при открытии раскрывающегося списка появляются признаки задержки из-за стресса, при 50КБ элементах требуется около 5 секунд, чтобы открыть раскрывающийся список.

Итог

Проблема не в размере массива, Vuex работает потрясающе, получая массив из 209 579 элементов за ~ 800 мс, который включал разбор бэкэнда в Express.js (весь мой стек является локальным, поэтому сетевая задержка отсутствует).

Я попытаюсь создать автозаполнение, которое будет начинать перечисление со 2-го или 3-го символа.

Спасибо отвечающим.

0 голосов
/ 29 апреля 2018

У вас есть геттеры с именем getCityNames. Это $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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...