JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.26/vue.global.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/4.0.2/vuex.global.min.js"></script>

<div id="app">
  <button :disabled="!prev" @click="fetchPokemons('prev')">prev</button>
  <button :disabled="!next" @click="fetchPokemons('next')">next</button>
  <div v-if="loading">loading...</div>
  <div v-else>
    <div v-for="n in pokemons" class="pokemon-list-item">{{ n.name }}</div>
  </div>
</div>

CSS

.pokemon-list-item {
  font-family: monospace;
  margin: 10px;
  padding: 10px;
  border: 1px solid silver;
  display: inline-block;
}

JavaScript

const store = Vuex.createStore({
  state: {
    pokemons: [],
    next: 'https://pokeapi.co/api/v2/pokemon',
    prev: null,
    loading: false,
  },
  mutations: {
    setLoading: (state, loading) => state.loading = loading,
    setPokemons: (state, { pokemons, next, prev }) =>
      Object.assign(state, { pokemons, next, prev }),
  },
  actions: {
    async fetchPokemons({ state, commit }, page) {
      if ([ 'next', 'prev' ].includes(page) && state[page] && !state.loading) {
        commit('setLoading', true);

        try {
          const data = await fetch(state[page]).then(r => r.json());

          commit('setPokemons', {
            pokemons: data.results,
            next: data.next,
            prev: data.previous,
          });
        } catch (e) {
          console.error(e);
        }

        commit('setLoading', false);
      }
    },
  },
});

Vue.createApp({
  computed: Vuex.mapState([ 'pokemons', 'prev', 'next', 'loading' ]),
  methods: Vuex.mapActions([ 'fetchPokemons' ]),
  created() {
    this.fetchPokemons('next');
  },
}).use(store).mount('#app');