[Vue] 무한 스크롤 예제(직접 구현) (with Vuex)

suhanLee·2022년 7월 7일
0

vue-basic

목록 보기
23/29

ProductList.vue

<template>
	<div v-scroll="scrollDown">
		<v-card
			class="mx-auto"
			outlined
			v-for="(item, index) in $store.state.productList"
			:key="`item.index_${index}`"
		>
			<v-list-item three-line>
				<v-list-item-content>
					<div class="text-overline mb-4">{{ item.brand_nm }}</div>
					<v-list-item-title class="text-h5 mb-1">
						{{ item.product_nm_dp }}
					</v-list-item-title>
					<v-list-item-subtitle>{{ item.cust_prc }}</v-list-item-subtitle>
				</v-list-item-content>

				<v-list-item-avatar tile size="80" color="grey" />
			</v-list-item>

			<v-card-actions>
				<v-btn outlined rounded text> Button </v-btn>
			</v-card-actions>
		</v-card>
		<div v-show="loading" style="text-align: center">
			<v-progress-circular indeterminate color="primary" />
		</div>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				page: 1,
				loading: false,
				isDelay: false,
			};
		},
		methods: {
			async scrollDown() {
				// 화면크기 + scrollY (스크롤 한칸당 +100) >= body의 총 높이
				if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
					console.log('무한스크롤 발생!');
					this.loading = true;
					if (!this.isDelay) {
						this.isDelay = true;

						var formData = new FormData();
						formData.append('currPage', this.page);
						formData.append('pageSize', '10');
						const { data } = await this.$store.dispatch(
							'FETCH_GET_PRODUCT_LIST',
							formData,
						);
						if (data.productPageList.length) {
							console.log(this.page);
							this.page += 1;
							this.$store.commit('SET_PRODUCT_LIST', data.productPageList);
						}
						setTimeout(() => {
							this.isDelay = false;
							this.loading = false;
						}, 5000);

						// this.$store
						// 	.dispatch('FETCH_GET_PRODUCT_LIST', formData)
						// 	.then(({ data }) => {
						// 		if (data.productPageList.length) {
						// 			console.log(this.page);
						// 			this.page += 1;
						// 			this.$store.commit('SET_PRODUCT_LIST', data.productPageList);
						// 		}
						// 		setTimeout(() => {
						// 			this.isDelay = false;
						// 			this.loading = false;
						// 		}, 5000);
						// 	});
					}
					console.log(this.$store.state.productList);
				}
			},
		},
		mounted() {
			this.scrollDown();
		},
	};
</script>

<style></style>

src/api/index.js

import axios from 'axios';
function getProductPageList(payload) {
	return axios
		.post('/api/prd/getProductList', payload)
		.then(res => res);
}
export { getProductPageList };

src/store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
import { getProductPageList } from '@/api/index.js';

Vue.use(Vuex);

export default new Vuex.Store({
	state: {
		productList: [],
	},
	mutations: {
		SET_PRODUCT_LIST(state, payload) {
			//state.productList = [...state.productList, ...payload];
			state.productList = state.productList.concat(payload);
		},
	},
	actions: {
		FETCH_GET_PRODUCT_LIST(context, payload) {
			return getProductPageList(payload).then(res => res);
		},
	},
	modules: {},
});

vue.config.js

module.exports = {
	devServer: {
		overlay: false,
		proxy: {
			'/api': {
				target: process.env.VUE_APP_DEV_API,
				changeOrigin: true,
			},
		},
	},
};

0개의 댓글