728x90
반응형
<template>
<div class="pagination">
스크롤 페이지네이션
<li v-for="item in dataList" :key="item.id">{{ item }}</li>
</div>
</template>
<script>
import { onMounted, reactive } from 'vue';
import { paging } from '@/composables/paging';
import { useStore } from 'vuex';
export default {
setup() {
// page 10개씩 api 찌를 수 있는 상황일시,
// pageNumb 0 ~ 숫자 올라감.
const pageNationData = [{
id: 0,
data: '제목1',
contents: '내용',
}, {
id: 1,
data: '제목2',
contents: '내용',
},{
id: 2,
data: '제목3',
contents: '내용',
},{
id: 3,
data: '제목4',
contents: '내용',
}
,{
id: 4,
data: '제목5',
contents: '내용',
}
,{
id: 5,
data: '제목6',
contents: '내용',
}
,{
id: 6,
data: '제목7',
contents: '내용',
}
,{
id: 7,
data: '제목8',
contents: '내용',
}
,{
id: 8,
data: '제목9',
contents: '내용',
}
,{
id: 9,
data: '제목10',
contents: '내용',
}]
const pageNationData2 = [
{
id: 10,
data: '제목11',
contents: '내용',
},
{
id: 11,
data: '제목12',
contents: '내용',
},
{
id: 12,
data: '제목13',
contents: '내용',
}
]
const total = 13;
const store = useStore();
const tabMenuStatus = store.state.tabMenuStatus;
let pageNo = reactive(0);
let pageSize = reactive(10);
let dataList = reactive([]);
// 스크롤
const moreSearch = () => {
pageNo = pageNo + 1;
if (pageNo > 0) {
tabMenuStatus.moreSearchYn = true;
test();
}
console.log(pageNo, 'pageNo');
};
const { handleScroll } = paging(moreSearch);
const test = () => {
console.log(pageNationData.length);
if (pageNo == 0) {
for(let i = 0; i < pageSize; i ++) {
dataList.push(pageNationData[i]);
}
// pageNo 0보다 크고 총 개수 범위에만 걸리게.
} else if (pageNo > 0 && dataList.length < total + 1) {
for(let i = 0; i < pageNationData2.length; i ++) {
dataList.push(pageNationData2[i]);
}
tabMenuStatus.moreSearchYn = false;
return;
} else {
tabMenuStatus.moreSearchYn = false;
return;
}
}
try {
document.querySelector('.pagination').removeEventListener('scroll', handleScroll);
// eslint-disable-next-line no-empty
} catch (ignore) {}
onMounted(()=>{
test();
document.querySelector('.pagination').addEventListener('scroll', handleScroll);
})
return {total, pageNationData, pageNationData2, tabMenuStatus, pageNo, pageSize, handleScroll, dataList }
}
}
</script>
<style scoped>
.pagination {
height: 75px;
overflow: auto;
}
</style>
폴더 구조
src> composables > paging.js
import { useStore } from 'vuex';
export const paging = callback => {
const store = useStore();
const handleScroll = event => {
let scrollTop = Math.ceil(event.target.scrollTop);
let innerHeight = Math.ceil(event.target.clientHeight);
let scrollHeight = Math.ceil(event.target.scrollHeight);
if (scrollTop + innerHeight >= scrollHeight && store.state.tabMenuStatus.moreSearchYn) {
store.state.tabMenuStatus.moreSearchYn = false;
callback();
}
};
return {
handleScroll,
};
};
src > store > index.js
/*****************************************************************************
* PROJECT NAME : SKT 모바일지갑
* SUBSYSTEM NAME : 모바일지갑 웹뷰
* FILE NAME : index.js
* DESCRIPTION : VUEX 스토어 파일
*
* VERSION NO author date content -> info
* ----------------------------------------------------------------------------
* 1.0 InJae Yeo 2021-09-27 init
*****************************************************************************/
import { createStore } from 'vuex';
const files = require.context('@/store/modules/', true, /\.js$/);
const modules = {};
files.keys().forEach(key => {
if (key === './index.js') return;
modules[
key
.replace(/^.*[\\/]/, '') // filename only
.replace(/(\.\/|\.js)/g, '') // .js only
.replace(/(-)/g, '_') // change - to _
] = files(key).default;
});
export default createStore({
state() {
return {
};
},
mutations: {
},
actions: {},
modules: {
...modules,
},
});
src > store > modules > tabMenuStatus.js
const state = {
moreSearchYn: true,
};
export default {
state,
};
728x90
반응형
'개발 > script&vue&react' 카테고리의 다른 글
null vs undefined 차이 (0) | 2024.12.31 |
---|---|
데이터 타입의 종류 (0) | 2024.12.30 |
[vue.js] v-if, v-show 차이점, 사용해야 할 타이밍 (0) | 2024.12.28 |