Что делаю?
1. Ajax запрос к серверу через библиотеку axios. Получаю, к примеру, список машин (id -> name).
2. В цикле строю option для select.
3. К данному select применяю bootstrap-select. Он нужен, чтобы кастомизировать select:
В чем проблема?
JS скрип selectpicker не успевает дождаться, пока Vue.js отрендерит select-> option, считая, что там элементов нет.
Упрощенно код выглядит так:
<template>
<div>
<select name="cars" class="selectpicker">
/* 2. Vue.js, получив данные, начал рендерить option */
<option v-for="(val, key) in cars" :key="key" :value="key">{{val}}</option>
</select>
</div>
</template>
<script>
export default {
data() {
return {
cars: []
}
},
mounted() {
axios.get('/info/car')
.then((result) => {
this.cars = result.data; /* 1. Получили данные от сервера и записали в переменную. */
$('.selectpicker').selectpicker(); /* 3. Иногда не успевает дождаться рендеринга и
в select не отображает элементы, ибо vue.js их еще не создал. */
});
}
}
</script>
Upd:
this.$nextTick - не помог:
Доку прочитал, в теории это должно было решить проблему, но увы.
Подробнее опишу всю цепочку того, что реально происходит может быть ошибка в другом.
1. В модуле Vuex делаются запросы и получаются все списки всех select на сайте из БД.
2. Создаю computed свойство listCar и отслеживаю его в watch. Если изменится, значит данные с сервера загружены и можно применять selectpicker.
<template>
<div>
<select name="cars" class="selectpicker" id="carList">
/* Использует computed listCar */
<option v-for="(val, key) in listCar" :key="key" :value="key">{{val}}</option>
</select>
</div>
</template>
computed: {
...mapState(['list']), // Получили
listCar() {
return this.list.cars;
}
},
watch: {
listCar() { // Отслеживает, чтобы список с сервера уже был загружен.
this.$nextTick(function () { // Ждем пока отрендерит.
$('#carList').selectpicker(); // Применяет selectpicker
})
}
}