<< Back
blog 프로그래밍

:: Vue.js + Axios 를 이용한 프론트엔드 웹페이지 개발




Vue.js

Vue(/vjuː/ 로 발음, view 와 발음이 같다.)는 사용자 인터페이스를 만들기 위한 진보적인 프레임워크로 다른 단일형 프레임워크와 달리 점진적으로 채택할 수 있도록 설계 되어 있다. 핵심 라이브러리는 뷰 레이어만 초점을 맞추어 다른 라이브러리나 기존 프로젝트와의 통합이 매우 쉬운 편이다.

시작하기

Vue.js 는 자바스크립트 기반이며 프론트엔드 개발 프레임워크 이기 때문에 HTML, CSS, JavaScript 에 대한 기본적인 이해를 전제로 하고 있다. 따라서 기본적인 프론트엔드 개발 경험이 전혀 없다면 관련 부분을 먼저 학습하기 바란다. 본 강좌도 관련된 기초학습이 어느정도 이루어진 것으로 가정하고 진행할 것이다.

복잡한 웹페이지 개발이나 서버사이드 렌더링, 개발된 사이트를 배포하는 등의 작업을 위해서는 node.js, npm, vue-cliwebpack 등에 대해서도 다뤄야 하지만 여기서는 기본적인 개념을 잡을수 있는 수준까지만 진행 하게 된다.

Vue.js 포함

제일먼저 해야 할 일은 웹 페이지에 Vue.js 라이브러리는 CDN 을 통해 포함 하는 것이다.

<script src="https://cdn.jsdelivr.net/npm/vue"></script>

기본구조

Vue.js 는 MVVM(Model, View, View Model) 아키텍처 를 사용한다. Vue.js 의 역할은 View Model 로 DOM 과 자바스크립트 객체를 연결해 주면 뷰모델이 이들간의 동기화를 자동으로 처리한다. 또한 Vue.js 는 가상돔(Virtual DOM)을 사용 함으로써 필요한 부분만 신속하게 업데이트 할 수 있다.

템플릿 구문을 이용한 데이터 표현

일반적인 웹페이지와 마찬가지로 화면은 html 과 css를 이용해 개발하면 된다. 다만 데이터를 표현해야 하는 부분은 이중 중괄호(Mustaches) {{변수}} 형태로 정의 한다. JSP에서의 EL(Expression Language, ${expression} 형태로 사용)과 유사하다.

<div id="app">
 {{ msg }} 
</div>

Vue 인스턴스

Vue 인스턴스는 Vue 객체를 생성하고 데이터 변수나 라이프사이클에 따른 콜백 메서드등을 정의하는 Vue 의 핵심 구현 부분이다. 동적으로 데이터 변수를 변하게 한다면 별다른 처리 없이 자동으로 문서의 내용이 실시간으로 업데이트 된다.

var app = new Vue({
  el: '#app',
  data: {
    message: '안녕하세요 Vue!'
  }
})

Vue는 자바스크립트 객체로 생성자를 이용해 객체를 생성하는 형태이며 이 구조는 JSON(Java Script Object Notation) 이라고 할 수 있다.

디렉티브

디렉티브는 v-로 시작하는 특수한 속성으로 HTML 태그의 속성형태로 일반적인 브라우저에서는 무시되며 Vue.js 에 의해서만 동작하게 된다. JSP에서 사용하는 JSTL(JSP Standard Tag Library) 에서 제공하는 for, if, 변수접근 등의 기능과 유사하다고 볼 수 있다.

v-bind 와 전달인자

이중중괄호는 HTML 태그에서 사용할 수 없기 때문에 태그에서 Vue 데이터를 연동하기 위해서는 v-bind 를 사용한다. 다음에제에서 <a> 태그의 href 속성은 url 변수의 값으로 할당 된다. 이때 :href 를 전달인자라고 한다.

<a v-bind:href="url"> ... </a>
<button v-bind:disabled="isButtonDisabled">Button</button>

v-on

이벤트 핸들러로 전달인자에 지정된 이벤트에 호출할 이벤트 처리를 지정 한다.

<a v-on:click="doSomething"> ... </a>

v-if

간단한 조건문으로 if 조건이 참인 경우 동작하는 태그를 구성할때 사용한다. 다음 예제는 seen 변수값이 true인 경우에만 보이게 된다.

<p v-if="seen">이제 나를 볼 수 있어요</p>

v-for

배열의 데이터를 사용해 반복적으로 출력하는 데이터를 표현할 때 사용한다.

