가장 먼저 시작한 것은 Vue에 좀 친숙해지기 위해서 화면부터 구성해보기로 했다. 보통의 방법으로 마크업을 만들어서 화면을 구성하는 것 자체는 크게 문제가 안된다고 생각했는데 Vue의 룰에서 화면을 구성을 하는 것은 조금 더 이해가 필요했다. 그런데 또 다른 형태의 Vue의 개발도 있어서 조금 놀랐다.
먼저 Vue의 한글화 공식 홈페이지의 튜토리얼을 보면 아래와 같이 되어있다.
<!-- 도움되는 콘솔 경고를 포함한 개발 버전 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: '안녕하세요 Vue!'
}
})
cdn에 있는 vue js 라이브러리를 선언하고 이후에 마크업과 스크립트를 이용하면 필요한 화면을 구성할 수 있다. 그런데 vue-cli 를 통해서 생성한 프로젝트 안에는 조금 다른 형태로 자리 잡아있었다. 이전 학습했던 개발 환경 만들기의 내용을 살펴보면 된다.
그런데 내가 만난 소스는 좀 달랐는데, /src/App.vue 파일이 존재했다. 그리고 Index.html 에는 webpack 을 통해서 빌드되는 js 파일 하나만 달랑 있는 정도. 마크업은 한개, 한개의 Vue 파일과 하나의 Javascript 코드로 구성이 되어있는데 대략적인 모습을 살펴보면 이렇다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>dev-pets</title>
</head>
<body>
<div id="pet-list"></div>
<script src="/dist/build.js"></script>
</body>
</html>
<template>
<b-container fluid>
<b-img v-for="img in list" :key="img.id" :src="img.src" :alt="img.petName" :title="img.desc" thumbnail fluid ></b-img>
</b-container>
</template>
<script>
module.exports = {
name: "pet-list",
data: function() {
return {
...
};
}
};
</script>
<style>
</style>
import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue'
import App from './App.vue'
Vue.use(BootstrapVue)
new Vue({
el: '#pet-list',
render: h => h(App)
})
Vue 파일로 따로 나와 있는 파일은 template 라고 되어있는 태크와 script, style 로 구성되어있다. 그리고 마지막 js파일에는 모듈에 대한 선언(import)과 Vue component 에 대한 정보가 표시 되어있다. 저 중에 BootstrapVue 는 작업하면서 추가된 내용이다. 위에 있는 공식 홈페이지의 소스는 html 파일 한개에 vue 스크립트와 마크업이 함께 포함되었다면, 아래는 마치 클래스 처럼 vue 파일이 분리되어있고 이를 메인 JS (Java나 C#으로 치면 main 메소드가 선언되어있는)에서 사용하여, HTML 에서 수행이 되는 것 처럼 뭔가 역할이 분담되어있는 모습이다.
VueJS 문서에 살펴보면 '싱글 파일 컴포넌트' 라는 이름으로 소개가 되어있는 방식의 구성이다. 이런 형태로 파일을 구성하는 목적은 복잡도가 높은 프로젝트 일 수록 Javascript 기반의 프론트엔드 개발이 갖는 단점이 명확해 지는데 (위 링크 참조) 이런 단점을 보완하는 목적으로 고안된 방법이라고 한다. 이는 webpack 에서의 모듈 빌드 시스템이 있기에 가능한 방법이라고 하고 조금 더 학습이 필요한 내용이 된다.
'더 복잡한 프로젝트(In more complex projects)' 가 정확히 어떤 규모인지는 알 수가 없다. 최초에 Vue에 접근하기에는 아래와 같은 형태는 뭔가 Vue에게 얻어지는 이미지를 어렵게 만들고 있지는 않을까 싶다.
그리고 대략 만든 것을 화면에 띄워보면 아무것도 나오지 않고 Chrome 브라우저의 DevTools(F12) 를 통해서 살펴보면 콘솔창에 Vue warn 이라는 메시지와 함께 대략적인 오류에 대해서 표시를 해주고 있다.
[Vue warn]: The "data" option should be a function that returns a per-instance value in component definitions.[Vue warn]: Property or method "list" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.[Vue warn]: Property or method "list" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
영어로 디버깅을 해주는데, 대충 알아 듣는 정도라면.. data 라고 표시한 애는 function 으로 쓰라는 이야기. 그 이후의 경고는 list라는 속성이 인스턴스에 정의가 안되어있다는 이야기. 결국 data는 function 으로 고쳐보니 정상적으로 화면이 표시 되었다. 왜 이렇게 해야하는지 잘 모르겠지만 일단은 디버거가 시키는 대로 하니까 의도한 대로 화면이 잘 나온다. 이렇게 이미지 목록을 표시하는 UI를 완성시켰다.
요렇게까지 하고 깃헙에 올렸다.