-
4장. 상용 웹 앱을 개발하기 위한 필수 기술들 - 라우터 & HTTP 통신 - 1개발 공부/Do it! Vue.js 입문 2025. 5. 23. 09:00반응형
4장 - 1
04-1 뷰 라우터
<라우팅이란?>
- 라우터(Router)를 이해하기 위해서는 먼저 라우팅(Routing)이 무엇인지 알아야 한다.
- 라우팅이란 웹 페이지 간의 이동 방법을 말하며, 현대 웹 앱 형태 중 하나인 SPA(Single Page Application)에서 주로 사용하고 있다.
- SPA : 페이지를 이동할 때마다 서버에 웹 페이지를 요청하여 새로 갱신하는 것이 아니라 미리 해당 페이지들을 받아 놓고 페이지 이동 시에 클라이언트의 라우팅을 이용하여 화면을 갱신하는 패턴을 적용한 애플리케이션
- 일반적으로 브라우저에서 웹 페이지를 요청하면 서버에서 응답을 받아 웹 페이지를 다시 사용자에게 돌려주는 시간 동안 화면 상에 깜빡거림 현상이 나타난다.
- 이러한 부분들을 라우팅으로 처리하면 깜빡거림 없이 화면을 매끄럽게 전환할 수 있을 뿐만 아니라 더 빠르게 화면을 조작할 수 있어 사용자 경험이 향상된다.
- 뷰뿐만 아니라 리액트와 앵귤러 모두 라우팅을 이용하여 화면을 전환하고 있으며, 일반 HTML 파일들로도 라우팅 자바스크립트 라이브러리를 이용하여 구현할 수 있다.
GitHub - tildeio/router.js
Contribute to tildeio/router.js development by creating an account on GitHub.
github.com
GitHub - krasimir/navigo: A simple vanilla JavaScript router.
A simple vanilla JavaScript router. Contribute to krasimir/navigo development by creating an account on GitHub.
github.com
<뷰 라우터>
- 뷰 라우터는 뷰에서 라우팅 기능을 구현할 수 있도록 지원하는 공식 라이브러리이다.
- 뷰 라우터를 이용하여 뷰로 만든 페이지 간에 자유롭게 이동할 수 있다.
- 뷰 라우터를 구현할 때 필요한 특수 태그와 기능은 다음과 같다.
태그 설명 <router-link to="URL 값"> 페이지 이동 태그. 화면에서는 <a>로 표시되며 클릭하면 to에 지정한 URL로 이동한다. <router-view> 페이지 표시 태그. 변경되는 URL에 따라 해당 컴포넌트를 뿌려주는 영역이다. - 뷰 라우터를 이용하여 페이지를 이동하는 예제를 살펴보자.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue Router Sample</title> </head> <body> <div id="app"> <h1>뷰 라우터 예제</h1> <p> <router-link to="/main">Main 컴포넌트로 이동</router-link> <!-- 1. URL 값을 변경하는 태그 --> <router-link to="/login">Login 컴포넌트로 이동</router-link> </p> <router-view></router-view> <!-- 2. URL 값에 따라 갱신되는 화면 영역 --> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script> <!-- 라우터 CDN(Content delivery network 또는 content distribution network) 추가 --> <script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script> <script> var Main = { template: '<div>main</div>' }; // 3. Main, Login 컴포넌트 정의 var Login = { template: '<div>login</div>' }; var routes = [ // 4. 각 URL에 맞춰 표시할 컴포넌트 지정 { path: '/main', component: Main }, { path: '/login', component: Login } ]; var router = new VueRouter({ // 5. 뷰 라우터 정의 mode: 'history', routes }); var app = new Vue({ // 6. 뷰 인스턴스에 라우터 추가 router }).$mount('#app'); </script> </body> </html>
- 위 코드는 뷰 기본 라우팅 방식을 이용하여 페이지를 전환하는 예제이다.
- 라우팅을 하기 위해 코드가 어떻게 동작하는지 살펴보자.
- 각 <router-link>는 화면 상에서 [Main 컴포넌트로 이동], [Login 컴포넌트로 이동]이라는 <a> 버튼 태그로 변환되어 표시된다. 각 버튼을 클릭하면 to=""에 정의된 텍스트 값이 브라우저 URL 끝에 추가된다. 여기서는 /main과 /login의 2개의 URL이 끝에 추가된다.
- <router-view>는 갱신된 URL에 해당하는 화면을 보여주는 영역이다. <router-view>에 나타낼 화면은 <script>에서 정의한다.
- Main과 Login 컴포넌트에는 template 속성으로 각 컴포넌트를 구분할 수 있는 정도의 간단한 HTML 코드를 정의한다.
- routes 변수에는 URL 값이 /main일 때 Main 컴포넌트를, /login일 때 Login 컴포넌트를 표시하도록 정의한다.
- router 변수에는 뷰 라우터를 하나 생성하고, routes를 삽입해 URL에 따라 화면이 전환될 수 있게 정의한다.
- 마지막 부분은 새 인스턴스를 생성하고 라우터의 정보가 담긴 router를 추가하는 코드이다. 여기서 .$mount( )는 el 속성과 같이 인스턴스를 화면에 붙여주는 역할을 한다.
- 인스턴스를 생성할 때 el 속성을 넣지 않았더라도 생성하고 나서 $mount( )를 이용하면 강제로 인스턴스를 화면에 붙일 수가 있다. 참고로, 뷰 라우터의 공식 문서는 모두 인스턴스 안에 el을 지정하지 않고 라우터만 지정하여 생성한 다음 생성된 인스턴스를 $mount( )를 이용해 붙이는 식으로 안내하고 있다.
- 코드를 실행하면 아래와 같은 결과 화면이 나타난다.
뷰 라우터 실행 결과 화면(왼쪽), Main 컴포넌트로 이동한 화면(중간), Login 컴포넌트로 이동한 화면(오른쪽) - 각 링크를 클릭하면 깜박거림 현상 없이 URL의 끝이 'main' 혹은 'login'으로 바뀐다.
- 라우터 URL의 해시 값(#)을 없애는 방법
- 뷰 라우터의 기본 URL 형식은 해시 값을 사용한다. 만약 index.html/login과 같이 해시 값을 없애고 싶으면 아래의 코드처럼 히스토리 모드(history mode)를 활용하면 된다.
var router = new VueRouter({ mode: 'history', // 로컬서버에서 구동하여야 정확히 동작함. 파일로 열면 올바르게 작동하지 않음. routes });
- 앞의 예제는 한 화면에 컴포넌트 1개만 표시하지만 여러 개의 컴포넌트로 분할된 경우가 많기 때문에 이를 동시에 표시할 수 있는 라우터인 네스티드 라우터와 네임드 뷰에 대 알아보자.
<네스티드 라우터>
- 네스티드 라우터(Nested Router)는 라우터로 페이지를 이동할 때 최소 2개 이상의 컴포넌트를 화면에 나타낼 수 있다. 네스티드(둥지)라는 단어에서 추측할 수 있듯이 상위 컴포넌트 1개에 하위 컴포넌트 1개를 포함하는 구조로 아래와 같이 구성한다.
네스티드 라우터의 구조 - 위 그림처럼 네스티드 라우터를 이용하면 URL에 따라서 컴포넌트의 하위 컴포넌트가 다르게 표시된다.
- 네스티드 라우터를 구현하는 예제를 살펴보자.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue Nested Router</title> </head> <body> <div id="app"> <router-view></router-view> <!-- 1. User 컴포넌트가 뿌려질 영역 --> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script> <script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script> <script> var User = { // 2. 컴포넌트 내용 정의 template: ` <div> User Component <router-view></router-view> <!-- 하위 컴포넌트가 뿌려질 영역 --> </div> ` }; var UserProfile = { template: '<p>User Profile Component</p>' }; var UserPost = { template: '<p>User Post Component</p>' }; var routes = [ // 3. 네스티드 라우팅 정의 { path: '/user', component: User, children: [ { path: 'posts', component: UserPost }, { path: 'profile', component: UserProfile } ] } ]; var router = new VueRouter({ // 4. 뷰 라우터 정의 routes }); var app = new Vue({ // 5. 뷰 인스턴스에 라우터 추가 router }).$mount('#app'); </script> </body> </html>
- 위 예제는 네스티드 라우터의 구조를 코드로 구현한 것으로 User 컴포넌트를 상위 컴포넌트로 놓고 URL에 따라 하위 컴포넌트인 UserPost 컴포넌트와 UserProfile 컴포넌트를 표시하는 코드이다.
- 어떻게 동작하는지 살펴보자
- <div id="app">에 <router-view>를 등록하여 User 컴포넌트가 뿌려질 영역을 정의한다.
- User, UserPost, UserProfile 컴포넌트의 내용을 각 객체에 정의한다. 컴포넌트가 정환된 것을 확인할 수 있게 template 속성을 컴포넌트 내용에 추가한다. 여기서 주목할 부분은 User 컴포넌트의 template에 하위 컴포넌트를 표시할 <router-view>가 하나 더 있다는 점이다.
- routes에 라우터 정보를 정의한다. 제일 먼저 path 속성에는 네스티드 라우터를 실행하는 기본 URL을 /user로 설정하고, 상위 컴포넌트를 User 컴포넌트로 지정한다. 그런 다음 children 속성에는 URL 값 /user 다음에 올 URL에 따라 표시될 하위 컴포넌트를 정의한다. /user/posts인 경우 UserPost를 표시하고, /user/profile인 경우 UserProfile을 표시하도록 설정한다.
- 이제 뷰 라우터를 새로 하나 생성하고 앞에서 정의한 라우터 정보를 담은 객체 routes를 정의한다.
- 마지막으로 인스턴스를 하나 생성하고 라우터 정보 router를 포함한다. 그리고 app이라는 id를 가진 요소에 인스턴스를 붙여 화면에 나타낸다.
- 네스티드 라우터와 기본 라우터의 차이점은 최상위(root) 컴포넌트에도 <router-view>가 있고, 최상위 컴포넌트의 하위 컴포넌트(User)에도 <router-view>가 있다는 것이다. 컴포넌트 간 관계를 아래의 그림으로 표현할 수 있다.
실습 코드의 컴포넌트 간 관계도 - 코드를 실행하고 URL 값 끝에 user를 입력하면 아래와 같은 결과가 나타난다.
/user 실행 결과 화면 - 하위 컴포넌트가 제대로 표시되는지 확인하기 위해 URL 값의 끝에 '/posts' 혹은 '/profile' 를 입력하면 아래와 같이 컴포넌트가 나타나는지 확인한다.
/user/posts 실행 결과 화면(왼쪽), /user/profile 실행 결과 화면(오른쪽) - 네스티드 라우터 구성 방법을 알아보았다. 네스티드 라우터는 화면을 구성하는 컴포넌트의 수가 적을 떄는 유용하지만 한 번에 더 많은 컴포넌트를 표시하는 데는 한계가 있다. 이 문제를 해결할 수 있는 방안으로 네임드 뷰에 대해 알아보자.
<네임드 뷰>
- 네임드 뷰(Named View)는 특정 페이지로 이동했을 때 여러 개의 컴포넌트를 동시에 표시하는 라우팅 방식이다.
네스티드 라우터와 네임드 뷰의 차이 - 네스티드 라우터는 아래의 왼쪽 그림처럼 상위 컴포넌트가 하위 컴포넌트를 포함하는 형식이지만 네임드 뷰는 오른쪽 그림처럼 같은 레벨에서 여러 개의 컴포넌트를 한 번에 표시한다.
- 네임드 뷰 구조를 아래의 예제로 살펴보자.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue Named View Sample</title> </head> <body> <div id="app"> <!-- 1. 라우팅 영역 정의 --> <router-view name="header"></router-view> <router-view></router-view> <!-- name이 없는 경우는 디폴트 --> <router-view name="footer"></router-view> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script> <script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script> <script> var Body = { template: '<div>This is Body</div>' }; // 2. 컴포넌트 내용 정의 var Header = { template: '<div>This is Header</div>' }; var Footer = { template: '<div>This is Footer</div>' }; var router = new VueRouter({ // 3. routes: [ { path: '/', // 4. components: { // 5. <router-view>의 name 속성과 컴포넌트를 연결 default: Body, header: Header, footer: Footer } } ] }); var app = new Vue({ // 6. router }).$mount('#app'); </script> </body> </html>
- 위 코드는 Header, Body, Footer 구조를 네임드 뷰로 구현한 코드이다.
- 파일을 실행하면 URL 값 '/'에 의해 네임드 뷰가 바로 실행된다.
- 코드를 자세히 살펴보자.
- <div> 태그 안에 <router-view>를 3개 추가하고 name 속성을 추가한다. 여기서 name 속성은 아래 components 속성에 정의하는 컴포넌트와 매칭하기 위한 속성이다. Header 컴포넌트는 header, Footer 컴포넌트는 footer를 각각 name 속성에 값으로 지정한다. 그리고 name 속성이 없는 두 번째 <router-view>는 default로 표시될 컴포넌트를 의미한다.
- Body, Header, Footer 컴포넌트의 내용이 담길 객체를 선언한다. 각 컴포넌트 내용에는 컴포넌트 영역이 구분될 수 있게 간단한 template 속성을 추가한다.
- new VueRouter( )로 라우터를 하나 생성하고 라우터 정보를 바로 그 안에 정의한다.
- path는 네임드 뷰가 실행될 URL을 정의하는 속성이다. 여기서는 애플리케이션을 실행하면 마주치는 기본 URL 값 '/'을 지정했다.
- components는 앞에서 <router-view>에 정의한 name 속성에 따라 표시될 컴포넌트를 정의하는 속성이다.
- 인스턴스를 생성하고 네임드 뷰 정보를 갖고 있는 라우터를 포함한다.
- 코드를 실행하면 아래와 같은 결과 화면이 나타난다.
네임드 뷰 예제 코드 실행 결과 화면 - 네임드 뷰를 활용하면 특정 페이지로 이동했을 때 해당 URL에 맞추어 여러 개의 컴포넌트를 한 번에 표시할 수 있다.
- name 속성에 사용한 값이 예약어인가?
- <router-view>에서 사용한 name 속성은 예약어가 아니라 사용자가 임의로 정의할 수 있는 값이다. 위에서 사용한 header, footer 값 모두 appHeader, appFooter라고 이름을 변경해도 동일하게 동작한다. 예외적으로 name 속성을 지정하지 않았을 때의 기본 컴포넌트는 default로 접근한다.
해당 글은 [Do it! Vue.js 입문] 책을 토대로 공부한 내용을 기록하기 위하여 작성됨.
반응형'개발 공부 > Do it! Vue.js 입문' 카테고리의 다른 글
4장. 상용 웹 앱을 개발하기 위한 필수 기술들 - 라우터 & HTTP 통신 - 2 (2) 2025.05.24 3장. 화면을 개발하기 위한 필수 단위 - 인스턴스 & 컴포넌트 - 3 (2) 2025.05.22 3장. 화면을 개발하기 위한 필수 단위 - 인스턴스 & 컴포넌트 - 2 (1) 2025.05.21 3장. 화면을 개발하기 위한 필수 단위 - 인스턴스 & 컴포넌트 - 1 (0) 2025.05.20 2장. 개발 환경 설정 및 첫 번째 프로젝트 (1) 2025.05.19