export default {
state: {
results: [],
totalPhotos: 0,
perPage: 15,
page: 1
},
getters: {
allPhoto(state) {
return state.results
}
},
mutations: {
updatePhotos( state, results ) {
state.results = results
}
},
actions: {
async fetchCurrency( ctx, page ) {
const options = {
params: {
page: page,
per_page: this.perPage
}
}
const url = 'https://jsonplaceholder.typicode.com/photos'
const res = await fetch( url, options )
let results = await res.json()
console.log( results )
ctx.commit( 'updatePhotos', results )
}
}
}
<template>
<div>
<div class="flex">
<div class="container-block">
<div class="name" v-for="result in allPhoto" :key="result.id" >
<img class="img" :src="result.url" />
</div>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from "vuex"
export default {
computed: mapGetters( [ 'allPhoto' ] ),
async mounted() {
this.$store.dispatch( 'fetchCurrency' )
},
}
</script>
<template>
<div>
<app__loader v-if="loading" />
<div v-else >
<app__photo/>
<div class="wrapper">
<div class="body">
<button type="button" class="btn" > {{ previous }} </button>
<button type="button" class="btn" > {{ next }} </button>
</div>
</div>
</div>
</div>
</template>
<script>
import app__loader from '../under_components/Loader'
import app__photo from '../under_components/Photo__post'
export default {
components: { app__loader, app__photo },
data() {
return {
loading: true,
carrency: null,
previous: '<',
next: '>'
}
},
async mounted() {
this.carrency = await this.$store.dispatch( 'fetchCurrency' )
this.loading = false
},
}
</script>
state: {
page: 0,
perPage: 5,
total: 0,
posts: [],
loading: false,
},
getters: {
numPages: state => Math.ceil(state.total / state.perPage),
},
mutations: {
updateLoading: (state, loading) => state.loading = loading,
updatePosts: (state, { posts, total, page }) => Object.assign(state, { posts, total, page }),
},
actions: {
async fetchPosts({ state, commit }, page) {
commit('updateLoading', true);
const start = (page - 1) * state.perPage;
const end = page * state.perPage;
const url = `https://jsonplaceholder.typicode.com/posts?_start=${start}&_end=${end}`;
try {
const response = await fetch(url);
const posts = await response.json();
const total = response.headers.get('x-total-count');
commit('updatePosts', { posts, total, page });
} catch (e) {
console.error(e);
}
commit('updateLoading', false);
},
},
props: [ 'page', 'numPages' ],
methods: {
goTo(page) {
this.$emit('paginate', page);
},
next(step) {
this.goTo(this.page + step);
},
},
computed: {
isFirst() {
return this.page <= 1;
},
isLast() {
return this.page >= this.numPages;
},
},
<button @click="goTo(1)" :disabled="isFirst"><<</button>
<button @click="next(-1)" :disabled="isFirst"><</button>
{{ page }} / {{ numPages }}
<button @click="next(+1)" :disabled="isLast">></button>
<button @click="goTo(numPages)" :disabled="isLast">>></button>
v-model
:model: {
prop: 'page',
event: 'paginate',
},
computed: {
page: {
get() {
return this.$store.state.page;
},
set(page) {
this.$store.dispatch('fetchPosts', page);
},
},
<компонент-пагинации
v-model="page"
:num-pages="$store.getters.numPages"
/>
created() {
this.page = 1;
},
<div v-if="$store.state.loading">данные загружаются, ждите</div>
<компонент-для-отображения-данных v-else :данные="$store.state.posts" />