使用 fetch 检索数据时,Vue JS 组件没有反应

Vue JS component not reactive when retrieving data using fetch

我的 Vue 应用程序有一个奇怪的问题。 该组件如下所示:

...
<template v-for="foo in foos">
   <Elm v-if="foo.visible" :key="foo.label" :bar="foo" />
</template>
...

"Elm" 是对象中的值,从 JSON 文件中检索。 如果我在本地获取 JSON 文件,该组件是反应性的:

<script>
    import datas from "datafile.json";
    ...
    methods: {
        fillFoos() {
            datas.forEach(data => {
               this.foos.push(data)
            })
        }
    },
    mounted: {
        this.fillFoos()
   }
   ...
</script>

但是当我使用 fetch 远程检索文件时,组件不再反应并且当 foo.visible 值更改时组件不再消失 :

<script>
    methods: {
        getDataFromApi() {
            return new Promise((resolve, reject) => {
                fetch(this.apiUrl)
                .then(response => {
                    return response.json();
                })
                .then(jsonResponse => {
                    resolve(jsonResponse);
                })
                .catch(e => {
                    ...
                })
            })
        },
        fillFoos() {
            this.getDataFromApi()
            .then(response => {
                response.forEach(data => {
                    this.foos.push(data);
                });
            });
        }
    },
    mounted: {
        this.fillFoos()
    }
    ...
</script>

在这两种情况下,"foos" 数组都被正确填充,唯一的区别是 v-if 指令在第二种情况下似乎被破坏了。 更准确地说,显示在初始化时正确完成(foo.visible 对所有元素都是正确的,它们都显示了),但如果稍后更改 foo.visible 值,它们不会'消失。

我找不到问题所在...

我认为您遇到的问题是方法 getDataFromApi 正在返回一个承诺,但是当您在 fillFoos 中使用它时,不会等待承诺,而是调用 forEach 就可以了。

您需要使用 getDataFromApi().then(x => {}) 语法来解决承诺,或者您可以使用 async await.

你可以试试这个

methods: {
    async getDataFromApi() {
        const response= await fetch(this.apiUrl);
        return response.json();
    },
    async fillFoos() {
        try {
            await foos = this.getDataFromApi();
            this.foos = foos;
        } catch(error) {
            //handle error.
        }
    }
}

昨天有人发了一个很接近解决方案的回复,后来删了,不知道为什么。 问题是我在使用它填写 "foos" table

之前将获取响应存储在数据部分的一个变量中
data: function() {
    return {
        dataFromApi: null
    }
}

通过删除这个变量,然后在获取后即时创建它,一切正常....我没有指定我将答案存储在这个变量中,因为我认为它不可能相关...道德:总是指定一切!