javascriptvue.jsvuejs3vuejs3-composition-api

Data error not coming from Vue 3 browser refresh


I am pulling data from database with Axios. With onMounted, the data is coming, but the data is not visible without any action on the browser. I am using v-for. When there is a change, the data comes in. For example, when I scroll, the data comes. I couldn't solve it, what should I do? Where am I doing wrong?

It looks like in the video below: https://s11.gifyu.com/images/Ekran-Kaydi-2023-04-17-09.21.31-1.gif

<script setup>
import {requiredValidator} from '@validators'
import {onMounted, ref} from "vue";
import axios from '@axios'

const {t} = useI18n()
const route = useRoute()
const name = ref('')
const tag = ref('')
const checkbox = ref(false)
let permissions = ref([])
let selectedPermissions = ref([])

onMounted(async () => {
    try {
        const {data} = await axios.get('/api/users/roles/role-permissions')
        permissions = data.permissions
    } catch (e) {
        console.log(e)
    }
});


</script>

<template>
    <VCard>
        <VCardTitle>
            Rol Ekle
        </VCardTitle>
        <VCardText>
            <VForm class="mt-5">
                <VRow>
                    <VCol
                        cols="12"
                        md="6"
                    >
                        <VTextField
                            v-model="name"
                            label="Rol Parent"
                            placeholder="super-admin"
                            :rules="[requiredValidator]"
                        />
                    </VCol>
                    <VCol
                        cols="12"
                        md="6"
                    >
                        <VTextField
                            v-model="tag"
                            label="Rol Adı"
                            placeholder="Süper Yönetici"
                        />
                    </VCol>
                    <VCol
                        cols="12"
                        md="12"
                    >
                        <h3>Yetkiler</h3>
                    </VCol>
                    <VCol
                        v-for="(perm, index) in permissions" :key="perm.id"
                        cols="12"
                        md="3"
                    >
                        <VCheckbox
                            :label="perm.value"
                            :value="perm.id"
                            v-model="selectedPermissions"
                        />
                    </VCol>
                    <VCheckbox
                        label="perm.value"
                        value="perm.id"
                    />

                    <VCol
                        cols="12"
                        class="d-flex gap-4"
                    >
                        <VBtn type="submit">
                            Ekle
                        </VBtn>

                        <VBtn
                            type="reset"
                            color="warning"
                            variant="tonal"
                        >
                            Sıfırla
                        </VBtn>

                        <VBtn
                            to="/roles"
                            color="secondary"
                            variant="tonal"
                        >
                            Geri Dön
                        </VBtn>
                    </VCol>
                </VRow>
            </VForm>
        </VCardText>
    </VCard>

</template>


<route lang="yaml">
meta:
    action: create
    subject: roles
</route>


Solution

  • You are overriding a reactive object in your code. The purpose of ref() and reactive() is to make constant manipulation immediately detectable by Vue. In contrast, if you declare a reactive array called permissions, but then manipulate the entire object instead of the reactive array, it won't work as intended.

    BAD
    Overriding is not a good practice

    let permissions = ref([])
    permissions = data.permissions // don't use this - now you dropped ref([]) and redeclare permissions as not reactive array
    

    GOOD
    Manipulating the reactive array is the right approach
    (and it's worth noting that the permissions variable can be declared as a const, since we don't want to change its value - it remains a reactive array throughout)

    const permissions = ref([])
    permissions.value = data.permissions // successfully - just modified items of reactive object
    

    More information: https://vuejs.org/api/reactivity-core.html#ref