2025.01.18 - [2024 회사 프로젝트] - 컴포넌트 분리하기
2025.02.14 - [2024 회사 프로젝트] - 객체 안에 배열 안에 객체가 있는 데이터에.. 타입스크립트를 곁들인..1에 이은
2번째 포스팅이다!
이로 인해 내가 얼마나 무지했는지를 알게되어 버렸다..!
우선 화면에서 서버그룹 이름과 서버그룹을 클릭했을 때 하위서버들을 표현하는 팝업까지는 연결이 되었고, 이제 데이터를 받아와서 데이터를 표현해 주는 것을 고민해야 했다.
📌 화면 구현 계획
- 타입스크립트 인터페이스 정의 → 데이터 구조 명확화
- store 정의 → 서버 상태 및 API 통신
- vue 파일 작성 → 서버 그룹의 상태값 표현 + 팝업 내 데이터 표현
1️⃣ 데이터 구조를 명확하게 표현하기 위한 타입스크립트 인터페이스 정의
📝 ServerVO (각 서버의 개별 정보)
각 서버 그룹에 속하는 서버 개별 정보를 담는 객체이다.
export default interface ServerVO {
seq: number;
status: boolean | string;
date: string;
server_info: {
seq: number;
name: string;
type: string;
server_address: string;
check_interval_sec: number;
};
}
📝 ServerGroupVO (서버 그룹 정보)
ServerVO를 기반으로, 서버 그룹(server1~server5)을 배열로 관리하는 객체이다.
import ServerVO from '@/types/ServerVO';
export default interface ServerGroup {
server1: ServerVO[];
server2: ServerVO[];
server3: ServerVO[];
server4: ServerVO[];
server5: ServerVO[];
}
2️⃣ 서버와 통신할 Store 정의 (Pinia 사용)
위에서 정의한 ServerGroupVO와 ServerVO를 사용하여 서버 그룹의 상태와 하위 서버 리스트의 상태를 관리했다.
export const useServerStore = defineStore({
id: 'useServerStore',
state: () => ({
/** 서버 그룹 상태 */
server: {} as ServerGroupVO,
/** 하위 서버 리스트 */
serverDetail: {} as ServerVO,
}),
actions: {
// 서버 그룹 상태 조회
async getServerStatus() {
try {
const res = await httpHelperV2()
.get(API.SERVER);
this.server = res.data.data;
} catch (e) {
console.error(e);
}
},
// 특정 서버 그룹의 하위 서버 목록 조회
async getDetailServerStatus(type: string) {
try {
const res = await httpHelperV2().get(`${API.SERVER}/${type}`);
this.serverDetail = res.data.data.map(server => ({
...server,
date: new Date(server.date).toLocaleString(), // 날짜 변환
status: server.status ? "Success" : "Fail"
}));
} catch (e) {
console.error(e);
}
},
},
🚨 타입스크립트 오류 경험
- server를 배열로 정의했는데(server : [] as serverGroupVO), 실제 API 응답은 단일 객체였다.
- API 응답 구조를 정확히 이해하지 못해 데이터를 제대로 표현할 수 없었음.(각각의 서버 그룹을 단일 객체로 받는 구조였다.)
- 객체와 배열 구조를 올바르게 파악하는 것이 중요함을 깨달았다.
3️⃣ Vue 파일 정의
store에서 server와 serverDetail의 값을 가지고 와서, 내가 원하는 대로 화면에 뿌려 보겠다.
그리고 2025.01.18 - [2024 회사 프로젝트] - 컴포넌트 분리하기 이전 글에서 언급했던 바와 같이,부모 컴포넌트에서 자식 컴포넌트의 함수를 호출해서 사용해야 하기 때문에defineExpose()를 이용했다.
<template>
<div
v-for="(serverGroupItem, index) in serverGroups"
:key="index"
@click="openServerDetail(serverGroupItem.key)"
>
<h2>{{ serverGroupItem.title }}</h2>
<div>
<span
v-bind="getStatusProps(serverGroupItem.key)"
v-text="getStatusProps(serverGroupItem.key).title"
></span>
<q-icon v-bind="getStatusProps(serverGroupItem.key)" />
</div>
</div>
</template>
<script setup lang="ts">
import serverDetail from "@/components/ServerDetail.vue";
const serverGroups = ref([
{ title: "server1", key: "server1" },
{ title: "server2", key: "server2" },
{ title: "server3", key: "server3" },
{ title: "server4", key: "server4" },
{ title: "server5", key: "server5" },
]);
const openServerDetail = (type: string) => {
dialog.open({
component: serverDetail,
componentProps: { type },
});
};
const serverStore = useServerStore();
const { server } = storeToRefs(serverStore);
const status = computed(() => {
const server1 = server.value.server1 || [];
const server2 = server.value.server2 || [];
const server3 = server.value.server3 || [];
const server4 = server.value.server4 || [];
const server5 = server.value.server5 || [];
return {
server1,
server2,
server3,
server4,
server5,
};
});
const getStatusProps = (key) => {
const statusArray = status.value[key] || [];
const hasError = statusArray.some((item) => item.status === false);
if (hasError) {
return {
name: 'report',
color: 'red',
size: '24px',
title: '장애',
};
} else {
return {
name: 'lock',
color: 'primary',
size: '24px',
title: '정상',
};
}
};
const loadServerStatus = async () => {
try {
await serverStore.getServerStatus();
} catch (e) {
notify.error('서버 상태를 불러오는데 실패했습니다.');
}
};
defineExpose({
loadServerStatus,
});
</script>
✅ 결과
- 서버 그룹별로 상태를 확인할 수 있다.
- 데이터 구조를 명확히 이해하고, 타입스크립트를 활용하여 오류를 방지
🔥 배운 점
- 객체와 배열의 구조를 정확히 파악하는 것이 중요함!
- 타입스크립트를 활용해 API 응답을 올바르게 정의해야 함!
📢 다음 포스팅에서는 서버 그룹을 클릭했을 때 하위 서버의 값을 제대로 가져오는지도 확인해 보겠다!!
'2024 회사 프로젝트' 카테고리의 다른 글
FE개발자의 Fast API와 SQL alchemy를 이용한 BE 도전기 (0) | 2025.03.01 |
---|---|
객체 안에 배열 안에 객체가 있는 데이터에.. 타입스크립트를 곁들인..3 (0) | 2025.02.22 |
객체 안에 배열 안에 객체가 있는 데이터에.. 타입스크립트를 곁들인..1 (0) | 2025.02.14 |
컴포넌트 분리하기 (1) | 2025.01.18 |
엑셀 다운로드 기능 FE에서 해결하기 (1) | 2025.01.11 |