본문 바로가기

JavaScript/Vue.js

[Do it! Vue.js 입문] 07. 뷰 라우터 (네스티드 라우터, 네임드 뷰)

반응형

뷰 라우터

뷰에서 *라우팅 기능을 구현할 수 있도록 지원하는 공식 라이브러리.

뷰 라우터를 이용하여 뷰로 만든 페이지 간에 자유롭게 이동.

 

<!-- 라우터 CDN 추가 -->
<script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script>

<!-- 페이지 이동 태그. 화면에서는 <a>로 표시되며 클릭하면 to에 지정한 URL로 이동 -->
<router-link to="URL 값"></router-link>

<!-- 페이지 표시 태그. 변경되는 URL에 따라 해당 컴포넌트를 뿌려주는 영역 -->
<router-view></router-view>

 

* 라우팅(Routing)

웹 페이지 간의 이동 방법.
*싱글 페이지 애플리케이션에서 주로 사용. 화면 간의 전환이 매끄러움.


일반적으로 웹 페이지를 요청(request)하면 서버에서 응답(respone)을 받아 웹 페이지를 다시 사용자에게 돌려주는 시간 동안 화면 상에 깜빡거림 현상이 나타남. 이런 부분들을 라우팅으로 처리하면 깜빡거림 없이 화면을 매끄럽게 전환할 수 있고, 더 빠르게 화면을 조작할 수 있어 사용자 경험(UX)이 향상된다.

뷰뿐만 아니라 리액트나 앵귤러 모두 라우팅을 이용하여 화면을 전환. 라우팅 자바스크립트 라이브러리(router.js)를 이용해 라우팅 방식의 페이지 이동을 구현하는 방법도 있음.

* 싱글 페이지 애플리케이션(SPA, Single Page Application)
페이지를 이동할 때마다 서버에 웹 페이지를 요청하여 새로 갱신하는것이 아니라, 미리 해당 페이지들을 받아 놓고 페이지 이동 시에 클라이언트의 라우팅을 이용하여 화면을 갱신하는 패턴을 적용한 애플리케이션

 

#예시 1

<div id="app">
  <h1>라우터</h1>
  <p>  
  	<!-- URL 값을 변경하는 태그 -->
    <router-link to="/main">Main 컴포넌트로 이동</router-link> <br />
    <router-link to="/login">Login 컴포넌트로 이동</router-link>
  </p>
  
  <!-- URL 값에 따라 갱신되는 화면 영역 -->
  <router-view></router-view>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>

<!-- 라우터 CDN 추가 -->
<script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script>

<script>
  // 컴포넌트 정의
  var main = { template: '<div>main</div>' };
  var login = { template: '<div>login</div>' };
  
  // 라우트 정의. 각 URL에 맞춰 표시할 컴포넌트 지정
  // 각 라우트는 반드시 컴포넌트와 매핑되어야 함.
  // "component"는 `Vue.extend()`를 통해 만들어진 실제 컴포넌트 생성자이거나 컴포넌트 옵션 객체
  var routes = [
    { path: '/main', component: main },
    { path: '/login', component: login }
  ];
  
  // 뷰 라우터 정의
  var router = new VueRouter({
    routes
  });
  
  // 뷰 인스턴스에 라우터 추가
  var app = new Vue({
    router
  }).$mount('#app');

</script>
$mount() API

el 속성과 동일하게 인스턴스를 화면에 붙이는 역할. 인스턴스를 생성할 때 el 속성을 넣지 않더라도 생성하고 $mount()를 이용하면 강제로 인스턴스를 화면에 붙일 수 있음.

#예시 1 실행 결과

router-link 태그 부분이 a 태그로 바뀐걸 알 수 있다.

 

 


 