<div id="app-4">
  <ol>
    <li v-for="todo in todos">
      
    </li>
  </ol>
</div>
...
<script>
var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: 'JavaScript 배우기' },
      { text: 'Vue 배우기' },
      { text: '무언가 멋진 것을 만들기' }
    ]
  }
})
</script>

예제::주소록 목록 보여주기

JAX-RS 기반 RESTful API 개발 에서 만든 주소록 Rest API 를 이용해 Vue.js 기반의 주소록 목록 화면을 만들어 본다.

html 작성

<head></head> 부분

화면 디자인을 위한 boostrap 과 View Model 구현을 위한 Vue.js, REST API 호출을 처리할 Axios 라이브러리를 포함 시킨다.

<head>
    <meta charset="utf-8">
    <title>AddressBook Vue.js</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

데이터 출력 부분

주소록 데이터는 번호, 이름, 전화번호, 생년월일, 회사, 메모 로 구성되어 있으며 목록 구성을 위해 v-for 디렉티브를 사용 한다. 여기서는 datas라는 이름의 배열 데이터로 부터 각각의 데이터를 ab 라는 이름의 객체로 받아 각각의 키값에 해당하는 데이터를 출력하는 구조 이다.

<div id="app">
<table>
    ...
<tbody>
    <tr v-for="ab in datas">
        
        <td><a href="">{{ab.ab_id}}</a></td>
        <td>{{ab.ab_name}}</td>
        <td>{{ab.ab_tel}}</td>
        <td>{{ab.ab_birth}}</td>
        <td>{{ab.ab_comdept}}</td>
        <td>{{ab.ab_memo}}</td>
        
    </tr>
</tbody>
</table>
</div>

Vue 인스턴스 생성

Vue 인스턴스는 기본예제에서와 같은 형식이며 datas 변수는 배열 구조이며 초기 데이터는 비워져 있다.

var ex = new Vue( {
    el: '#app',
    data: { 
        datas: []
    }
});

Axios 를 이용한 주소록 REST API 호출

Axios 는 여러 자바스크립트 REST API 중에서 간단하고 편리한 사용법으로 널리 이용되고 있다. Axio 이외 다른 REST API나 raw 레벨의 자바스크립트 코드 사용도 가능하다. REST API 호출 결과가 JSON 배열이므로 전달받은 값을 datas 변수에 연결해 주면 된다.

객체가 생성되는 시점에 실행되도록 created: 에 콜백 함수를 구현 했다.

created: function(){
    // using JSONPlaceholder
    const baseURI = 'http://localhost:8080/javaweb/api/addrbook';
    axios.get(`${baseURI}/list`)
    .then((result) => {
    console.log(result)
    this.datas = result.data
    }
)}

실행결과 및 전체 소스

실행결과

전체소스

<!doctype html>

<html>
    <head>
        <meta charset="utf-8">
        <title>AddressBook Vue.js</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
        <script src="https://unpkg.com/vue"></script>
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    </head>

    <body>
        <div class="container w-75 mx-auto mt-5">
            <H2>AddressBook::List</H2>
            <HR>
                <a href="" class="btn btn-info">New Entry</a>
                <P>

                <div id="app">
                <table class="table table-hover table-striped">
                    <thead class="thead-dark">
                        <tr>
                            <th>#No</th>
                            <th>Name</th>
                            <th>CellPhone</th>
                            <th>Birth Date</th>
                            <th>Company</th>
                            <th>Memo</th>
                        </tr>
                    </thead>
                    <tbody>
                        
                        <td><a href="">{{ab.ab_id}}</a></td>
                        <td>{{ab.ab_name}}</td>
                        <td>{{ab.ab_tel}}</td>
                        <td>{{ab.ab_birth}}</td>
                        <td>{{ab.ab_comdept}}</td>
                        <td>{{ab.ab_memo}}</td>
                        
                    </tbody>
                </table>
            	</div>
			</div>
			
            <script>          
                var ex = new Vue( {
                    el: '#app',
                    data: { 
                        datas: []
                    },
                    computed: {
                    hasResult: function () {
                        return this.posts.length > 0
                    }
                    },
                    created: function(){
                        const baseURI = 'http://localhost:8080/javaweb/api/addrbook';
                        axios.get(`${baseURI}/list`)
                        .then((result) => {
                        console.log(result)
                        this.datas = result.data
                        }
                    )}
                });
            </script>    
        </body>
    </html>

참고 자료

<< Back