Интерполяция не перерисовывается в родительском компоненте после пользовательского события из дочернего

У меня есть выбор, отображаемый в цикле v-for:

<div v-for="(n, key) in selectedLanguages">
    <select class="input input__col"
            v-model="currentLang[key]"
            @change="changeLanguage(currentLang[key], key)"
            id="lang_select">
        <option value="pl">Polski</option>
        <option value="en">Angielski</option>
        <option value="es">Hiszpański</option>
    </select>
</div>

К каждому выбору я добавляю метод changeLanguage, который:

<script>
    export default {
        data() {
            return {
                currentLang: []
            }
        },
        methods: {
            changeLanguage(value, key) {
                let data = { value, key };
                this.$nuxt.$emit('change::language', data);
            }
        },
        props: ['selectedLanguages']
    }
</script>

и это в дочернем компоненте. В родительском я слушаю это событие change::language:

this.$nuxt.$on('change::language', res => {
    console.log(res);
    this.selectedLanguages[res.key] = res.value;
    console.log(this.selectedLanguages);

Хотя он работает правильно и обновляет массив selectedLanguages просто отлично, он не перерисовывает интерполяцию {{ selectedLanguages }} в родительском. Однако он правильно перерисовывает интерполяцию {{ selectedLanguages }} в дочернем элементе, где она передается реквизитами. Почему?


Кажется, что vue не «улавливает», что массив selectedLanguages был изменен. Он видит только когда я .push или .pop этот массив. Есть ли что-то вроде метода apply в vue?

Я нашел эту ссылку в документации: https://vuejs.org/v2/guide/list.html#Caveats и добавил this.$set(this.selectedLanguages, res.value, res.key); в родительский элемент под моим заданием, но это не помогло.


person BT101    schedule 02.02.2019    source источник


Ответы (1)


Я нашел решение в Vue docs:

Из-за ограничений в JavaScript Vue не может обнаружить следующие изменения в массиве: Когда вы напрямую устанавливаете элемент с индексом, например. vm.items[indexOfItem] = новое значение

Я делал точно так же, как выше.

Вместо этого решение

this.selectedLanguages[res.key] = res.value;

использовать

this.$set(this.selectedLanguages, res.key, res.value);

что в основном немного странно, но это работает.

person BT101    schedule 02.02.2019
comment
splice также работает, как и выполняет переназначение всего массива. - person DigitalDrifter; 03.02.2019