본문 바로가기
카테고리 없음

Vue.js 입문 (프로젝트 구조, 라우터, 네비게이션 가드)

by ricepuppy9733 2026. 6. 23.

Vue.js를 처음 접했을 때 솔직히 "이걸 왜 배워야 하지?"라는 생각이 먼저 들었습니다. HTML 파일 하나로 다 짜면 되는 거 아닌가 싶었는데, 직접 써봤더니 그 생각이 완전히 바뀌었습니다. 파일을 컴포넌트 단위로 쪼개서 조립하는 방식이 이렇게 편할 줄은 예상 밖이었습니다. 이 글은 Vue.js 프로젝트를 처음 만들면서 겪은 것들을 구조, 라우터, 그리고 네비게이션 가드 순으로 정리한 경험담입니다.

vue 사용법

Vue.js 프로젝트 구조를 처음 열었을 때

npm create vue@latest 명령어 하나로 프로젝트를 생성하면, 폴더와 파일이 한꺼번에 쏟아집니다. 처음에는 뭘 건드려야 할지 몰라서 한참 멍하니 쳐다봤습니다. 제가 직접 써봤을 때 가장 먼저 느낀 건 "건드릴 파일이 생각보다 적다"는 점이었습니다.

실질적으로 개발자가 손대는 건 src 폴더 안입니다. 나머지 node_modules나 .vscode 폴더는 자동으로 생성되는 것들이라 신경 쓸 필요가 없습니다. 특히 node_modules는 용량이 크기 때문에 프로젝트를 공유할 때 반드시 삭제하고 넘겨야 합니다. 받는 쪽에서 npm i 명령어를 한 번만 치면 다시 생성됩니다.

Vue.js의 핵심 개념 중 하나가 바로 가상 DOM(Virtual DOM)입니다. 여기서 가상 DOM이란, 실제 브라우저 화면을 직접 건드리지 않고 메모리 안에 별도의 가상 화면을 만들어 두었다가 변경된 부분만 골라 실제 화면에 반영하는 기술입니다. 기존 방식은 HTML 코드 전체가 파싱(parsing) → 스타일 계산 → 레이아웃 → 페인트 → 컴포지트라는 긴 과정을 매번 거쳐야 했는데, 가상 DOM을 쓰면 바뀐 부분만 처리하니 렌더링 속도가 눈에 띄게 빨라집니다.

그리고 Vue.js에서 빠질 수 없는 개념이 선언적 렌더링(Declarative Rendering)입니다. 선언적 렌더링이란 "화면에 이것을 보여줘라"라고 결과 상태만 선언하면 Vue가 알아서 DOM을 맞춰주는 방식입니다. 개발자가 DOM을 직접 조작하는 명령형 방식과 달리, 데이터 상태(State)만 바꾸면 화면이 자동으로 따라옵니다. 처음에는 그게 왜 편한지 몰랐는데, 실제로 코드를 짜다 보면 document.querySelector 같은 코드를 쓰지 않아도 된다는 게 얼마나 큰 차이인지 느껴집니다.

프로젝트 생성 시 제가 추천하는 선택 항목은 다음과 같습니다.

  • Router: 여러 페이지처럼 보이게 만드는 기능으로, 거의 모든 프로젝트에 필요합니다.
  • Pinia: 컴포넌트 간 데이터를 공유할 때 쓰는 전역 상태 관리 도구입니다.
  • Prettier: 코드 들여쓰기와 정렬을 자동으로 맞춰줘서 협업 시 특히 유용합니다.

TypeScript나 ESLint는 입문 단계에서는 오히려 발목을 잡는 경우가 있어서 저는 처음에 과감히 빼고 시작했습니다.

라우터로 SPA를 구현하는 방식

Vue.js 라우터를 처음 배울 때 가장 헷갈렸던 부분이 바로 SPA 개념이었습니다. SPA(Single Page Application)란, 말 그대로 HTML 파일이 단 하나인데 여러 페이지가 있는 것처럼 동작하는 애플리케이션입니다. 사용자가 메뉴를 클릭하면 실제로 새 페이지를 받아오는 게 아니라, 화면 안의 특정 영역만 다른 컴포넌트로 교체되는 방식입니다.

이 동작의 핵심이 RouterView 태그입니다. App.vue 안에 RouterView를 넣어두면, 라우터 설정 파일인 router/index.js에서 URL과 컴포넌트를 매핑해 둔 대로 해당 자리에 컴포넌트가 끼워집니다. Header와 Footer는 그대로 유지되고 RouterView 부분만 바뀌는 구조라서, 화면이 깜박이지 않고 빠르게 전환됩니다. 제 경험상 이 구조를 이해하고 나면 Vue 전체 흐름이 한 번에 잡힙니다.

라우터 안에 라우터를 넣는 중첩 라우트(Nested Route)도 실무에서 자주 쓰입니다. 예를 들어 /product 경로 아래 /product/list와 /product/detail을 두고 싶을 때, children 속성으로 하위 라우트를 정의하면 됩니다. 이때 하위 경로에는 앞에 슬래시(/)를 붙이지 않는다는 점이 처음엔 헷갈렸는데, 붙이면 절대 경로로 인식되어서 중첩이 깨집니다.

