typescriptvuejs3nuxt3.jsvue-reactivity

Why nested objects are not reactive in Vue3?


I have encountered a problem during updating reactive variables in Vue 3.

For handling my logics in vue 3, i have defined the following composable as follows:

export const useAddCustomPackage = () => {
  // Reactive variables
  const selectedService: {
    title: string;
    description: string;
    period: number;
    data: {
      service: number;
      request_number: number;
      min_interval_time?: unknown;
      service_province?: unknown;
    }[];
  } = reactive({ title: "", description: "", period: 30, data: [] });

  const activeService: {
    [key: string]: IActiveServices;
  } = reactive({
    "ssl-checker": { active: false, requestNumber: 0, id: "", unitPrice: 0 },
    "up-time": { active: false, requestNumber: 0, id: "", unitPrice: 0 },
    traceroute: { active: false, requestNumber: 0, id: "", unitPrice: 0 },
    "interval(up-time)": {
      active: false,
      requestNumber: 0,
      id: "",
      unitPrice: 0,
      minIntervalTime: 0,
      servers: [],
    },
  });

  // Get services and add id to active services list
  const addIdsOfServices = async () => {
    try {
      const response = await fetchListOfServices();

      const listOfServices = response.data;

      for (const service of listOfServices) {
        activeService[service.title].id = service.id;
        activeService[service.title].unitPrice = service.unit_price;
      }
     
      console.log("list of active services", activeService);
    } catch (e) {
      throw new Error("error during fetching list of services");
    }
  };

 return {activeService,addIdsOfServices}
}

and I used the addIdsOfservices in in following component :

 <script setup lang='ts'>
   import CustomPlanForm from "./CustomPlanForm.vue";
   import { useAddCustomPackage } from "../composables/useAddCustomService";
   // Composables
   const {
  selectedService,
  addSubservices,
  addServers,
  addChosenInterval,
  activeService,
  addIdsOfServices,
} = useAddCustomPackage();

onMounted(async()=>{await addIdsOfServices()})
 </script>

<template>
 
   <VCol
      md="12"
      class="d-flex justify-space-between align-center"
      v-for="service in Object.keys(activeService)"
      :key="service"
    >
      <CustomPlanForm
        :unit-price="activeService[service].unitPrice"
        :service-name="service"
        v-model:request-number="activeService[service].requestNumber"
        :cities="cities"
        @emit-servers="addServers"
        @emit-interval="addChosenInterval"
      />
    </VCol>

</template>

When the new ids are added through function of addIdsOfServices, the activeService[service], will not be updated and not reactive!. How can handle this issue?


Solution

  • You are doing de-structuring assignments from reactive objects.

    De-structuring can break reactivity.

    This is a common topic you can search online and the solutions typically involve using toRefs to retain reactivity.

    https://vuejs.org/api/reactivity-utilities.html#torefs