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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/element-plus/1.0.2-beta.71/index.full.min.js"></script>
<div id="app">
<el-pagination
v-model:current-page="currentPage"
:page-count="$store.state.pages"
layout="prev, pager, next"
background
></el-pagination>
<div v-loading="$store.state.loading">
<div
v-for="n in $store.state.pokemons"
v-text="n.name"
class="pokemon-list-item"
></div>
</div>
</div>
CSS
@import url(https://cdnjs.cloudflare.com/ajax/libs/element-plus/1.0.2-beta.65/theme-chalk/index.min.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: [],
onPage: 25,
page: 0,
pages: 0,
loading: false,
},
mutations: {
setLoading: (state, loading) => state.loading = loading,
setPokemons: (state, { pokemons, pages, page }) =>
Object.assign(state, { pokemons, pages, page }),
},
actions: {
async fetchPokemons({ state, commit }, page = 1) {
commit('setLoading', true);
try {
const searchParams = new URLSearchParams({
offset: (page - 1) * state.onPage,
limit: state.onPage,
});
const url = `https://pokeapi.co/api/v2/pokemon?${searchParams}`;
const data = await fetch(url).then(r => r.json());
commit('setPokemons', {
page,
pages: Math.ceil(data.count / state.onPage),
pokemons: data.results,
});
} catch (e) {
console.error(e);
}
commit('setLoading', false);
},
},
});
Vue.createApp({
computed: {
currentPage: {
get() {
return this.$store.state.page;
},
set(page) {
this.$store.dispatch('fetchPokemons', page);
},
},
},
created() {
this.currentPage = 1;
},
})
.use(store)
.use(ElementPlus)
.mount('#app');