본문 바로가기

3.구현/HTML5&Javascript

[vue2] 레이아웃 구성

웹페이지는 여러 화면으로 구성되어 있다. 일반적으로 상단에 로고와 메뉴, 가운데에 컨텐츠, 하단에 사이트정보 등 형태로 되는 경우가 많다. 이런 화면을 모든 페이지에 반복적으로 나타나는데, 모든 페이지에 같은 작업을 반복적으로 하기에는 매우 비효율적이다. 이때 필요한게 레이아웃을 구성해여 화면 분할해서 작업하는 형식이다.

작성자: ospace114@empal.com, http://ospace.tistory.com/

들어가기

vue.js에서 레이아웃은 기본 기능이기 보다는 라우터의 기능과 컴포넌트 기능을 적절하게 활용하는 형태이다. 다른 프레임워크에서는 페이지를 임포트하여 구성하거나 이를 위한 별도 라이브러리를 사용하는 경우가 많다.
물론 더 훌륭한 기능을 사용하고 싶다면 추가 라이브러리를 사용할 수도 있지만, 라우터와 컴포넌트 기능만으로도 충분히 레이아웃을 구성할 수 있다.

간단한 레이아웃

가장 단순한 레이아웃을 만들어보자. 헤더, 컨텐츠, 푸터 형태의 레이아웃으로 아래 모습과 같다.

화면 페이지별로 내용은 가운데 컨텐츠에 표시된다.

App.vue

먼저 App.vue 파일을 먼저 수정하자. 기본적인 레이아웃을 여기서 모두 구성한다.

<template>
    <div>
      <Header></Header>
      <router-view></router-view>
      <Footer></Footer>
    </div>
</template>

<script>

import Header from './layout/Header';
import Footer from './layout/Footer';

export default {
  name: 'App',
  components: {
    Header,
    Footer,
  }
}
</script>

Header와 Footer 컴포넌트는 layout 폴더에 위치하도록 했다. 별도 layout 폴더를 만들어서 다른 컴포넌트와 분리하도록 했다. 나머지 컴포넌트도 생성해보자.

Header.vue

헤더에 해당하는 파일이다. 현재는 제목과 네비게이션으로 단순 링크로 구성되어 있다.
src/layout/Header.vue 파일

<template>
  <div class="header">
    <h1>Header</h1>
    <router-link to="/">Home</router-link> / <router-link to="/bar">Go to Bar</router-link>
  </div>
</template>
<style scoped>
.header {
  text-align: center;
  background-color: lightgray;
}

a {
  color: #42b983;
}
</style>

Footer.vue

푸터로 화면 하단에 배치된다. 별다른 내용은 없다.
src/layout/Footer.vue 파일

<template>
  <div class="footer">
    <h1>Footer</h1>
  </div>
</template>
<style scoped>
.footer {
  text-align: center;
  background-color: lightgray;
}
</style>

나머지 컴포넌트

나머지 테스트용 페이지이다.

홈페이지에 해당하는 src/Home.vue 파일이다.

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <p>
    <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
  </div>
</template>

<script>

export default {
  name: 'Home',
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

src/components/Bar.vue 파일은 단순 테스트용 화면이다.

<template>
    <h1>Bar Page</h1>
</template>

라우터 설정

여기까지 했다면 모두 완료했다. 나머지는 링크만 만들어주면 된다. 마지막으로 라우터를 설정해보자. 라우터에 아래 설정을 추가하면 된다.

const router = new VueRouter({
    mode: 'history',
    routes: [
        {
            path: '/',
            name: 'home',
            component: ()=> import('@/Home.vue'),
        },
        {
            path: '/bar',
            name: 'bar',
            component: ()=> import('@/components/Bar.vue'),
        },
    ],
});

결과 화면

테스트한 화면이다.

새로운 레이아웃

한단계 더 나아가 보자. 로그인 페이지를 만들려고 한다. 로그인 페이지는 화면에 아무것도 없고 ID와 Password을 입력하는 컨트롤만 있는 화면이다. 즉, 기존 레이아웃과 다른 화면이다. 이럴 경우 기존 레이아웃을 그대로 사용할 수 없다.
레이아웃을 2개로 분리해보자.

  • DefaultLayout: 기존 헤더, 컨텐츠, 푸터 형태로 구성된 레이아웃
  • EmptyLayout: 아무것도 없는 빈 레이아웃

App.vue

먼저 App.vue 파일을 수정하자. 기존에 기본 레이아웃 구성되었지만, 지금은 링크에 따라 달라지기 때문에 별도 처리하지 않는다. 그냥 페이지 출력해준다.

<template>
  <router-view></router-view>
</template>

<script>
export default {
  name: 'App',
}
</script>

DefaultLayout.vue

먼저 layouts/DefaultLayout.vue 파일을 생성하다. 기존 App.vue에 있던 기본 레이아웃 구성을 그대로 사용한다.

<template>
    <div>
      <Header></Header>
      <router-view></router-view>
      <Footer></Footer>
    </div>
</template>

<script>

import Header from './Header';
import Footer from './Footer';

export default {
  components: {
    Header,
    Footer,
  }
}
</script>

EmptyLayout.vue

새로 추가되는 레이아웃으로 layouts/EmptyLayout.vue 파일이다. 헤더나 푸터가 없는 빈 레이아웃으로 로그인 페이지만 표시된다.

<template>
  <router-view></router-view>
</template>

Login.vue

로그인 페이지이다. 여기서는 실제 로그인을 수행하지 않고 홈으로 이동하는 단순 링크만 추가했다.

<template>
    <div>
        <h1>Login</h1>
        <router-link to="/">Home</router-link>
    </div>
</template>

라우터 설정

앞의 컴포넌트를 가지고 최종 라우터 설정을 해보자. 기존에 Home.vue와 Bar.vue은 그대로 사용한다.

const router = new VueRouter({
    mode: 'history',
    routes: [
        {
            path: '/',
            name: 'defaultLayout',
            component: () => import('@/layouts/DefaultLayout.vue'),
            children: [
                {
                    path: '/',
                    name: 'home',
                    component: ()=> import('@/Home.vue'),
                },
                {
                    path: '/bar',
                    name: 'bar',
                    component: ()=> import('@/components/Bar.vue'),
                },
            ],
        },
        {
            path: '/',
            name: 'emptyLayout',
            component: () => import('@/layouts/EmptyLayout.vue'),
            children: [
                {
                    path: '/login',
                    name: 'login',
                    component: ()=> import('@/Login.vue'),
                },
            ],
        },
    ],
});

routes 속성에 defaultLayout과 emptyLayout이라는 2개의 라우트 설정이 되어 있다. 그리고 defaultLayout의 children에 home과 bar 라우트가 설정되었고 emptyLayout의 children에는 login 라우트가 설정되었다. 즉, 이는 각각 children의 path로 접근할 때에 가져올 레이아웃이 달라지게 된다.

템플릿 파일

$ git clone https://github.com/ospace/vuejs-template-layout
  • 다운로드

project-files.zip
13.1 kB

결론

vue.js에서 레이아웃을 구성해보았다. 단순한 부분이라서 어떻게 응용하느냐에 따라 다양한 방법이 있을 수 있다. 물론 레이아웃을 사용하지 않고 페이지를 구성할 수도 있지만, 규모가 있는 웹페이지인 경우는 일관된 사용자 경험을 제공하기 위해서 특정 패턴의 화면을 반복적으로 사용하게 된다. 이렇게 동일한 화면 패턴에 레이아웃을 적용할 경우 반복적인 작업 및 유지보수가 좋아질 거라고 생각한다.ospace.

반응형