SKALA / / 2026. 2. 9. 17:41

Front-framework: Vue.js - Stock Market

Vue 3 Composition API와 커스텀 API 통신 모듈을 활용하여 구축한 SKALA Stock Market의 핵심 구현 내용 정리

 

📌 프로젝트 개요

시스템 구성

기술 스택

Frontend: Vue 3 (Composition API), Vite
UI: Bootstrap 5, Bootstrap Icons
상태 관리: Reactive, Ref, SessionStorage
통신: Custom API Wrapper (Axios 기반)

 

데이터 흐름 요약 (Data Flow)

Vue.js의 반응형 시스템(Reactivity System)을 기반으로 한 전체 데이터 흐름은 다음과 같다.

  1. 사용자 입력: v-model을 통해 사용자의 입력값이 ref 또는 reactive 변수에 실시간으로 반영된다.
  2. 자동 감지: 변수가 변경되면 watch가 이를 감지하여 API를 호출하거나, computed가 계산된 값을 즉시 업데이트한다.
  3. 비동기 통신: apiCall 모듈을 통해 서버로 데이터를 전송하거나 수신한다.
  4. 상태 업데이트: 서버로부터 받은 응답 데이터(Body)를 다시 반응형 변수에 할당한다.
  5. 화면 갱신: Vue의 가상 DOM이 변경된 상태를 감지하여 브라우저 화면을 자동으로 재렌더링한다.

 

핵심 API 엔드포인트 정리

프론트엔드와 백엔드 간의 약속된 인터페이스 명세는 다음과 같다. 모든 요청은 공통 응답 포맷을 준수한다.

기능 Method URL 용도
로그인 POST /api/players/login 사용자 인증 및 세션 생성
회원가입 POST /api/players 신규 플레이어 계정 생성
주식 목록 GET /api/stocks/list?offset=0&count=10 페이징을 적용한 주식 데이터 조회
주식 추가 POST /api/stocks 관리자에 의한 신규 종목 등록
플레이어 정보 GET /api/players/:playerId 특정 플레이어의 잔고 및 보유 주식 조회
주식 구매 POST /api/players/buy 플레이어 자산을 사용한 매수 트랜잭션
주식 판매 POST /api/players/sell 보유 주식 매도 및 자산 최신화

 


1️⃣ 로그인 프로세스 (StartMain.vue)

사용자 인증 및 세션 관리의 시작점이다.

  • 데이터 바인딩: v-model을 통해 사용자가 입력한 playerId, playerPassword를 실시간으로 저장한다.
  • 로그인 로직:
    1. 로그인 버튼 클릭 시 login() 함수를 실행하여 apiCall.post()로 서버에 요청을 보낸다.
    2. 성공 시: storePlayer()로 사용자 정보를 저장하고, router.push('/stock')을 통해 메인 페이지로 이동한다.
    3. 실패 시: notifyInfo()로 에러 메시지를 표시하며, 신규 사용자인 경우 회원가입 모드(isNewPlayer = true)로 전환한다.

 

🔑 주요 기술 구현 포인트

StartMain: 사용자 인증 및 상태 처리

  • ref를 활용한 반응형 상태 관리: 단일 데이터 값인 playerId 등은 ref로 선언하여 관리한다. 스크립트 단에서는 .value로 접근하며, 템플릿에서는 자동으로 언랩핑되어 편리하게 사용 가능하다.
const playerId = ref('');  // 단일 값 → ref 사용
// 접근 시: playerId.value
// 템플릿에서는 자동으로 언랩핑됨
  • 조건부 렌더링 활용: v-if를 사용하여 로그인과 회원가입 버튼을 교체한다. 이는 v-show와 달리 조건이 맞지 않을 때 DOM에서 요소를 완전히 제거하므로 보안 및 초기 렌더링 최적화에 유리하다.
<button v-if="isNewPlayer">회원가입</button>
<button v-else>로그인</button>
  • 표준 에러 핸들링 패턴: apiCall.Response.SUCCESS 상수를 활용해 응답 결과를 판별하며, 성공과 실패 로직을 명확히 분리하여 사용자 피드백(알림창 등)을 제공한다.
if (response.result === apiCall.Response.SUCCESS) {
  // 성공 로직
} else {
  // 실패 로직 + 사용자 피드백
}

 


2️⃣ 주식 시장 관리 (StockList.vue)

전체 주식 목록을 조회하고 새로운 종목을 추가하는 대시보드다.

  • 자동 데이터 로드: onMounted() 생명주기 훅을 통해 컴포넌트 로딩 시 getStockList()를 자동으로 실행한다.
  • 주요 기능:
    • 목록 표시: 서버에서 가져온 데이터를 table.items에 저장하고, ItemsTable 컴포넌트에 전달하여 화면에 렌더링한다.
    • 주식 추가: InlineInput에 입력된 값을 addStock() 함수를 통해 서버에 POST 요청을 보낸 후, 목록을 새로고침한다.
    • 이벤트 핸들링: 특정 행(Row) 클릭 시 handleRowSelected()가 실행되며, 콜백 함수를 통해 선택된 주식 정보를 PlayerStocks 컴포넌트로 전달한다.
    • 반응형 페이징: 페이지 네비게이터의 변경 사항을 watch()가 감지하여 자동으로 리스트를 동기화한다.

 

