이전 글: Vue.js: 기초 사용 방법 + 예제: 이름으로 보는 운세
요구사항: Home, Portfolio, Guestbook 3개의 메뉴로 된 홈페이지를 만들되 각 메뉴는 Vue.js의 컴포넌트를 사용하여 작성하시오.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <title>Homepage</title> <link rel="stylesheet" href="[부트스트랩-cdn-주소]"> </head> <body class=container> <nav id="home-nav" class="navbar navbar-expand-lg navbar-dark bg-dark"> <a class="navbar-brand" href="#">{{ title }}</a> <button class="navbar-toggler" type="button"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarColor02"> <ul class="navbar-nav mr-auto"> <li class="nav-item" v-for="item in menus"> <a class="nav-link" href="#" v-on:click="moveMenu">{{ item }}</a> </li> </ul> </div> </nav> <!-- 컴포넌트 부분, :contents 는 article객체의 currentContents에 있는 내용을 불러온다. --> <article id="home-article" class="row"> <display-article :contents="currentContents"> </display-article> </article> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="./index.js"></script> </body> </html>
<article>
은 HTML5에 나오는 태그로 웹사이트에서 읽을 거리 등 주요 내용이 들어가는 의미를 가진(semantic) 구역(div) 태그입니다. 하위에 위치한 <display-article>
이 컴포넌트가 들어갈 자리입니다. 이 태그의 이름은 실제 HTML5 스펙에는 없는 이름으로 Vue.js의 컴포넌트의 이름은 만드는 사람 마음대로 지을 수 있다는 것이 특징입니다.
컴포넌트는 HTML 상에서는 껍데기 부분만 선언해놓고 실제 내용은 다른 곳에서 작성된다는 특징이 있습니다. 보통 규모가 있는 개발 환경에서는 *.Vue
라는 확장자의 파일로 따로 작성되는데, 지금은 예제이므로 단순하게 컴포넌트를 스크립트 부분에 선언해 보겠습니다.
:contents
는 v-bind:contents
의 약자로 currentContents
의 내용이 (실시간으로) 컴포넌트의 props
의contents
에 대입된다는 의미입니다.
Vue.component('display-article', { template: '<div class="col-12 text-primary">{{ contents }}</div>', props: ['contents'] })
컴포넌트의 전역 선언 방법입니다. 지역 스코프로 선언하는 방법도 있지만 지금은 넘어가겠습니다. 프로퍼티(props
)로 contents
를 지정하고, 그 contents
를 템플릿 안에서 사용한다는 의미입니다. prop
의 contents
가 바뀔 때마다 템플릿 안의 내용도 바뀌게 됩니다. 그럼 이 contents
라는 이름의 무언가를 다루는 방법에 대해 알아보겠습니다.
그 전에 템플릿에 대한 주의 사항이 있습니다. 템플릿(template
)는 실제 컴포넌트 안에 렌더링될 내용들이 들어 있는 곳인데, 템플릿의 내용은 <display-article>
의 하위 태그로 들어가는 것이 아니며, 해당 태그를 대체합니다. 즉, 렌더링된 최종 결과에서 임의로 선언한 <display-article>
는 사라지고 그 자리를 템플릿의 <div>
태그가 차지할 것입니다.
var nav = new Vue({ el: "#home-nav", data: { title: "홈페이지", menus: ["Home", "Portfolio", "Guestbook"], contents: { home: "첫화면입니다", portfolio: "포트폴리오입니다.", guestbook: "방명록입니다." } }, methods: { moveMenu: function (e) { var menu = e.target.text.toLowerCase() // 클릭하면 메뉴값을 article.currnetContents에 대입한다. article.currentContents = this.contents[menu] } } }) var article = new Vue({ el: "#home-article", data:{ currentContents: "" } }) // 첫 화면 지정 window.onload = function(){ article.currentContents = nav.contents.home }
nav
변수는 내비게이터 부분인 <nav>
태그를 관리하는 Vue.js 인스턴스입니다. methods
에 moveMenu
라는 것이 있는데 이 메소드가 실행되면 contents[menu]
의 내용이 article.currentContents
에 할당합니다. 예를 들어 menu
가 guestbook
이라면 this.contents["guestbook"]
에 있는 "방명록입니다."
라는 내용을 article.currentContents
에 할당하겠다는 의미와 동일합니다.
맨 위 HTML 부분의 <display-article>
태그에서 :contents="currentContents"
부분을 다시 보겠습니다. <article>
이 Vue.js 인스턴스 관리 하에 있으므로 하위에 있는 <display-article>
이라는 태그도 currentContents
데이터를 인식할 수 있습니다. 여기서 contents
는 전역 선언한 컴포넌트 'display-article'
의 프로퍼티입니다. currentContents
가 nav
인스턴스의 메소드에 의해 변경되면, 그것이 컴포넌트의 프로퍼티인 contents
로 전달되며, 프로퍼티는 다시 템플릿(template
) 안으로 전달됩니다. 브라우저에서는 템플릿의 내용을 바탕으로 컴포넌트 안이 렌더링됩니다. 이것을 순서대로 표시하면 아래 그림과 같습니다.
결과화면입니다. JSFiddle에서도 볼 수 있습니다.
0개의 댓글