在来自子组件的自定义事件发生后,插值不会在父组件中重新呈现

Interpolation doesn't rerender in parent component after custom event from child

我在 v-for 循环中显示了 select:

<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>

我要为每个 select 添加 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 没有 "catch" 那个 selectedLanguages 数组被改变了。它只在我 .push.pop 时看到这个数组。 vue中有没有类似apply的方法?

我在文档中找到了这个 link:https://vuejs.org/v2/guide/list.html#Caveats 并在我的作业下方的父项中添加了 this.$set(this.selectedLanguages, res.value, res.key);,但没有修复。

我在 Vue docs 中找到了解决方案:

Due to limitations in JavaScript, Vue cannot detect the following changes to an array: When you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue

我做的和上面的完全一样。

解决方法是

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

使用

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

这基本上有点奇怪,但它有效。