🔑 주요 기술 구현 포인트

StockList: 목록 조회 및 페이징 전략

  • reactive 기반 객체 상태 관리: 테이블 헤더나 아이템 목록처럼 구조화된 데이터는 reactive를 사용하여 객체 단위로 관리한다. ref와 달리 .value 없이 속성에 직접 접근할 수 있어 코드가 간결해진다.
const table = reactive({
  headers: [...],
  items: []
});

// 직접 접근 가능 (. value 불필요)
table.items = newData;
  • watch를 활용한 자동 갱신: 페이지 번호(page.current)나 페이지당 개수(page.count)가 변경될 때마다 watch가 이를 감지하여 getStockList()를 재호출한다. 이는 사용자 액션과 데이터 동기화를 연결하는 강력한 도구다.
// 단일 값 감시
watch(() => page.current, getStockList);

// 복합 처리
watch(() => page.count, () => {
  page.current = 1;  // 리셋
  getStockList();    // 재조회
});
  • Offset 기반 페이징: API 규격에 맞춰 현재 페이지 번호에서 1을 뺀 offset 값을 계산하여 전달한다. (예: 1페이지 → offset 0)
// API는 page가 아닌 offset을 받음
queryParams: {
  offset: page.current - 1,  // 0부터 시작
  count: page.count
}
  • 콜백 기반 이벤트 전파: getCallback을 통해 등록된 함수가 있는지 확인 후 실행함으로써, 컴포넌트 간 결합도를 낮추면서도 데이터를 안전하게 전달한다.
// 1. 콜백 가져오기
const callback = getCallback('selectStock');

// 2. 존재 여부 확인 후 실행
if (callback) callback(item);

 


3️⃣ 플레이어 자산 및 거래 (PlayerStocks.vue)

개인 자산을 관리하고 실제 매수/매도 거래가 이루어지는 컴포넌트다.

  • 초기 설정: 로드 시 getPlayerInfo()를 호출하여 잔고와 보유 주식을 조회하며, selectStock 콜백을 등록한다.
  • 거래 흐름:
    1. 주식 선택: StockList에서 주식을 클릭하면 selectStock()이 실행되어 해당 주식 ID가 입력란에 자동 바인딩된다.
    2. 유효성 검사: isFormValid computed 속성이 수량 입력 여부 등을 감지하여 버튼의 활성화 상태를 결정한다.
    3. 거래 실행: 구매(buyPlayerStock) 또는 판매(sellPlayerStock) 버튼 클릭 시 서버 요청을 보낸다.
    4. 상태 갱신: 거래 성공 후 getPlayerInfo()를 재호출하여 잔고와 보유 목록을 즉시 최신화하고 입력란을 초기화한다.

 

🔑 주요 기술 구현 포인트

PlayerStocks: 비즈니스 로직 및 UI 인터랙션

  • computed를 활용한 폼 검증: stockId와 stockQuantity의 입력 여부를 computed로 실시간 감시한다. 이를 버튼의 :disabled 속성에 바인딩하여 잘못된 요청이 서버로 전송되는 것을 원천 차단한다.
const isFormValid = computed(() => {
  return stockId.value !== '' && stockQuantity.value !== '';
});
  • Lifecycle 기반 콜백 등록: onMounted 시점에 콜백을 등록하여 외부 컴포넌트(StockList)로부터 넘어오는 데이터(주식 선택 정보)를 받을 준비를 한다.
onMounted(() => {
  setCallback('selectStock', selectStock);
});
  • 트랜잭션 후 상태 동기화: 주식 매매 성공 시 서버에서 다시 정보를 불러오는 await getPlayerInfo()를 실행한다. 이는 클라이언트의 데이터와 서버의 DB 상태를 일치시키는 핵심 프로세스다. 이후 입력 폼을 초기화하여 다음 거래를 준비한다.

💡 시스템 핵심 요약

구분 주요 기술 및 패턴
상태 관리 v-model 및 로컬 상태를 활용한 실시간 데이터 동기화
통신 구조 Axios 래퍼(apiCall)를 통한 일관된 REST API 처리
컴포넌트 통신 사용자 정의 콜백 패턴을 활용한 컴포넌트 간 데이터 전달
사용자 경험 watch, computed를 활용한 반응형 UI 및 자동 갱신 로직

 

'SKALA' 카테고리의 다른 글

Front-framework: Vue.js  (0) 2026.02.05
HTML, CSS, JavaScript  (0) 2026.02.05
생성형 AI 기초 및 Prompt Engineering  (0) 2026.02.03
Vector Database  (0) 2026.02.02
LLM 모델 이해 및 활용(2)  (0) 2026.02.02
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유