usePagination - composition api (vue2)
2022-08-19
이슈 1. 반복 코드 리팩토링
Pagination 컴포넌트를 사용하는 곳에서 공통으로 반복해서 사용하는 코드를 composition api 를 사용하여 개선해보았습니다.
기존 공통 코드
export default Vue.extend({
data: () => ({
pageOptions: {
page: 1,
size: 10,
totalElements: 0,
totalPages: 0,
first: false,
last: false,
},
}),
...
methods: {
async getNotice() {
try {
const response = await notice_api.getNotice(config);
if (response.status === 200) {
const data = response.data.items;
this.pageOptions = {
page: this.pageOptions.page,
size: data.size,
totalElements: data.totalElements,
totalPages: data.totalPages,
first: data.first,
last: data.last,
};
개선 코드
hooks/usePagination.ts
공통으로 사용할 data와 function을 관리
import { reactive } from "@vue/composition-api";
export interface PageType {
page: number;
size: number;
totalElements?: number;
totalPages: number;
first: boolean;
last: boolean;
}
interface ArgType {
size: number;
}
interface ReturnType {
pageOptions: PageType;
setPageOptions: (page: number, response: PageType) => void;
}
// 한번에 보여줄 리스트 갯수(size)를 argument로 전달하고, 기본값은 10. optional로 생략가능
export const usePagination = (arg?: ArgType): ReturnType => {
const pageOptions = reactive<PageType>({
page: 1,
size: arg?.size || 10,
totalElements: 0,
totalPages: 0,
first: false,
last: false,
});
const setPageOptions = (page: number, response: PageType) => {
pageOptions.page = page;
pageOptions.size = response.size;
pageOptions.totalElements = response.totalElements;
pageOptions.totalPages = response.totalPages;
pageOptions.first = response.first;
pageOptions.last = response.last;
};
return { pageOptions, setPageOptions };
};
사용 예
import { usePagination } from "@/hooks/usePagination";
export default Vue.extend({ // 이슈 2. 에서 수정!
setup() {
const { pageOptions, setPageOptions } = usePagination();
return { pageOptions, setPageOptions };
},
...
methods: {
async getNotice() {
try {
const response = await notice_api.getNotice(config);
if (response.status === 200) {
const data = response.data.items;
this.setPageOptions(this.pageOptions.page, data);
한번에 보여줄 리스트 갯수(size) 조절시 예
const { pageOptions, setPageOptions } = usePagination({size: 5});
이슈 2. typescript: property does not exist on type 'object & record<never, any>
setup() 에서 return한 데이터를
<template>
코드 내에서 사용시 기능은 모두 동작하였으나, 위와 같은 빨간줄 typescript 경고가 생겼습니다.테스트해보니 chrome vue extention 에서도 data로 잘 들어오고 있고, build 에러도 뜨지 않았지만, 찾아보니 아래와 같이 수정을 하면 typescript 경고가 발생하지 않았습니다.
참고 자료
해결 코드
<template>
...
// 이제 빨간 경고 줄이 생기지 않습니다.
<Pagination :pageOptions="pageOptions" @click="onClickPage" />
</template>
<script lang="ts">
import { defineComponent } from "@vue/composition-api";
export default defineComponent({
setup() {
const { pageOptions, setPageOptions } = usePagination();
return { pageOptions, setPageOptions };
},
Pagination 2개 이상 사용시 코드 비교
composition api 사용 전
data: () => ({
pageOptionsHistory: {
page: 1,
size: 5,
totalElements: 0,
totalPages: 0,
first: false,
last: false,
},
pageOptionsGroup: {
page: 1,
size: 5,
totalElements: 0,
totalPages: 0,
first: false,
last: false,
},
}),
...
methods: {
async getHistory() {
try {
const response = await notice_api.getHistory(config);
if (response.status === 200) {
const data = response.data.items;
this.pageOptionsHistory = {
page: this.pageOptionsHistory.page,
size: data.size,
totalElements: data.totalElements,
totalPages: data.totalPages,
first: data.first,
last: data.last,
};
...
async getGroup() {
try {
const response = await notice_api.getGroup(config);
if (response.status === 200) {
const data = response.data.items;
this.pageOptionsGroup = {
page: this.pageOptionsGroup.page,
size: data.size,
totalElements: data.totalElements,
totalPages: data.totalPages,
first: data.first,
last: data.last,
};
composition api 사용 후
setup() {
const {
pageOptions: pageOptionsHistory,
setPageOptions: setPageOptionsHistory,
} = usePagination({ size: 5 });
const {
pageOptions: pageOptionsGroup,
setPageOptions: setPageOptionsGroup,
} = usePagination({ size: 5 });
return {
pageOptionsHistory,
setPageOptionsHistory,
pageOptionsGroup,
setPageOptionsGroup,
};
},
...
methods: {
async getHistory() {
try {
const response = await notice_api.getHistory(config);
if (response.status === 200) {
const data = response.data.items;
this.setPageOptionsHistory(this.pageOptionsHistory.page, data);
...
async getGroup() {
try {
const response = await notice_api.getGroup(config);
if (response.status === 200) {
const data = response.data.items;
this.setPageOptionsGroup(this.pageOptionsGroup.page, data);
이렇게 코드의 재사용성을 높여 반복 코드를 줄일 수 있습니다.
Last updated
Was this helpful?