Home > Mobile >  Vue 3 computed property and ref not updating page content
Vue 3 computed property and ref not updating page content

Time:09-06

I have a Pinia store with content that I am pulling onto cards on a page. There are 3 pages identical in format but with different content, and when I switch between the pages I have to update the content by updating the list ref, which is passed through a computed property, filteredList, which filters based on a current selected topic, selectedCategory. The issue I'm running into is despite the list being a ref and going through a computed, the content is not being updated on the page.

I know the list ref is updating correctly through console logs on each page update, but I think either the updated content is not making it through the computed filteredList or it is making it through the filter and just not displaying on the page.

When I initialize the list ref as null and then load the data on a onMounted() hook, it doesn't display any content on the page but when I initialize the list ref with a page's content, it displays the content on the page, but then it won't update the content in either situation when I try to change the pages.

As far as I know, each content.id is unique, which is a common issue that I've seen from other Stack Overflows. I've even tried the avoided practice of force reloading the component or creating fake key that you increment to force reload the element, but none of those have worked.

// list ref
var list = ref(null); // doesn't work

var list = ref(contentStore.guides); // works

// mounted hook
onMounted(() => {
  console.log("mounted");
  if (path.value.includes("guide")) {
    list = ref(contentStore.guides);
    pageType.value = "guide";
  } else if (path.value.includes("resource")) {
    list = ref(contentStore.resources);
    pageType.value = "resource";
  } else if (path.value.includes("tool")) {
    list = ref(contentStore.tools);
    pageType.value = "tool";
  } else router.push("/");
  console.log("list", list.value);
});

// updated hook
var pageType = ref(null);

onUpdated(() => {
  console.log("updated");
  if (path.value.includes(pageType.value)) return console.log("same page");
  else console.log("different page");
  if (path.value.includes("guide"))
    (list = ref(contentStore.guides)), (pageType.value = "guide");
  else if (path.value.includes("resource"))
    (list = ref(contentStore.resources)), (pageType.value = "resource");
  else if (path.value.includes("tool"))
    (list = ref(contentStore.tools)), (pageType.value = "tool");
  else router.push("/");
});

// filter
const selectedCategory = ref("");

var filteredList = computed(() => {
  if (selectedCategory.value === "") return list.value;
  else return list.value.filter((item) => item.category.includes(selectedCategory.value));
});

card HTML

<GeneralCard
  
  v-for="content in filteredList"
  :key="content.id"
  :content="content"
/>

What the intended behavior is is that when the user loads to one of the three pages, it gets the type of page from the URL path (resources, guides, or tools), and then accordingly gets and updates the content (list) and then resets the filter (filteredList) so that the selectedCategory is "" and the filter will return the unfiltered list.

Thanks for any help or insight you can provide, I've been stuck on this for a few hours.

CodePudding user response:

I was reassigning the ref every time the page updated, thanks to Emil for pointing this out. I needed to instead be updating the ref.value = newContent instead of doing ref = ref(newContent). Here's the fixed code :)

onMounted(() => {
  if (path.value.includes("guide")) {
    list.value = contentStore.guides;
    pageType.value = "guide";
  } else if (path.value.includes("resource")) {
    list.value = contentStore.resources;
    pageType.value = "resource";
  } else if (path.value.includes("tool")) {
    list.value = contentStore.tools;
    pageType.value = "tool";
  } else router.push("/");
});

onUpdated(() => {
  if (path.value.includes(pageType.value)) return;
  if (path.value.includes("guide"))
    (list.value = contentStore.guides), (pageType.value = "guide");
  else if (path.value.includes("resource"))
    (list.value = contentStore.resources), (pageType.value = "resource");
  else if (path.value.includes("tool"))
    (list.value = contentStore.tools), (pageType.value = "tool");
  else router.push("/");
});
  • Related