Vue CLI 를 사용해 Vue.js SPA(Single Page Application)을 생성하고 Vuetify를 사용해 머터리얼 디자인을 적용해 본다.

I. Vue CLI 와 Vuetify.js 소개

Vue CLI 는 Vue.js 를 생성, 관리, 실행할 수 있는 Command Line Interface 이다.

Vue CLI 를 사용하면 Webpack, Babel, Lint, TypeScript, Vue Router, Vuex 등의 다양한 피쳐들을 선택해서 프로젝트를 생성할 수 있다.

이번 프로젝트는 Vue CLI 를 사용해서 SPA(Single Page Application)을 생성하고 빌드하도록 한다.


Vuetify는 Vue.js를 위한 개발된 디자인 프레임워크이다.

Vue.js로 프로젝트를 진행할때 Vuetify 를 사용하면 손쉽게 아름다운 디자인을 적용할 수 있다.

Vuetify는 머터리얼 디자인 스펙 (Material Design Spec) 을 준수한다.
Material Design Spec V2


이 글을 읽기전에 이전 글 Vue.js 프레임워크 소개와 스프링부트(Spring Boot) REST API 호출 예제 와 같은 로직을 사용할 예정이므로 이 글을 참고하는것이 좋다.

II. Vue.js 프로젝트 생성

Vue CLI를 사용해서 Vue.js 프로젝트를 만들기 위해서는 NPM 이 먼저 설치되어 있어야 한다.

NPM 설치에 관해서는 이전 글 개발자 기본 개발 환경 설정 에서 확인할 수 있다.

1. Vue CLI 설치

프로젝트를 생성하기전에 NPM 에서 Vue CLI 를 먼저 설치해야 한다.

  • 터미널에서 아래 명령어를 실행한다.
    $ npm install -g @vue/cli
    

2. Vue CLI 를 사용해 Vue.js 프로젝트를 생성

  • 프로젝트를 생성할 폴더로 이동한 뒤 아래 명령어를 실행한다.
    $ vue create vuetify01
    
  • “Please pick a preset:” 선택옵션에서 나오면 “default(babel, lint)” 항목을 선택한다.
    ? Please pick a preset:
    ❯ default (babel, eslint)
    Manually select features
    

“Manually select features”를 선택하면 다양한 선택가능 피쳐들이 표시되는데 처음 Vue.js를 접할때는 “default”를 사용하는것을 권장한다.

이러한 피쳐들에 대해서는 다음에 글을 남겨보도록 하겠다.

III. Vue.js 프로젝트 확인

1. Vue.js 프로젝트

  • 통합개발환경(IDE)에서 생성된 프로젝트를 연다.

  • Vue CLI 가 많은 파일들을 생성해주는데, /src 폴더 이하에서 주로 작업을 하게되니 이부분을 주의 깊게 관찰하도록 한다. Vue CLI 로 생성된 Vue.js 프로젝트 소스

2. Vuetify 적용

  • 기본적으로 생성되는 프로젝트에는 Vuetify 가 적용되지 않으므로 터미널에서 아래 명령어로 Vuetify 를 적용한다.
    $ vue add vuetify
    
  • 선택옵션에서는 “Default”를 선택하도록 한다.
    ? Choose a preset: (Use arrow keys)
    ❯ Default (recommended) 
    Prototype (rapid development) 
    Configure (advanced) 
    

3. NPM 으로 프로젝트 실행

  • NPM 명령으로 프로젝트를 실행해 볼 수 있다. 터미널에서 아래 명령어를 입력한다.
    $ npm run serve
    

4. 웹브라우져에서 확인

  • 웹브라우져에서 아래 주소로 접속하면 프로젝트 실행 결과 화면을 볼 수 있다. Vuetify를 적용한 화면

IV. Vue.js 프로젝트 수정

1. App.vue 파일 수정

  • App.vue 파일을 열어서 모든 “HelloWorld” 를 “HomeView”로 변경한다.
