[Vue.js] SPA 개발을 위한 사전 정리




목표

본 포스팅에서는 SPASingle Page Application 개발에 앞서 SPA에 대한 이해 및 자바스크립트 프레임워크 Vue.js에 대한 기본적인 이해를 목표로 하고 있습니다. (MPA 웹 서비스 및 MVC 패턴에 대한 기본적인 이해를 바탕으로 작성하였습니다.)




목차

  1. JavaScript Framework의 사용 배경
  2. MPA 개발에서 SPA 개발까지
  3. SPA 라우팅에 대한 이해
    ①Link 방식
    ②Ajax 방식
    ③Hash 방식
  4. JavaScript Framework의 주 활용 요소
  5. Vue.js
  6. 주 라이브러리
    ①Vue Router
    ②Vue CLI
    ③Vuex
    – 상태 관리 패턴이란?
    – 상태 관리 패턴의 적용 이유
    – Vuex의 필요성 및 구성 요소
    – 동작 (Getters, Action, Mutaitions)
  7. 정리




1. JavaScript Framework의 사용 배경


자바스크립트 프레임워크가 등장하기 전에는, 프론트 로직을 플레인 자바스크립트나 jQuery*1을 활용하여 구현하였습니다. JavaScript 프레임 워크는 프론트엔드의 개발이 복잡해지면서 등장하였습니다.

JavaScript 프레임 워크를 활용하면 SPA(Single Page Application)*2 등 고급 웹 애플리케이션을 개발하는 데 훨씬 용이합니다.

*1 jQuery: DOM을 쉽게 조작하기 위한 라이브러리
*2 SPA: 단일 페이지 어플리케이션(Single Page Application)의 형태로 웹을 개발하는 것을 의미, 자세한 내용은 2번 참고




2. MPA 개발에서 SPA 개발까지


기존의 MPA(multiple-page application)웹 서비스는, 클라이언트의 리퀘스트request가 있을 때마다 서버로부터 리소스resource들과 데이터를 받아와 화면에 새롭게 렌더링rendering을 하는 방식이었습니다. 링크 <a href="#">를 클릭하면 해당 페이지로 이동하게 되며, 명시 되어있는 자원을 서버로 요청하여 응답을 받아옵니다.
이처럼, MPA방식은 매 페이지마다 서버측으로 html 문서를 요청하기 때문에 중복되는 데이터를 받아올 수 밖에 없었습니다.

한편, SPA 웹 서비스는 위와 같은 기존 웹서비스의 한계를 보완합니다. 최초 로드 시, 전체 페이지를 로드 한 후부터는 기존의 페이지와 비교하여 갱신이 필요한 특정 부분만을 json형태로 데이터를 가져와 바인딩binding합니다.
따라서, SPA방식은 Ajax(3번 참고)로 데이터를 가져와 필요한 부분만을 갱신 하도록 자바스크립트를 작성합니다.




3. SPA 라우팅에 대한 이해


*라우팅(Routing)이란?
데이터를 보낼 최적의 경로를 선택하는 과정으로, 주어진 데이터를 최적화 된 형태로 주고받을 수 있는 경로를 선택하는 과정 입니다.


① 링크 방식(전통적 방식)


링크 방식은 아래의 과정을 포함하고 있습니다.

(1) link tag(<a href="#">) 클릭
(2) href 속성attribute값인 리소스의 경로가 URL의 path에 추가
(3) 브라우저의 주소창에 path값 표시
(4) 해당 리소스를 서버에 요청

클라이언트 측에서 (1)~(4)를 거치게 되면, 서버 측에서는 완전한 리소스를 html 형태로 응답합니다. 또한, 브라우저 측에서는 이 html을 받아 렌더링 합니다. 이전 페이지에서 새로 받아온 페이지로 전환하는 방식은, 전체 페이지를 다시 렌더링하는 방식으로, 새로고침reload이 발생하고 히스토리history가 남으며 뒤로가기를 사용할 수 있습니다. 이 때, 클라이언트의 리퀘스트마다 중복된 HTML과 JavaScript, CSS를 매번 받아와야 하므로 퍼포먼스 측면에서 손해를 봅니다.



출처: ASP.NET – Single-Page Applications / 전통적인 페이지 수명 주기



② AJAX 방식


이를 보완하기 위하여 자바스크립트에서 비동기Asynchronous로 서버와 브라우저가 데이터를 교환할 수 있는 통신 방식을 활용하게 되는데, 이 통신 방식이 AJAXAsynchronous JavaScript and XML입니다.

