vue.jsvuejs3vue-composition-apivue-options-api

Show loaded data in curly braces using Vue 3 Composition API


Can someone explain the difference between the following, please?

Options API version

Displays loaded data in DOM as expected

export default {
    data() {
        return {
            config: {},
        };
    },
    async mounted() {
        this.config = await fetch('/path/to/file.json');
    },
    template: `<div>{{ config }}</div>`
}

Composition API version

Displays initial state of config but not the loaded data

import { onMounted, reactive } from 'vue';

export default {
    setup() {
        let config = reactive({});

        onMounted(async () => {
            config = await fetch('/path/to/file.json');
        });

        return {
            config,
        };
    },
    template: `<div>{{ config }}</div>`
}

I suspect that the reactive() is being overridden by the asynchronous data load (and I can console log the new data in the onMounted function) but I can't see anything in the docs to indicate how to mass-update a reactive object like this (especially when it works in the Options API)

Edit: final thoughts:

I've taken to using reactive objects to provide / inject data around the app and then using toRefs as a JIT way to provide the reactive data to my views. This seems to be the best of both worlds.

example:

import { onMounted, reactive, toRefs } from 'vue';

export default {
    setup() {
        const data = reactive({
            config: {},
        });

        onMounted(async () => {
            data.config = await fetch('/path/to/file.json');
        });

        return {
            ...toRefs(data),
        };
    },
    template: `<div>{{ config }}</div>`
}

Solution

  • I think if you are overriding the whole config you should use ref instead of reactive. See HERE

      setup() {
        let config = ref({});
    
        onMounted(async () => {
            config.value = await fetch('path/to/file.json');
        });
    
        return {
            config,
        };
    }
    

    Never the less its working with reactive too:

      setup() {
        let config = reactive({});
    
        onMounted(async () => {
            config.value = await fetch('path/to/file.json');
        });
    
        return {
            config,
        };
    }