또 라우터 경로에 이름을 붙이는 Named Route 방식도 꼭 익혀두시길 권합니다. 경로 문자열 대신 이름으로 이동하면, 나중에 URL을 바꿔도 RouterLink를 수정할 필요가 없습니다. 경로가 10개, 20개 넘어가기 시작하면 이게 얼마나 편한지 바로 느껴집니다.

한편 모든 컴포넌트를 처음부터 한꺼번에 불러오지 않고 필요할 때만 불러오는 Lazy Loading 방식도 중요합니다. Lazy Loading이란 사용자가 실제로 해당 페이지를 방문하는 순간에만 그 컴포넌트 파일을 다운로드받게 하는 기법입니다. import 구문을 화살표 함수로 감싸는 것만으로 적용되는데, 페이지 수가 늘어날수록 초기 로딩 시간을 줄여주는 효과가 있습니다. 자바스크립트 번들(Bundle) 크기를 줄이는 데도 직접적으로 기여합니다. 여기서 번들이란, 여러 개의 JavaScript 파일을 하나 또는 몇 개의 파일로 합쳐주는 결과물을 말하며, Vue.js는 기본적으로 Vite라는 번들러를 사용합니다(출처: Vite 공식 문서).

네비게이션 가드로 접근 제어 구현하기

라우터를 어느 정도 익히고 나면 자연스럽게 "로그인한 사람만 볼 수 있는 페이지는 어떻게 만들지?"라는 질문이 생깁니다. 저도 그 시점에서 네비게이션 가드를 배우게 됐는데, 생각보다 간결해서 오히려 놀랐습니다.

네비게이션 가드(Navigation Guard)란, 라우터가 페이지를 이동하기 직전에 특정 코드를 실행해서 이동을 허용하거나 차단하거나 다른 경로로 보낼 수 있는 기능입니다. router.beforeEach 함수가 그 역할을 합니다. 이 함수는 어떤 페이지로 이동하든 항상 먼저 실행되기 때문에, 전체 인증 로직을 한 곳에 모아둘 수 있습니다.

실제로 적용해 보면 각 라우트 설정에 meta 속성을 붙이는 방식이 가장 깔끔했습니다. meta: { requiresAuth: true }처럼 로그인이 필요한 페이지에 표시를 해두고, beforeEach에서 to.meta.requiresAuth 값을 확인해서 로그인 여부에 따라 분기하는 패턴입니다. 이렇게 하면 새로운 페이지를 추가할 때마다 가드 코드를 건드릴 필요 없이 meta 값만 설정하면 됩니다.

프론트엔드 개발에서 인증 처리는 보안의 핵심 요소 중 하나입니다. 다만 클라이언트 사이드에서의 라우팅 가드는 사용자 경험(UX)을 위한 것이지, 서버 측 인증을 대체하지는 않는다는 점을 반드시 기억해야 합니다. 실제 데이터 보호는 반드시 백엔드 API 단에서 토큰 검증 등의 처리가 병행되어야 합니다(출처: OWASP - Authentication Cheat Sheet).

네비게이션 가드를 활용할 때 실무적으로 유용한 패턴을 정리하면 다음과 같습니다.

  • 로그인 여부 확인: meta.requiresAuth로 인증이 필요한 페이지를 표시하고, 미로그인 시 로그인 페이지로 리다이렉트합니다.
  • 이미 로그인한 사용자 처리: 로그인 페이지에 다시 접근하면 메인 페이지로 되돌려 보내는 로직도 beforeEach에서 함께 처리할 수 있습니다.
  • 권한 레벨 구분: meta.role 같은 속성을 추가하면 관리자 전용 페이지와 일반 사용자 페이지를 분리하는 것도 동일한 구조로 확장할 수 있습니다.

Vue.js를 처음 배울 때 컴포넌트, 라우터, 네비게이션 가드 이 세 가지가 어떻게 연결되는지 감이 잡히지 않아서 같은 코드를 여러 번 쳐봤습니다. 그런데 직접 프로젝트를 생성하고, 파일을 지워가며, 라우터 설정을 하나씩 추가해보니 어느 순간 전체 흐름이 눈에 들어왔습니다. 개념 설명만 읽는 것보다 실제로 파일을 만들고 URL을 바꿔보는 게 압도적으로 빠릅니다. 다음 단계로는 Pinia를 이용한 전역 상태 관리를 익혀두면, 컴포넌트 간 데이터 전달 문제를 훨씬 깔끔하게 해결할 수 있습니다.


참고: https://dltldnr2563.tistory.com/entry/%EC%BD%94%EB%94%A9%EA%B3%B5%EB%B6%8020250701-Vuejs-router-Lazy-Loading-%EB%84%A4%EB%B9%84%EA%B2%8C%EC%9D%B4%EC%85%98-%EA%B0%80%EB%93%9C


소개 및 문의 · 개인정보처리방침 · 면책조항

© 2026 자동식단생성 연관 블로그