[Vuejs]-Vue 3/Nuxt v-if/watch prevents data attr from init

0๐Ÿ‘

I was able to figure it out myself.

Index.vue โ€” I had to add a const appLoaded that would init the drawer component onMounted(), I found that it would try to search for the data attr associated with the off canvas drawer before this. We also removed any/all flowbite init and imports since we moved this over to ProductGrid.vue

<meta name="viewport" content= "width=device-width, initial-scale=1.0">
<template>
<Header />
  <!-- drawer init and toggle -->
  <!-- drawer component -->
  <div
  v-if="appLoaded"
    id="drawer-right-example"
    class="
      fixed
      top-0
      right-0
      z-40
      h-full
      p-4
      overflow-y-auto
      transition-transform
      translate-x-full
      bg-white
      w-96
    "
    tabindex="-1"
    aria-labelledby="drawer-right-label"
  >
    <button
      type="button"
      data-drawer-hide="drawer-right-example"
      aria-controls="drawer-right-example"
      class="
        text-gray-400
        bg-transparent
        hover:bg-gray-200 hover:text-gray-900
        rounded-lg
        text-sm
        p-1.5
        absolute
        top-2.5
        right-2.5
        inline-flex
        items-center
        dark:hover:bg-gray-600 dark:hover:text-white
      "
    >
      <svg
        aria-hidden="true"
        class="w-5 h-5"
        fill="currentColor"
        viewBox="0 0 20 20"
        xmlns="http://www.w3.org/2000/svg"
      >
        <path
          fill-rule="evenodd"
          d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
          clip-rule="evenodd"
        ></path>
      </svg>
      <span class="sr-only">Close menu</span>
    </button>
    <LoadItem />
  </div>
  <!--End of Drawer-->
  <div class="mx-auto max-w-7xl mt-5">
    <ProductGrid />
  </div>
  <!--End Shadow-->
  <Footer/>
</template>
<script setup lang="ts">
const appLoaded = ref(false);
// initialize components based on data attribute selectors
onMounted(() => {
  document.documentElement.style.setProperty("--vh", window.innerHeight * 0.01 + 'px');
  appLoaded.value = true;
});
</script>
<style type="css">
.bg-gray-900 {
  background-color: #111827;
  opacity: 0.8;
}
.h-screen {
    height: 100vh; /* Fallback for browsers that do not support Custom Properties */
    height: calc(var(--vh, 1vh) * 100);
}
</style>

ProductGrid.vue โ€” We are moving the flowbite imports and inits to this file, instead we are going to init each import on updated since the actual data attr are not initially loaded because of the skeleton loader.

<script setup>
//import Store Data
import { useAppStore } from '~/store/app';
import { Drawer } from 'flowbite';
import { onMounted } from 'vue';
import { initDrawers, initTooltips, initDropdowns } from 'flowbite';

// initialize components based on data attribute selectors
onUpdated(() => {
  initDrawers();
  initTooltips();
  initDropdowns();
});

const supabase = useSupabaseClient();
const to = ref(14);
const load = ref(false);
const supaPagination = () => ((to.value = to.value + 5), (load.value = true));
const returnData = ref(null);
const end = ref(false);

//we are fetching count for rows in database
const { count } = await supabase
  .from('productinfo1')
  .select('*', { count: 'exact' });

watch(
  () => to.value,
  async () => {
    // added async keyword here
    if (to.value && to.value <= count) {
      const { data, error } = await supabase
        .from('productinfo1')
        .select('*', { count: 'exact' })
        .range(0, to.value);
      if (to.value == 14) {
        setTimeout(function () {
          returnData.value = data;
          load.value = false;
        }, 1000);
      } else {
        load.value = true;
        setTimeout(function () {
          returnData.value = data;
          load.value = false;
        }, 1000);
      }
      //we are using to.value + 1 to set the value end.value = true once the last item has loaded
      if (to.value + 1 >= count) {
        //we are emting this to let the DOM know there are no more items to load.
        end.value = true;
      }
    }
  },
  { immediate: true }
);

//set Store as a Constant
const appStore = useAppStore();

watch(
  () => appStore.storeID,
  () => {
    // added async keyword here
    if (appStore.storeID > 0) {
      appStore.updateDataID(0);
      //console.log(document.getElementById('drawer-right-example'));
    }
  }
);
</script>

Leave a comment