2

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?

3
  • 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
    Commented Nov 20, 2020 at 5:19
  • @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
    Commented Nov 20, 2020 at 7:48
  • @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
    Commented Nov 21, 2020 at 14:25

1 Answer 1

2

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.

2
  • FYI useStore is now available composition-api.nuxtjs.org/packages/store
    – Nick
    Commented Jul 8, 2021 at 14:15
  • @Nick: Thanks, this one would be helpful when next time I'm using Nuxt2 with composition api!
    – Ray
    Commented Sep 11, 2021 at 1:20

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.