vuejs - npm запускает автоматическое обновление dev веб-сервера, когда я сохраняю файл, но обновление браузера не - PullRequest
0 голосов
/ 09 сентября 2018

Я очень новичок в VueJS, но мне нравятся возможности. Я начал с одного из моих простых проектов (одностраничного приложения php / jquery) и работал над его преобразованием в VueJS / Webpack. В основном это таблица, которая собирает данные JSON в массив, заполняет таблицу и имеет элементы управления фильтрами. Выпадающие элементы управления, которые фильтруют, заполняются уникальными значениями из поля json. Это то, над чем я сейчас работаю (уже работает вызов json и таблица, а также модалы, которые появляются при нажатии на строку таблицы).

Что я замечаю, это странно, если я работаю и сохраняю свою работу в своей IDE (vscode), а localwebserver обновляет мою страницу, я вижу, что в моем коде должно произойти. Однако, если я снова нажму REFRESH в моем браузере, ничего не будет работать, как ожидалось. Хороший пример - один из моих компонентов, я создаю массив для использования в моих выпадающих элементах управления. Я вывожу массив, который использую для заполнения раскрывающегося списка, используя console.log(), чтобы убедиться, что он работает, как я надеюсь, и когда я просто сохраняю файл в vscode, он корректно выводит данные в браузере. Если я немедленно обновлю свою страницу в браузере, он не выведет массив, как он это сделал, и вместо этого я вижу [__ob__: Observer] с length:0, где мой массив был ранее выведен из-за console.log (). Это также не заполняет мой выпадающий список .. Это ожидаемое поведение?

Использование npm с webpack и (впервые) встроенным веб-сервером и компилятором. Я использую одностраничный подход, App.vue, и у меня есть 3 компонента в этом App.vue. Я заполняю массив с именем fans, используя данные json (на моем хуке mounted()), и передаю его как опору в каждый компонент. Вот мой App.vue:

<template>
  <div>
      <fan-modals v-bind:fans="fans"></fan-modals>

      <div class="container">
          <filter-controls v-bind:fans="fans"></filter-controls>
          <fans v-bind:fans="fans"></fans>
      </div>  <!-- end #container -->
  </div>
</template>

<script>
  import FilterControls from './components/FilterControls.vue';
  import Fans from './components/Fans.vue';
  import FanModals from './components/FanModals.vue';

  export default {
    name: 'app',
    data: function() {
      return {
        fansUrl: 'example.com',
        fans: []
      }
    },
    components: {
      filterControls: FilterControls,
      fans: Fans,
      fanModals: FanModals
    },
    methods: {
    },
    mounted() {
        var self = this;
        $.getJSON(self.fansUrl, function(data){
            self.fans = data;
        });
    }
}
</script>

Компонент, который вызывает у меня проблемы, - это мой FilterControls компонент, показанный здесь (для краткости я пропустил все остальные элементы управления):

<template>

        <div class="row">
            <div class="col-xs-6 col-sm-6 control-wrap">
                <select id='selectVoltage' class='form-control' v-model="voltageArray">
                <option>Voltage</option>
                <option v-for="(voltage, index) in voltageArray" :key="index" v-bind:value="voltage">
                    {{ voltage }}
                </option>
                </select>
            </div>
            <div class="col-xs-6 col-sm-6 control-wrap">
                <select id='selectMaxRPM' class="form-control">
                <option>Max RPM</option>
                </select>
            </div>
        </div>
        </template>

<script>
    export default {
        data: function() {
            return {
                voltageArray: [],
            }
        },
        props: {
            fans: {
                type: Array,
                required: false
            }
        },
        methods: {
            populateControls() {
                var vi = this;
                console.log("populateControls() called ");
                if (vi.fans) {
                    console.log("there are fans ");

                    var voltage = [];

                    $.each(vi.fans, function(index, value) {
                        voltage.push(vi.fans[index].voltage);

                    });

                    vi.voltageArray = $.unique(voltage);

                    console.log(vi.voltageArray);
                }

            }
        },
        mounted() {
            this.populateControls();
        }
    }
</script>

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

Когда я сохраняю свою работу и она автоматически обновляется в браузере, она работает. Когда я обновляю страницу в браузере, это не так. Я сбит с толку.

1 Ответ

0 голосов
/ 09 сентября 2018

Это состояние гонки. Время монтирования <filter-controls> и ответа асинхронной сети от $.getJSON будет различным. В тех случаях, когда вы видите ожидаемый результат, сетевой ответ, вероятно, будет получен до того, как <filter-controls> смонтирован Ответ сети может быть задержан по разным причинам, включая плохое сетевое соединение.

Я считаю, что в вашем случае происходит то, что сетевой ответ получен после <filter-controls> монтирования и регистрации fans (который основан на сетевом ответе). Позже вы делаете правку, webpack-dev-server горячие перезагрузки, и браузер получает кешированный сетевой ответ (без сетевого запроса) до монтирования <filter-controls>.

демонстрация ошибки

Вы также можете доказать это себе в своей песочнице, отключив кэш в Chrome DevTools.

Лучше удалить предположение о том, что данные о пропелле будут доступны при монтировании компонента. Вместо этого используйте watcher , чтобы реагировать на изменения реквизита:

export default {
  mounted() {
    // this.populateControls(); // DON'T DO THIS
  }
  watch: {
    fans(value) { // <-- called whenever fans prop changes
      this.populateControls(value);
    }
  },
  methods: {
    populateControls(fans) {
      console.log('new fans', fans);
    }
  }
}

Также обратите внимание, что v-model из <select> должно содержать значение выбранного напряжения, а не voltageArray, которое используется для заполнения <option> с. Вы должны добавить переменную data исключительно для выбранного напряжения:

<!-- <select v-model="voltageArray">  // DON'T DO THIS -->
<select v-model="selectedVoltage">

демонстрация исправлений

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...