<template>
  <v-app>
    <v-toolbar app>
      <v-toolbar-title class="headline text-uppercase">
        <span>Vuetify</span>
        <span class="font-weight-light">MATERIAL DESIGN</span>
      </v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn
        flat
        href="https://github.com/vuetifyjs/vuetify/releases/latest"
        target="_blank"
      >
        <span class="mr-2">Latest Release</span>
      </v-btn>
    </v-toolbar>

    <v-content>
      <HomeView/>
    </v-content>
  </v-app>
</template>

<script>
import HomeView from './components/HomeView'

export default {
  name: 'App',
  components: {
    HomeView
  },
  data () {
    return {
      //
    }
  }
}
</script>

2. 새로운 Vue 컴포넌트 생성

  • /src/components 폴더에서 “HomeView.vue” 파일을 생성한다. sr/components 폴더에 HomeVue.vue 파일을 생성

3. HomeView 컴포넌트 초기화

  • “HomeView.vue” 파일을 열어서 아래의 내용을 입력한다.
    (아래 텍스트를 복사해서 붙여넣는다)
<template>
    <v-container>
        <h1>Products</h1>
        <v-card>
            <v-layout>
                <v-flex xs3>
                    <v-img contain height="125px"></v-img>
                </v-flex>
                <v-layout column>
                    <v-card-title></v-card-title>
                    <v-card-text></v-card-text>
                    <v-card-actions>
                        <v-btn>Add Cart</v-btn>
                    </v-card-actions>
                </v-layout>
            </v-layout>
        </v-card>
        <v-spacer/>
        <h1>My Cart Items ($ {{totalAmount}}) </h1>
        <v-card>
            <v-layout>
                <v-flex xs3>
                    <v-img contain height="125px"></v-img>
                </v-flex>
                <v-layout column>
                    <v-card-title></v-card-title>
                    <v-card-text></v-card-text>
                </v-layout>
            </v-layout>
        </v-card>
    </v-container>
</template>

<script lang="js">
    export default {
        data() {
            return {
                products: [
                ],
                cartItems: [
                ],
                totalAmount: 0
            }
        },
        methods: {
        }
    }
</script>

지금처럼 생성한 HomeView을 Single File Component 라고 부른다.
“<template>” 태그안에는 이 컴포넌트의 외형을 표현하는 HTML 템플릿을 작성하고
“<script>” 태그안에는 이 컴포넌트의 액션을 작성하고
“<style>” 태그에 이 컴포넌트의 스타일을 작성하면 된다.

이 템플릿에서는 “<v-container>“로 시작해서 2세트의 “<h1>” 과 “<v-card>” 를 구현해 놓았다. 위 쪽에서는 제품들 목록, 아래쪽에서는 장바구니 아이템 목록을 표시할 예정이다.

4. 웹브라우져에서 확인

  • 웹브라우져에서 아래 주소로 접속하면 프로젝트 실행 결과 화면을 볼 수 있다. Vue CLI 로 생성된 Vue.js 프로젝트 결과화면

5. 제품 데이타 추가

  • script 영역의 data 아래의 “products” 배열값을 아래 내용으로 수정한다.
products: [
    {
        id: 1,
        title: 'Apple iPad (Wi-Fi, 32GB) - Space Gray',
        price: 350,
        inventory: 7,
        imgsrc: 'https://images-na.ssl-images-amazon.com/images/I/51x4j48wCpL._SL1024_.jpg'
    },
    {
        id: 2,
        title: 'Apple iPhone XR (64GB) - RED',
        price: 749,
        inventory: 5,
        imgsrc: 'https://images-na.ssl-images-amazon.com/images/I/51YXG1bDM5L._SL1024_.jpg'
    },
    {
        id: 3,
        title: 'Apple Macbook Retina Display Laptop',
        price: 949,
        inventory: 2,
        imgsrc: 'https://images-na.ssl-images-amazon.com/images/I/819zx3uAjhL._SL1500_.jpg'
    },
],

6. 제품 템플릿 수정

  • template 영역에서 첫번째 <v-card> 태그를 아래 내용으로 수정한다.
<v-card v-for="product in products" :key="product.id">
    <v-layout>
        <v-flex xs3>
            <v-img :src="product.imgsrc" contain height="125px"></v-img>
        </v-flex>
        <v-layout column>
            <v-card-title><h1>{{ product.title }}</h1></v-card-title>
            <v-card-text>{{ `$ ${product.price} (Inventory: ${product.inventory})` }}</v-card-text>
            <v-card-actions>
                <v-btn :disabled="product.inventory <= 0" @click="addToCart(product)">Add Cart</v-btn>
            </v-card-actions>
        </v-layout>
    </v-layout>
</v-card>

7. 웹브라우져에서 확인

  • 웹브라우져에서 아래 주소로 접속하면 프로젝트 실행 결과 화면을 볼 수 있다. Vue CLI 로 생성된 Vue.js 프로젝트 결과화면

8. 장바구니 템플릿 수정

  • template 영역에서 두번 <v-card> 태그를 아래 내용으로 수정한다.
<v-card v-for="cartItem in cartItems" :key="'C' + cartItem.id">
    <v-layout>
        <v-flex xs3>
            <v-img :src="cartItem.imgsrc" contain height="125px"></v-img>
        </v-flex>
        <v-layout column>
            <v-card-title><h1>{{ cartItem.title }}</h1><br/></v-card-title>
            <v-card-text>{{ `$ ${cartItem.price} x ${cartItem.quantity} = ${cartItem.subsum}` }}</v-card-text>
        </v-layout>
    </v-layout>
</v-card>

9. “ADD CART” 버튼 이벤트 핸들러 구현

  • methods 속성 아래와 같이 addToCart() 함수를 구현한다.
    addToCart: function (product) {
      // STEP01 - products 배열에서 id 를 기준으로 필터링하고 필터링된 아이템에서 inventory 값을 -1 한다.
      this.products
          .filter(function (p) {
              return p.id === product.id
          })
          .map(function (p) {
              return p.inventory--
          });
    
      // STEP02 - cartItems 배열에서 id 를 기준으로 필터링하고...
      var _cartItem = this.cartItems.filter(function (p) {
          return p.id === product.id
      });
      if (_cartItem.length > 0) {
          // 필터링 된 아이템이 존재하면 quantity 값을 +1 한다.
          _cartItem.map(function (p) {
              return p.quantity++
          });
      } else {
          // 필터링 된 아이템이 없으면 새로운 객체를 생성해서 추가한다.
          this.cartItems.push({
              "id": product.id,
              "title": product.title,
              "price": product.price,
              "quantity": 1,
              "imgsrc": product.imgsrc
          });
      }
    
      // STEP03 - cartItems 배열에서 "소계 = 가격 x 수량" 을 계산하여 아이템의 subsum 속성 값으로 대입한다.
      this.cartItems.map(function (p) {
          p.subsum = p.price * p.quantity;
          return p;
      });
    
      // STEP4 - cartItems 배열에서 REDUCE 하여 "총계" 값을 구해서 totalAmount 변수에 대입한다.
      this.totalAmount = this.cartItems.reduce(function (previousSum, currentItem) {
          return previousSum + currentItem.price * currentItem.quantity;
      }, 0);
    }
    

10. 웹브라우져에서 확인

  • 웹브라우져에서 아래 주소로 접속하면 프로젝트 실행 결과 화면을 볼 수 있다.
  • 각 제품들의 “ADD CART” 버튼을 클릭하면 “My Cart Items” 아래에 추가됨을 확인 할 수 있다.
  • 각 항목마다 “가격 x 수량”으로 소계를 계산하여 표시해 주었고, “My Cart Items” 옆에에는 총계가 표시된다. Vue CLI 로 생성된 Vue.js 프로젝트 결과화면

본 예제 결과물 vuetify02.zip 소스파일은 아래 링크에서 다운받을 수 있다.
vuetify02.zip 소스파일


Front-end Vue.js Vuetify Material Design Vue CLI

Blog Logo

HeeHun Kang


Published