Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

252
Visualizações
Why are computed properties not reactive in my Vue 3 app?

Issue

✅ Vue 2: computed properties are updated after vuex store mutation.

❌ Vue 3: computed properties are not updated after vuex store mutation.

Vuex 4

Purpose: Get posts from Firestore. Add to "postsArray". Commit mutation.

Note: The function "getNextPosts" is called from a (working) intersection observer which allows infinite-scrolling.

const postsArray: Array<string> = [];
const vuexStore = createStore({
  state: {
    posts: []
  },
  actions: {
    // See https://firebase.google.com/docs/firestore/query-data/query-cursors#paginate_a_query
    getFirstPosts({ commit }) {
      const getFirstPosts = async () => {
        const firstPostsQuery = firestore.collection("posts").limit(3);

        // Get FIRST posts.
        const firstPosts = await firstPostsQuery.get();

        // Add to postsArray.
        for (const doc of firstPosts.docs) {
          postsArray.push(doc.id);
        }

        // Add to vuex store.
        commit("addFirstPostsToVuex", postsArray);

        // Set reference.
        lastPostDownloaded = firstPosts.docs[2]; // 3rd post.
      };
      getFirstPosts();
    },
    getNextPosts({ commit }) {
      const getNextPosts = async () => {
        const nextPostsQuery = firestore
          .collection("posts")
          .startAfter(lastPostDownloaded)
          .limit(2);

        // Get NEXT posts.
        const nextPosts = await nextPostsQuery.get();

        // Add to postsArray.
        for (const doc of nextPosts.docs) {
          postsArray.push(doc.id);
        }

        // Add to vuex store.
        commit("addNextPostsToVuex", postsArray);

        // Update reference.
        lastPostDownloaded = nextPosts.docs[1]; // 2nd post.
      };
      getNextPosts();
    }
  },
  mutations: {
    addFirstPostsToVuex(state, value) {
      state.posts = value;
    },
    addNextPostsToVuex(state, value) {
      state.posts = value;
    }
  }
});

Computed properties

export default ({
  computed: {
    posts() {
      // List rendering.
      return vuexStore.state.posts;
    }
  }
});

v-for

<template>
  <div id="feed">
    <article class="post" v-for="post in posts" v-bind:key="post.id">
      <header class="info">
        {{ post }}
      </header>
    </article>
  </div>
</template>
over 4 years ago · Santiago Trujillo
4 Respostas
Responde à pergunta

0

This could be fixed if you use mapState function to map store's state to Vue component's state.

In the code above, that would be something like:

import { mapState } from "vuex";
import { defineComponent } from "vue";

export default defineComponent({
     computed: {
        ...mapState(["posts"])
     }
});

The v-for should work just fine now.

Reference: https://vuex.vuejs.org/guide/state.html and https://scrimba.com/scrim/c8Pz7BSK?pl=pnyzgAP

over 4 years ago · Santiago Trujillo Relatório

0

There is a slight difference in defining the state inside Vuex between the old and new version.

**In Vuex3 state was just a prop with an Object while in Vuex4 it has return an Object or a function which returns an Object.**

When migrating from V3 to V4 you might at first not notice the difference because the V3 style kind of works in V4 as well. The difference shows when you've got modules and have multiple instances of them. Then the state has to be a function that returns an object to avoid state pollution (as commented by tony19).

Modules:

// Vuex 3.x Module
const moduleVUEX3 = {
    export const state = { ... }
}

// Vuex 4.x Module
const moduleVUEX4 = {
    export const state = () => ({ ... })
}

Single Store:

// Vuex 3.x
import Vuex from 'vuex'

const store = new Vuex.Store({
  state: { ... }
})


// Vuex 4.x
import { createStore } from 'vuex'

const store = createStore({
  state() {
    return { ... }
  }
})

Solution for this question would be:

const vuexStore = createStore({
  state: return {
    posts: []
  }
})
over 4 years ago · Santiago Trujillo Relatório

0

You could try to remove the postsArray, I assume it has something to do with reactivity.

try changing the mutation to

addFirstPostsToVuex(state, docId) {
      state.posts.push(docId);
    }

and then in the action you do

for (const doc of firstPosts.docs) {
          commit("addFirstPostsToVuex",doc.id);
        }
over 4 years ago · Santiago Trujillo Relatório

0

I usually use it like this

<script setup lang="ts">
import { computed, reactive,ComputedRef } from "vue";
import { useStore } from "vuex";
interface State {
  shadow: ComputedRef<boolean>
}
const store = useStore();

const state = reactive<State>({
  shadow: computed(() => store.state.shadow),
)}
</script>

When the status in vuex changes, the page will respond in time, hope it can help you

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda