T
T
time_is_always_against_us2020-04-13 15:33:41
Vue.js
time_is_always_against_us, 2020-04-13 15:33:41

How to make JS method execute after full page rendering in Vue.js?

What do I do?
1. Ajax request to the server through the axios library. I get, for example, a list of machines (id -> name).
2. In a cycle I build option for select.
3. I apply bootstrap-select to this select. It is needed to customize select: 5e9447945cb94974637101.png

What's the problem?
The selectpicker JS script doesn't have time to wait for Vue.js to render the select-> option, assuming there are no elements there.

Simplified code looks like this:

<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 - did not help:
5e9466a9f0843885644272.png

Doc read it, in theory it should have solved the problem, but alas.
I will describe in more detail the whole chain of what is really happening, there may be an error in another.
1. Queries are made in the Vuex module and all lists of all selects on the site are obtained from the database.
2. I create a computed listCar property and keep track of it in watch. If it changes, then the data from the server has been loaded and selectpicker can be used.
<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
                })
            }
        }

Answer the question

In order to leave comments, you need to log in

1 answer(s)
0
0xD34F, 2020-04-13
@time_is_always_against_us

nextTick
And this one

$('.selectpicker')

should not be. Instead of a selector, use an element reference .

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question