페이지에서 업데이트가 필요한 부분만을 로드하여 갱신하고, 새로고침 없이 불필요한 리소스의 중복 요청을 막기 때문에 퍼포먼스 측면에서 더 우수합니다. 데이터 부분이 비워져있는 html을 서버에서 받아오며, 페이지 로드 시 JavaScript로 데이터를 가져와서 채워 넣습니다.



출처: ASP.NET – Single-Page Applications / SPA 수명주기



이 때, AJAX는 URL을 변경 시키지 않으므로 주소창의 주소가 변경되지 않습니다. 이는 브라우저의 히스토리history 관리가 불가능하며, 뒤로가기를 사용할 수 없음을 의미합니다. (이 외에도 SEO에 대한 이슈도 있습니다.)


③ HASH 방식


위의 AJAX를 보완하기 위해 등장한 클라이언트 라우팅 방식이 Hash입니다.

Hash 방식은 앵커anchor를 사용하는 방식으로, link tag(<a href="#hash">등)의 href 속성에 hash(#)를 사용합니다. 클릭 시 문서에서 #뒤에 붙은 id를 가진 요소로 이동합니다.

동일한 URL에서 Hash가 변경 될 경우,
브라우저 측에서는 이를 URL이 바뀐 것으로 인식하나, 실제로 클라이언트 측에서 서버 측으로 리퀘스트를 보내거나 하지는 않습니다. 앵커로 웹 페이지 내부에서의 이동을 위한 것이기 때문입니다. 요청을 하지 않기 때문에 페이지의 갱신은 없으나, 페이지가 각각의 고유한 URL을 가지므로 히스토리history 관리가 가능합니다.

위에 언급한 3가지 방식 외에도 PJAX(html5 pushState + ajax)도 있습니다.




4. Javascript Framework의 주 활용 요소


  • 라우팅
    : 공식적인 라우팅 라이브러리를 제공합니다.

  • 템플릿
    : 렌더링 된 DOM을 기본 인스턴스의 데이터에 선언적으로 바인딩 할 수 있는 HTML 기반 템플릿 구문을 사용합니다.
    (이 부분은 dJango에서도 지원을 해 줬던 것 같다)

  • 컴포넌트 재사용
    Web 컴포넌트는 Web 페이지와 Web 어플리케이션 사이에서 캡슐화 된 재사용이 가능한 HTML 태그를 생성할 수 있습니다.




5. Vue.js


가상 DOM을 활용할 수 있으며, DOM을 통해 모든 요소를 실시간 반응형 컴포넌트로 제작할 수 있는 자바스크립트 프레임워크 입니다. 보통 프로젝트의 규모가 커질수록 다양한 형태의 컴포넌트가 생성되기 때문에, 이를 관리하는 데에 도움이 되는 라우팅 관리 및 글로벌 상태를 관리하는 라이브러리 등을 제공합니다.




6. Vue 라이브러리


① Vue Router

Vue.js을 이용한 SPA 구축에서 라우팅 제어를하기위한 공식 플러그인입니다.

  • VueRouter을 이용하여 URL 히스토리를 관리할 수 있습니다.
  • 브라우저에서 뒤로 가기앞으로 가기 동작을 가능하게끔 하며, 이는 사용성을 향상 시킬 수 있습니다.

[라우팅을 정의하는 형식]

// views/Home.vue (템플릿 구성요소)
<template>
  <div class="home">
    <h1>Home</h1>
  </div>
</template>

// src/router.js (라우팅 정의)
import  Vue  from  ' vue ' 
import  Router  from  ' vue-router ' 
import  Home  from  ' ./views/ '

Vue . use ( Router )

export  default  new  Router ({ 
  mode :  ' history ' , 
  routes :  [ 
    { 
      path :  ' / ' , 
      name :  ' home ' , 
      component :  Home 
    } 
  ] 
})

이후 링크로 정의할 시, 템플릿의 아래와 같은 구문을 삽입하여 사용할 수 있습니다.

  < router-link to = "/" > Home </ router-link > 



②Vue CLI Command Line Interface


Vue-cli로 명령어를 실행 시키면 cli가 자동으로 최적화 된, 프로젝트의 기본 골격을 생성 합니다.  뿐만 아니라, 아래와 같은 설정이 가능합니다.

  • Vue 프로젝트 생성 
  • Vue 라이브러리 관리 
  • Vue 배포 파일 설정 : 최적화된 Webpack*1 형태의 결과물을 생성 합니다.
  • Vue GUI 제공



*1Webpack: JS, CSS, 이미지를 하나의 JS파일로 묶어주는 모듈입니다. 개발자가 작성한 JS와 프로젝트 내 필요한 라이브러리를 로드하는 JS, 작성한 CSS파일 및 이미지 파일까지 정리할 수 있습니다. 이미지 파일의 경우 DataURI (Base64 형식)으로 변환하여 JS 파일에 정리 합니다.

*dJango에서 프로젝트를 생성하고, 라이브러리를 관리하고, 배포 시 정적 파일 관리를 제공했던 것들과 유사한 느낌



③Vuex

많은 컴포넌트의 데이터를 관리하는 것을 목적으로 하는 상태 관리 패턴State Pattern 라이브러리입니다.


1)상태 관리 패턴State Pattern이란?

