📌공부하게 된 계기
- B2H 인턴 진행하면서 ‘코드 클린업’ 작업 수행 중이며 약 90% 완료
- 하지만 문제는 어떻게 작업했는지, 발표를 하라는 대표님의 요청이 들어옴
- 사실 처음부터 이렇게 공부하고 시작했어야 했지만, 발표하기 위해서는 논리적으로 왜 이렇게 진행하게 되었는지 설명해야 할 것 같아서 정리하게 됨
📌프로젝트 생성
초기 디렉토리 구조부터 살펴보기 위해 프로젝트를 생성해보자
생성 명령어
vue create 프로젝트명
프로젝트를 생성하면 아래와 같이 초기 디렉토리 구조가 구성된다.
📌프로젝트 생성 시 디렉토리 구조
가장 위에 있는 public 디렉토리 먼저 살펴본 후, src 디렉토리를 살펴볼 것이다. 이후, 디렉토리에 속해있지 않는 나머지 파일들에 대해 알아보겠다.
1. public 디렉토리 구조
가장 먼저 로드되는 파일은 index.html(기본 html)이다.
기본적인 html과 동일하며, 하단 div태그의 id값인 “App”을 통해서 뷰가 호출되어 보여진다.
2. src 디렉토리 구조
📁Assets
assets file을 관리한다. 여기서 assets file이란 “일반적으로 정적인 파일들을 저장하는 디렉토리”이다. 이미지 폰트, CSS 파일등과 같은 프로젝트에서 사용되는 정적인 자원들을 보관하는 용도로 사용된다.
font, icons, images, styles etc.
📁Components
각각의 기능 및 웹페이지들의 화면을 구성할 컴포넌트들로 구성되어 있다.
여기서 컴포넌트란, 아래 그림처럼 조합하여 화면을 구성할 수 있는 블록을 의미한다. 컴포넌트를 활용하면 화면을 빠르게 구조화하여 일괄적인 패턴으로 개발할 수 있으며, 코드를 쉽게 이해하고 재사용할 수 있다.
특징
- 기본 html element를 확장하여 재사용 가능한 코드
- 캡슐화하는데 도움이 됨
- vue component는 vue instance이기도 함.
화면 영역을 각각 Header, Content, Footer, Aside, Main으로 구분한 것이다. tree구조로 나타낸다면 아래와 같이 나타낼 수 있다.
새로운 html 파일의 내용을 생성해 호출할 수 있다.
이렇게 유형별, 기능별로 나누어 프로젝트의 규모가 커져도 유지보수에 용이하고 디버깅도 수월하게 진행할 수 있도록 한다.
컴포넌트 등록하는 부분에 대해서는 다른 디렉토리를 설명한 후, 아래에서 자세히 설명하도록 하겠다.
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
🏷️App.vue
- 최상위 컴포넌트
- 이 파일의 전체 레이아웃은 상단 메뉴부와 컨텐츠부로 구성됨
- 컨텐츠부는
vue.router
를 통해 처리
- 컨텐츠부는
🏷️main.js
- 애플리케이션의 진입점
- 최상위 컨테이너 뷰인
App.vue
파일을 로드하는 구조
간단하게 보자면 아래와 같이 순차적으로 호출하여 불러오고 있는 것이다.
👇
3. 루트 디렉토리 내 파일들
🏷️.gitignore
- git에서 특정 파일 혹은 디렉토리를 관리 대상에서 제외할 때 사용하는 파일
- 파일 안에 기입된 내용들에 대해서는 git에서 관리하지 않음
- 따라서 자동으로 생성되는 로그파일, 프로젝트 설정 파일 등 계속해서 중복되는 파일은 관리 대상에서 제외할 수 있다.
- 이때, 이미 어로드 된 파일(폴더)를 제외한 경우, 다시 커밋해야 함
🏷️babe.config.js(바벨)
- 개발자들이 실행 환경에 구애받지 않고 항상 최신 문법의 자바스크립트로 코딩할 수 있도록 도와주는 유용한 도구
🏷️package-lock.json
- npm을 사용하여 “
package.json
”파일을 또는 “node_modules
” 트리를 수정하면 자동으로 생성되는 파일 - 파일이 생성되는 시점의 의존성 트리에 대한 정보를 가지고 있음
- 업데이트 버전이 오류를 발생시키는 경우도 있기 때문에 안전성을 위해
package-lock.json
은 매우 중요한 파일
🏷️package.json
- 프로젝트 정보와 의존성(dependencies)을 관리하는 문서
- 패키지, 버전이 기록되어 있어 관리하기 쉬움
🏷️vue.config.js
- vue에 대한 설정(웹팩 등)을 하기 위한 환경설정 파일
- 기본 프로젝트 생성 시 포함되어 있지 않아 따로 생성하여 입력해야 함
🏷️Readme.md
- 깃(깃허브)과 같은 저장소에서 프로젝트에 대한 설명을 기입하도록 하는 파일
- 일반적으로 소프트웨어와 함께 배포
📌프로젝트 구조 세팅
vue cli 를 이용해 생성한 프로젝트를 생성한다.
vue init webpack-simple folder-structure
구성은 아래와 같이 구성된다.
.
├─ README.md
├─ index.html
├─ webpack.config.js
├─ package.json
└─ src
├─ main.js
├─ App.vue
└─ assets
└─ logo.png
📌기능별로 구분한 디렉토리 구조
실무에서 개발할 때 사용되는 라우터, 상태관리, 필터, 다국어, 플러그인 등을 이용하면 아래와 같이 폴더를 구분할 수 있다고 한다.
출처: https://joshua1988.github.io/web-development/vuejs/vue-structure/
.
├─ README.md
├─ index.html
├─ webpack.config.js
├─ package.json
└─ src
├─ main.js
├─ App.vue
├─ components 컴포넌트
│ ├─ common
│ └─ ...
├─ routes 라우터
│ ├─ index.js
│ └─ routes.js
├─ views 라우터 페이지
│ ├─ MainView.vue
│ └─ ...
├─ store 상태 관리
│ ├─ auth
│ ├─ index.js
│ └─ ...
├─ api api 함수
│ ├─ index.js
│ ├─ users.js
│ └─ ...
├─ utils 필터 등의 유틸리티 함수
│ ├─ filters.js
│ ├─ bus.js
│ └─ ...
├─ mixins 믹스인
│ ├─ index.js
│ └─ ...
├─ plugins 플러그인
│ ├─ ChartPlugin.js
│ └─ ...
├─ translations 다국어
│ ├─ index.js
│ ├─ en.json
│ └─ ...
├─ images 이미지
├─ fonts 폰트
└─ assets 기타 자원
- 이와 같이 프로젝트를 구성하기 위해서는 ES6의 Import & Export 기능을 정확히 이해해야 함
📌진행중인 프로젝트 구조
.
├── build
├── config
├── dist
├── node_modules
├── src
│ ├── api
│ ├── assets
│ ├── components
│ ├── mixins
│ ├── pages
│ ├── router
│ ├── sass
│ ├── store
│ └── utils
└── static
├── img
└── js
build
: 프로젝트 빌드시 사용되는 도구(ex. webpack) 빌드 설정config
: 프로젝트 환경 설정 (포트번호, 빌드 설정, 프록시 설정 등)dist
: 빌드하면 생성되는 결과물, 웹 서버에서 이 디렉토리를 호스팅하여 배포node_modules
: npm이나 yarn과 같은 외부 라이브러리, 패키지가 설치됨src
: 프로젝트의 소스 코드로 개발자들이 주로 작업하는 영역static
: 정적 파일 저장. 빌드 그대로 복사함- 굳이 src 밑에 component, asset 디렉토리가 있는데 굳이 왜 사용하는가?
- 빌드 시, 불필요한 파일 제거
- 경로 편의성 제공
- 굳이 src 밑에 component, asset 디렉토리가 있는데 굳이 왜 사용하는가?
번외) Vue.js 컴포넌트 등록하기
컴포넌트는 조합하여 화면을 구성할 수 있는 블록을 의미한다고 위에서 말했다. 이제 컴포넌트를 등록하는 방법에 대해 알아보겠다.
등록방법은 1) 전역(Global)과 2) 지역(Local) 두 가지 방법이 있다.
- 전역 컴포넌트 : 모든 범위의 여러 인스턴스에서 공통적으로 사용 가능
- 지역 컴포넌트 : 특정 인스턴스에서만 유효
전역 컴포넌트 등록
- 뷰 라이브러리를 로딩하고 나면 접근 가능한 vue 변수를 이용해 등록한다.
- 전역 컴포넌트를 모든 인스턴스에 등록하려면 Vue 생성자에서
.component()
를 호출하여 수행한다.
<!-- 전역 컴포넌트 등록 형식 -->
Vue.component('컴포넌트 이름', {
// 컴포넌트 내용
});
- 컴포넌트 이름 :
template
속성에서 사용할HTML
사용자 정의 태그(HTML 표준 태그 이외에도 개발자가 직접 정의해 사용할 수 있는 태그)를 의미함 - 컴포넌트 내용 : 컴포넌트 태그가 실제 화면의 HTML 요소로 변환될 때 표시될 속성들을 작성
template
,data
,methods
등 인스턴스 옵션 속성 정의
전역 컴포넌트 등록하는 방법 예제
<html>
<head>
<title>Vue Component Registration</title>
</head>
<body>
<div id="app>
<button>컴포넌트 등록</button>
<my-component></my-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script>
Vue.component('my-component', {
template: '<div>전역 컴포넌트가 등록되었습니다.</div>'
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
- 컴포넌트 이름 :
my-component
- 컴포넌트 내용 :
<div>전역 컴포넌트가 등록되었습니다.</div>
결과
이렇게 최종적으로 컴포넌트가 등록됨
// 컴포넌트 추가 됨
<my-component></my-component>
// 실제로 화면에 그려진 내용
<div>전역 컴포넌트가 등록되었습니다.</div>
지역 컴포넌트 등록
- 지역 컴포넌트 등록은 전역 컴포넌트 등록과 다르게 인스턴스에
component
속성을 추가하고 등록할 컴포넌트 이름과 내용을 정의한다.
<!-- 지역 컴포넌트 등록 형식 -->
new Vue({
components: {
'컴포넌트 이름': 컴포넌트 내용
}
});
- 컴포넌트 이름 : 전역 컴포넌트와 마찬가지로 HTML에 등록할 사용자 태그를 의미
- 컴포넌트 내용 : 컴포넌트 태그가 실제로 화면 요소로 변환될 내용 의미
지역 컴포넌트 등록하는 방법 예제
<script>
var cmp = {
// 컴포넌트 내용
template: '<div>지역 컴포넌트가 등록되었습니다.</div>'
};
new Vue({
el: '#app',
components: {
'my-local-component': cmp
}
});
</script>
- 컴포넌트 이름 :
my-local-component
- 내용 :
cmp
(변수)
결과
<div id="app">
<button>컴포넌트 등록</button>
<my-local-component></my-local-component>
</div>
컴포넌트 불러오기
스크립트 최상단에 import '컴포넌트 이름' from '경로';
를 작성하면 된다.
예시
import GreetingUser from './components/GreetingUser.vue';-
컴포넌트 나오면 단방향 바인딩과 양방향 바인딩이 얘기가 나오는데 이에 대해서는 다음 기회에 자세히 다루며, 관련 사이트에서 찾아보면 된다. (https://velog.io/@sms8377/Javascript-Vue-에서-컴포넌트란)
References
- https://velog.io/@sms8377/Javascript-Vue-에서-컴포넌트란
- https://kdydesign.github.io/2019/04/27/vue-component/
- https://mimah.tistory.com/157
💡TIL
- 효율적이고 발표를 잘 하기 위한 목적으로 찾아보았지만, vue의 구조를 이해하는데에 충분히 도움이 되었던 것 같다.
- 무엇이 필요한지 아닌지 더 잘 알 수 있었다.