1
votes

I use @nuxtjs/composition-api(0.15.1), but I faced some problems about accessing Vuex getters in computed().

This is my code in composition API:

import { computed, useContext, useFetch, reactive } from '@nuxtjs/composition-api';

  setup() {
    const { store } = useContext();
    const products = computed(() => {
      return store.getters['products/pageProducts'];
    });
    const pagination = computed(() => {
      return store.getters['products/pagination'];
    });

    useFetch(() => {
      if (!process.server) {
        store.dispatch('products/getPage');
      }
    });

    return {
      products,
      pagination,
    };
  }

And the console keeps reporting the warning:

[Vue warn]: Write operation failed: computed value is readonly.

found in

---> <Pages/products/Cat.vue> at pages/products/_cat.vue
       <Nuxt>
         <Layouts/default.vue> at layouts/default.vue
           <Root>

I'm really confused. Because I didn't try to mutate the computed property, just fetching the Data with the AJAX and then simply assign the data to the state in the Vuex mutations.

But I rewrite the code in option API in this way:

export default {
  components: {
    ProductCard,
    Pagination,
  },
  async fetch() {
    if (process.server) {
      await this.$store.dispatch('products/getPage');
    }
  },
  computed: {
    products() {
      return this.$store.getters['products/pageProducts'];
    },
    pagination() {
      return this.$store.getters['products/pagination'];
    },
  },
};

Everything works fine, there's no any errors or warnings. Is it the way I'm wrongly accessing the getters in the composition API or that's just a bug with the @nuxtjs/composition-api plugin?

1
Although probably unrelated, your fetch hook in the options API runs on the server (if (process.server)), while the one in the composition API does not (if (!process.server)). Can you link to a repro (Codesandbox or GitHub)? - tony19
@tony19 Here's the repo shorturl.at/pCOZ6. You're right. It's not related to the process.server, and I'm not trying to solve the problem from the server / client aspect also, but still can't figure it out. In my memory, I remember it's fine to access the Vuex getters from the computed(). - Ray
@tony19 I found a article which is talking about this kind of error. And use other way to prevent the error. thanks a lot for your help. - Ray

1 Answers

1
votes

fix: computed property hydration doesn't work with useFetch #207

This problem might not can be solved until the Nuxt3 come out.

But I found an alternative solution which use the middleware() instead of use useFetch(), if you want to the prevent this bug by fetching AJAX data with Vuex Actions and then retrieve it by Getters via the computed().

I make another clearer example which it's the same context like the question above.

~/pages/index.vue :

<script>
import { computed, onMounted, useContext, useFetch } from '@nuxtjs/composition-api';

export default {
  async middleware({ store }) {
    await store.dispatch('getUser');
  },
  setup() {
    const { store } = useContext();
    const user = computed(() => store.getters.user);

    return {
      user,
    };
  },
}
</script>

~/store/index.js (Vuex)

const state = () => ({
  user: {},
});

const actions = {
  async getUser({ commit }) {
    const { data } = await this.$axios.get('https://randomuser.me/api/');
    console.log(data.results[0]);
    commit('SET_USER', data.results[0]);
  },
};

const mutations = {
  SET_USER(state, user) {
    state.user = user;
  },
};

const getters = {
  user(state) {
    return state.user;
  },
};

If there's something wrong in my answer, please feel free to give your comments.