디자인 패턴 중 하나로, 각 상태를 클래스로 표현하는 패턴입니다. 
하나의 클래스에 하나의 상태를 표현합니다.

조건(혹은 상태)에 부합하는가를 확인하는 처리는 if 문을 사용하곤 합니다.
아래와 같은 경우에는 if 문만을 사용하기에는 유지 보수가 힘들어진다는 특징이 있습니다.
(1) 조건 분기 수가 많은 경우
(2) 코드의 양이 많을 경우
(3) 같은 조건 분기 처리가 여러 곳에서 사용되는 경우

이 때, 개발자가 if문으로 상태를 체크한 뒤, 그 상태에 따라 동작을 호출하지만
스테이트 패턴은 상태를 객체화 하여 특정 상태가 동작을 할 수 있도록 동작의 주체를 위임하는 패턴을 말합니다.


2) 상태 관리 패턴의 적용 이유

MVC 패턴의 복잡한 데이터 흐름 문제를 해결하기 위해서
대규모 어플리케이션의 경우, 복잡한 화면과 데이터의 구성이 필요할 시 Controller에 다수의 Model과 View가 얽히게 됩니다.
따라서 기존의 MVC간의 의존성을 제거하기 힘들어지고, 이는 기능 추가 및 업데이트 시 생기는 문제점을 해결하기 복잡하게 만듭니다.


3) 필요성 및 구성 요소

컴포넌트 간의 데이터 전달을 View, Action, State로 명시적으로 표현하여,
대규모 어플리케이션 개발 시 MVC 패턴에서 발생하는 구조적 오류를 방지합니다.



[예시]

출처: https://vuex.vuejs.org/ (vuex 공식 문서)



(1) 유저가 View(Template)에서 버튼을 클릭
(2) 클릭이라는 Action(Method)이 발생
(3) 해당 Action이 동작을 통해서 State(data)를 변경


(4) 동작 (Getters, Action, Mutaitions)
  • Getters

state로의 접근을 하는 방식에는 2가지 방식이 있습니다.
(1) 직접 this.$store.state등에서 직접 state에 접근하는 방법
(2) Vuex.getters(이하 getters)을 사용하여 state에 접근하는 방법

접근한 state에 특정 처리가 들어가야 하는 경우(filter등)에 getters를 쓰는 것을 추천합니다. 또한, 공식 문서를 참조하면, getters에는 캐시 처리가 포함되어 있기 때문에 computed함께 사용하면 이중 캐싱 처리가 되어버립니다.


  • Actions
    : Vue Components에서 Actions(비동기 로직)을 작성 합니다.


  • Mutations
    : State(Data)를 직접 변경하는 로직들을 작성 합니다.
    이 때, 여러 개의 컴포넌트에서 같은 state값을 동시에 업데이트를 하면 state값의 변경을 추적하는 것이 복잡해집니다. 따라서, mutations는 변경 사항에 대해서 commit 을 이용하여 state를 변경하고 변경 사항을 추적할 수 있도록 합니다.
    이 외에도 getters와는 달리 파라미터를 넘길 수 있으며, computed가 아닌 method로 추가됩니다.




7. 정리

Vue.js는 자바스크립트 프레임워크 중 하나로, SPA 개발에 특화되어 있습니다.

  • SPA
    SPA 웹은 최초 로드 시, 전체 페이지를 로드 한 후부터는 기존의 페이지와 비교하여 갱신이 필요한 특정 부분만을 json형태로 데이터를 가져와 바인딩binding합니다.

  • Routing
    SPA웹의 사용성 한계를 보완하기 위해서는, 라우팅을 담당해 줄 라이브러리를 이용하여 히스토리 관리를 해 주는 것이 필요합니다.

  • State Pattern
    또한 기존의 복잡한 구조의 MVC 패턴의 데이터 흐름을 보완하기 위해서, 상태를 객체화 하여 특정 상태가 동작을 할 수 있도록 동작의 주체를 위임하는 스테이트 패턴을 활용하고 있습니다.

Vue.js로 웹을 개발할 시, 프로젝트 구축 및 기타 작업을 수행해 줄 Vue-Cli, 라우팅을 담당해 줄 Vue Router, 컴포넌트 간의 상태관리를 담당 할 Vuex를 사용합니다.