부지런히 하자 제발 😭
Vue를 프로젝트에 포함하는 방법은 크게 두 가지로 나뉜다.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello Vue 3 CDN</title>
<script src="https://unpkg.com/vue@next"></script> <!-- cdn으로부터 vue 3을 코드에 포함하는 방법 -->
<style>
.app {
font-size: 3em;
}
</style>
</head>
<body>
<div class="app">
{{ msg_hello }}
</div>
<script>
const App = {
data() {
return {
msg_hello: 'Hello Vue 3 CDN'
}
}
}
Vue.createApp(App).mount('.app')
</script>
</body>
</html>
스크립트 코드 내에서 App 객체를 생성할 때 msg_hello라는 변수를 선언 -> 그 값으로 Hello Vue 3 CDN 를 넣음
뷰에서는 데이터 변수로 선언된 값은 템플릿 내 HTML 코드에서 두 개의 중괄호 ({{,}})로 접근 가능
이것을 선언적 렌더링
라고 한다. (DOM 엘리먼트에게 다시 렌더링할 것을 명령하지 않고 DOM과 연결된 상태와 속성이 변경될 때 자동으로 DOM 엘리먼트가 업데이트되는 것을 의미하며, 반대의 개념으로 명령형 렌더링이 있다.)
청크
의 개수로 컴파일하여 브라우저에 전달할 수 있다. 브라우저에서는 컴파일된 코드만 캐시하고 나면 서버로부터 추가적으로 받을 파일이 없으므로 매우 빠른 실행속도를 보여준다.청크?
하나의 트랙을 위한 연속적인 샘플의 집합
프로젝트를 진행할 때 npm을 이용하여 라이브러리들을 컴파일 후, 코드 축소하여 결과물 사이즈를 줄인다. 하나의 js 파일로 만들어지지만, 그 사이즈가 너무 클 경우 비동기적 방식
을 이용해 필요할 때 필요한 컴포넌트를 불러올 수 있는 Lazy 로딩방식
을 이용한다.
Lazy 컴포넌트는 별도의 파일로 저장되어 애플리케이션이 해당 컴포넌트를 필요로 할 때만 서버로부터 받아오므로 매우 효율적이다.
npm install vue@next
npm 커맨드를 이용할 때 -g 옵션을 쓰지 않으면 node_modules
라는 폴더를 생성
-> 이런 패키지 지역설치 방법은 독립된 개발환경을 가질 수 있게 해주기 때문에, 하나의 서버에서 여러 개발자들이 동시에 다양한 프로젝트를 진행 할 수 있게 한다.
Vite ?
Vue 3과 호환성이 높은 Vite는 빌드툴이다. 번들을 생성하는 과정없이 서버의 시작 속도가 빠르며, 모듈화된 컴포넌트의 수정사항을 브라우저로 볼 수 있다.
npm init vite
를 치면 프로젝트가 생성되고 package.json에는 필수 요건들이 최소한으로 들어간 애플리케이션 코드들이 생성된다.
내가 지정한 프로젝트 폴더에서 npm install (혹은 yarn install)
을 하면 node_modules 폴더 안에 패키지들이 설치된다.
yarn dev
을 수행하면 스크립트 속성에 명시된 vite가 npx를 통해 실행된다.
Vite는 개발서버를 실행시켜 http://localhost:3000 로 접속할 수 있게 해준다.
localhost:3000 ? 5173?
1.0.0-next.359 부터 SvelteKit은 dev, build 및 preview 명령에 대해 Vite CLI로 바뀜.
따라서 기본 포트 5173가 Vite의 기본값으로 변경되었다.
vite.config.js
에서 포트 값을 변경할 수 있다.
참고 : https://vitejs.dev/config/server-options.html
Vite는 기본적으로 Rollup을 이용해 번들을 생성한다. dist
폴더 안에 번들화된 js,html,css 그리고 asset 파일들이 생성된다. Vite의 개발서버는 웹 애플리케이션을 개발하는 과정에서 유리하지만, 실제 서버 환경에 애플리케이션을 배포하기 위해서는 번들을 생성하여 그 크기를 줄이고 자바스크립트의 코드를 최소화하는 것이 네트워크 속도
나 보안
면에서 좋다.
먼저 hello-world-vite의 폴더부터 살펴보자
에서는 Vue 컴포넌트들을 포함할 수 있는 루트 엘리먼트인 div 태그
를 가지고 있다.
div
엘리먼트는 app이라는 id값을 가지고 있는데, 이는 컴포넌트들이 어느 곳에 포함이 되어야 하는지 알 수 있는 단서가 되어준다.
import { createApp } from 'vue'
import App from './App.vue' // 루트 컴포넌트를 구성함
import './index.css'
createApp(App).mount('#app')
Vue 2 에서는 인스턴스를 생성할 때 new Vue({})와 같이 코드를 작성했고, 이는 여러 개의 독립된 Vue 인스턴스 생성을 불가능하게 했다. 때문에 Mixins
와 같은 전역 API는 자신의 상태 변경을 모든 뷰 인스턴스와 공유하게 되고, 단위테스트를 진행할 때 큰 오류를 야기했다.
이러한 문제점을 해결하기 위해, createApp
이라는 함수가 나왔다.
createApp
함수를 이용해 애플리케이션 인스턴스를 생성하고 id값이 app인 태그에 마운트시킨다. createApp은 옵션 객체를 받아 루트 컴포넌트를 구성할 수 있다.
마운트란?
어떤 구역을 다른 상위 구역 아래 부착한다는 의미
= 컴포넌트를 DOM트리에 부착할 때
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3.0 + Vite" />
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld,
},
}
</script>
이 파일은 컴포넌트에 대한 다양한 정보를 하나의 파일에 담고 있는 SFC(Single-File-Components)
이다. SFC를 구성하는 파일은 vue라는 확장자를 가지며 크게 세가지로 나뉜다.
이때, script 항목에서 선언된 변수를 이용해 선언적 렌더링을 구현할 수 있다. Vue는 모든 선언적 변수값을 DOM에 즉시 반영하지 않고, 가상 노드에 먼저 반영한 수 최종적으로 완성된 DOM을 브라우저가 렌더링하게 한다.
Vue 3에서는 Vue 2의 Oprions API와 달리 <script setup>
라는 신규 기능을 통해 내부적으로<template>
을 render()
함수로 변경하기 때문에 변수나 컴포넌트를 노출시킬 필요가 없다.
<template>
<h1>{{ msg }}</h1>
<p>
<a href="https://vitejs.dev/guide/features.html" target="_blank">
Vite Documentation
</a>
<a href="https://v3.vuejs.org/" target="_blank"> Vue 3 Documentation </a>
</p>
<button type="button" @click="state.count++">
count is: {{ state.count }}
</button>
<p>
Edit
<code>components/HelloWorld.vue</code> to test hot module replacement.
</p>
</template>
<script setup>
import {defineProps, reactive} from 'vue'
defineProps ({
msg:String
})
const state = reactive({count:0})
</script>
<style scoped>
a {
color: #42b983;
}
</style>
Vue 2에서는 템플릿 태그 안에 하나의 루트 태그만 존재할 수 있었으나, Vue 3에서는 제약이 풀어졌다.
<script setup>
: HelloWorld 컴포넌트는 하나의 버튼을 가지고 있고, state.count라는 변수를 참조하여 해당 값을 1씩 증가 시킴
<style scoped>
:scoped
라는 속성을 사용하지 않으면 정의한 css가 애플리케이션의 전역에 적용된다. 컴포넌트 내에서만 적용되기 위해서는 scoped 속성을 사용해야 한다.