라우터 URL의 해시 값(#)을 없애는 방법
VueRouter 객체에 mode: 'history' 를 추가한다. mode를 따로 선언하지 않으면 Hash가 기본이다.

 

 

책에 해시 값을 없애는 방법이 나왔는데,

해당 방법을 예제에 사용해보면 페이지를 찾을 수 없다는 오류가 나서 따로 더 찾아봤다.

아래 URL에 history와 환경별 오류 해결법이 잘 나와있다. 참고하자.

 

 

HTML5 히스토리 모드 | Vue Router

HTML5 히스토리 모드 vue-router의 기본 모드는 hash mode 입니다. URL 해시를 사용하여 전체 URL을 시뮬레이트하므로 URL이 변경될 때 페이지가 다시 로드 되지 않습니다. 해시를 제거하기 위해 라우터의

router.vuejs.org

 


 

History mode를 이용해 컴포넌트 따로 정의해 사용하지 않고 경로를 바로 지정해서 페이지가 이동하는 아래와 같은 예제도 가능하다. 다만 컴포넌트를 사용하지 않기 때문에 Vue가 지향하는 구현하는 방식이 아니기에 일반적으로 사용하는 방법은 아닐 것이고 그냥 가능하다 정도로만 알고 넘어가자.

 

+ HistoryMode로 설정하면 뒤로가기가 활성화되지 않는 것을 확인 할 수 있다.

 

<div id="app">
  <h1>라우터</h1>
  <p>
    <router-link to="../doit-vuejs-master/exam/02/02-1/index.html">Hello Vue.js!로 이동</router-link> <br />
    <router-link to="index.html">인스턴스 영역으로 이동</router-link>
  </p>
  <router-view></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 router = new VueRouter({
    mode: 'history'
  });
  var app = new Vue({
    router
  }).$mount('#app');

</script>

 

 


네스티드 라우터 (Nested Router)

네스티드(Nested; 중첩)라는 단어에서 추측할 수 있듯이 상위 컴포넌트 1개에 하위 컴포넌트 1개를 포함하는 구조

#예시 2

<div id="app">
  <h1>라우터</h1>
  <router-view></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 user = {
    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>' };

  // 네스티드 라우팅 정의
  // ~~/user/posts, ~~/user/profile
  var routes = [
    {
      path:'/user',
      component: user,
      children: [
        {
          path: 'posts',
          component: userProfile
        },
        {
          path: 'profile',
          component: userProfile
        }
      ]
    }
  ];
  
  // 뷰 라우터 정의
  var router = new VueRouter({
    routes
  });

  // 뷰 인스턴스에 라우터 추가
  var app = new Vue({
    router
  }).$mount('#app');
  
</script>

 

기본주소

기본주소/user

기본주소/user/post

기본주소/user/profile

기본주소/user/없는주소

=> 없는 주소를 넣는다고 해서 오류가 나진 않는다. 기본주소 페이지만 보인다.

 


네임드 뷰(Named View)

특정 페이지로 이동했을 때 여러 개의 컴포넌트를 동시에 표시하는 라우팅 방식

=> 네스티드 라우터의 경우 상위 컴포넌트에 하위 컴포넌트를 포함하는 형식이라면,

     네임드 뷰는 같은 레벨에서 여러 개의 컴포넌트를 한번에 표시하는 방식이다.

#예시 3

<div id="app">
  <h1>네임드 뷰 라우터</h1>
  <!-- 컴포넌트가 뿌려질 영역 -->
  <router-view name="header"></router-view>
  <router-view></router-view>
  <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 header  = { template: '<div>Header Component</div>' };
  var body    = { template: '<div>Body Component</div>' };
  var footer  = { template: '<div>Footer Component</div>' };

  var router = new VueRouter({
    routes: [
      {
        path:'/',
        components: {
          default: body,
          header: header,
          footer: footer
        }
      }
    ]
  });

  var app = new Vue({
    router
  }).$mount('#app');

</script>

실행결과


 

실습 #1 - 아래 샘플에 '/login' url을 추가하고, LoginHeader, LoginBody, LoginFooter 컴포넌트를 추가해보세요.

실습 #2 - 아래 샘플에 LoginHeader, LoginBody, LoginFooter 컴포넌트 내용을 정의해보세요.

 

<div id="app">
	<router-view name="header"></router-view>
	<router-view></router-view>
	<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>' };
	var Header = { template: '<div>This is Header</div>' };
	var Footer = { template: '<div>This is Footer</div>' };

	// 실습 #2 - LoginHeader, LoginBody, LoginFooter 컴포넌트 내용을 정의해보세요.

	var router = new VueRouter({
		routes: [
			{
				path: '/',
				components: {
					default: Body,
					header: Header,
					footer: Footer
				}
			},
			// 실습 #1 - '/login' url을 추가하고, LoginHeader, LoginBody, LoginFooter 컴포넌트를 추가해보세요.

		]
	});

	var app = new Vue({
		router
	}).$mount('#app');
</script>

실습 예제에 코드 추가

<div id="app">
  <router-view name="header"></router-view>
  <router-view></router-view>
  <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>' };
  var Header = { template: '<div>This is Header</div>' };
  var Footer = { template: '<div>This is Footer</div>' };

  // 실습 #2 - LoginHeader, LoginBody, LoginFooter 컴포넌트 내용을 정의해보세요.
  var LoginBody = { template: '<div>This is LoginBody</div>' };
  var LoginHeader = { template: '<div>This is LoginHeader</div>' };
  var LoginFooter = { template: '<div>This is LoginFooter</div>' };

  var router = new VueRouter({
    routes: [
      {
        path: '/',
        components: {
          default: Body,
          header: Header,
          footer: Footer
        }
      },
      // 실습 #1 - '/login' url을 추가하고, LoginHeader, LoginBody, LoginFooter 컴포넌트를 추가해보세요.
      {
        path: '/login',
        components: {
          default: LoginBody,
          header: LoginHeader,
          footer: LoginFooter
        }
      },
    ]
  })

  var app = new Vue({
    router
  }).$mount('#app');
  
</script>

 

반응형