๐ค VUE.JS?
Gunwoo
Posted on March 17, 2021
๐ ๊ถ๊ธํ ๋ชจ๋ ๊ฒ์ ๊ธฐ๋กํฉ๋๋ค.
๐ ๊ธฐ๋ก์์ ๋ฉ์ถ์ง ์๊ณ ๋์ ๊ฒ์ผ๋ก ๋ง๋ญ๋๋ค.
๐ ์๋ชป๋ ์ ๋ณด๊ฐ ์๋ค๋ฉด ์ธ์ ๋ ์ง ๋๊ธ์ ๋จ๊ฒจ์ฃผ์ธ์ :D์ ๋ ์ธ์ ๋ ๋ฆฌ์กํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด์ฉ๋ค Vue๋ฅผ ๊ณต๋ถํ ๊ธฐํ๊ฐ ์์ด์ ๊ณต๋ถํ ๊ธฐ๋ก์ ๋จ๊น๋๋ค.
๐ค VUE.JS?
๊ณต์๋ฌธ์์์ ๋ทฐ๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค(UI)๋ฅผ ๋ง๋ค๊ธฐ ์ํ ํ๋ก๊ทธ๋ ์๋ธ ํ๋ ์์ํฌ๋ผ๊ณ ์๊ฐํ๊ณ ์๋ค.
๐ง ํน์ง
1. ์ ์ฐํ๊ณ ๊ฐ๋ณ๋ค.
2. ๊ธฐ์กด์ ์น์ฑ์ ์ผ๋ถ UI๋ง ์ ์ฉํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
3. SPA๋ฅผ ์ํด ํ์ํ ๋ผ์ฐํฐ๊ธฐ๋ฅ๋ ์ง์ํ๋ค.
4. ๋ฆฌ์กํธ์ฒ๋ผ ๊ฐ์DOM์ ์ง์ํด์ ๋น ๋ฅธ UI ๋ ๋๋ง์ด ๊ฐ๋ฅํ๋ค.
5. ์ปดํฌ๋ํธ ๊ธฐ๋ฐ์ ํ๋ ์์ํฌ์ด๋ค.
6. ์ต๊ทค๋ฌ์ฒ๋ผ ์๋ฐฉํฅ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ์ด ๊ฐ๋ฅํ๋ค.
ํ๋ฉด์ ํ์๋๋ ๊ฐ๊ณผ ๋ชจ๋ธ ๋ฐ์ดํฐ ๊ฐ์ด ๋๊ธฐํ๋์ด ํ์ชฝ์ด ๋ณ๊ฒฝ๋๋ฉด ๋ค๋ฅธ ํ์ชฝ ๋ํ ์๋์ผ๋ก ๋ณ๊ฒฝ๋๋ค.
7. ๋ฆฌ์กํธ์ฒํ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ์ ๊ฐ์ง๊ณ ์๋ค.
์ปดํฌ๋ํธ๋ผ๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ๋ ํญ์ ์์์ปดํฌ๋ํธ์์ ํ์์ปดํฌ๋ํธ ๋ฐฉํฅ์ผ๋ก ๋ฐ์ดํฐ๊ฐ ์ ๋ฌ๋๋ค.
8. MVVM ํจํด์ด๋ค.
Model - View - ViewModel ๊ตฌ์กฐ๋ก ๊ฐ๋ฐํ๋ ๋ฐฉ์์ด๋ค. ํ๋ฉด์ ์์๋ฅผ ์ ์ดํ๋ ์ฝ๋์ ๋ฐ์ดํฐ ๋ก์ง์ฒ๋ฆฌํ๋ ์ฝ๋๋ฅผ ๋ถ๋ฆฌํ์ฌ ์ฝ๋์ ์ดํด๋๋ฅผ ๋์ด๊ณ ์ ์ง ๋ณด์๋ฅผ ํธ๋ฆฌํ๊ฒ ํด์ค๋ค.
View๋ ์ฌ์ฉ์์๊ฒ ๋ณด์ด๋ ํ๋ฉด์ด๋ค.
ViewModel์ View์ Model์ ์ค๊ฐ ์์ญ์ด๊ณ , DOM ๋ฆฌ์ค๋ ์ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ ์ ์ ๊ณตํ๋ ๊ณณ์ด๋ค.
Model์ ๋ฐ์ดํฐ๋ฅผ ๋ด๋ ์์น๋ก, ๋ณดํต ์๋ฒ์์ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ JS ๊ฐ์ฒด ํํ๋ก ์ ์ฅํ๋ค.
DOM Listener๋ DOM์ ๋ณ๊ฒฝ ์ํฉ์ ์ฆ๊ฐ ๋ฐ์ํด์ ํน์ ๋ก์ง์ ์ํํ๋ ์ฅ์น์ด๋ค.
Data Binding์ View์ ๋ด์ฉ๊ณผ Model์ ๋ฐ์ดํฐ๋ฅผ ๋๊ธฐํํด์ฃผ๋ ์ฅ์น์ด๋ค.
๐ง ์ค์น๋ฐฉ๋ฒ
ํ์ด์ง์ CDN package๋ก importํ๋ ๋ฐฉ๋ฒ๋ ์์ง๋ง, npm์ ์ด์ฉํด ์ค์นํ๋ ๊ฒ์ ๊ถ์ฅํ๋ค.
// vue ์ค์นํ๊ธฐ
$ npm install vue@next
// vue cli ์ค์นํ๊ธฐ
yarn global add @vue/cli
// ์๋๋ฉด
npm install -g @vue/cli
// vue cli๋ฅผ ํตํ ํ๋ก์ ํธ ์์ฑ ๋ฐฉ๋ฒ
vue create my-project
// ํน์ ์๋ ๋ช
๋ น์ด๋ฅผ ํตํด ui๋ก ํ๋ก์ ํธ๋ฅผ ์์ฑํ ์ ๋ ์๋ค.
vue ui
Vue ํ์ผ ๊ตฌ์กฐ
Vue์ ๊ตฌ์กฐ์ ๊ฐ ๊ฐ๋ ์ ์ฝ๋๋ก ์์ฑํ๋ฉด์ ๋ณด์์ต๋๋ค.
// Home.vue
<template>
<!-- Vue ํ์ผ์ ์ปดํฌ๋ํธ ํ
ํ๋ฆฟ์ ์ ์ํ๋ template ํํธ, ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๋ script ํํธ, ๊ทธ๋ฆฌ๊ณ ์คํ์ผ๋ง ์ ๋ณด๋ฅผ ์์ฑํ๋ style ํํธ๋ก ๋๋์ด์ ธ ์๋ค. -->
<div>
<!-- ์ค๊ดํธ๋ฅผ ๋๋ฒ ์ฌ์ฉํด์ JS ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฌ์ค ์ ์๋ค. Mustache bracket-->
<h1>Welcome to {{title2}}!</h1>
<!-- v-model ๋ฅผ ์ฌ์ฉํด์ input ๊ฐ์ ๊ฐ์ ธ์ฌ ์ ์๋ค. ๋ํ ์๋ฐฉํฅ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ์ด๊ธฐ์ data()์ ์ ์๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๋ค. -->
<input type="text" v-model="input1" />
<!-- @click ์ ์ด์ฉํด์ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ํจ๋ค๋ง ํ ์ ์๋ค. -->
<!-- v-on์ ์ฝ์ด => v-on:click์ @click์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. -->
<button type="button" @click="getData">Get</button>
<button type="button" @click="setData">Set</button>
<!-- @change ๋ฅผ ์ด์ฉํด์ ๊ฐ์ ๋ณํ๋ฅผ ํ์ธํ๊ณ ์ค์ ํ ์ ์๋ค. -->
<select class="form-control" v-model="region" @change="changeRegion">
<!-- v-for ๋ฅผ ์ด์ฉํด์ ๋ฐ๋ณต๋ฌธ์ ๋๋ฆด ์ ์๋ค. ๋ฐ์ดํฐ ํ์์ด ๋ฐฐ์ด๋ก ์ฃผ์ด์ก์ ๋ -->
<!-- :key๋ v-bind:key์ ์ฝ์ด์ด๋ค -->
<option :key="i" :value="d.v" v-for="(d,i) in options">{{d.t}}</option>
</select>
<div>
<!-- v-if ๋ฅผ ์ด์ฉํด ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ผ ํ ์ ์๋ค. -->
<h3 v-if="awesome"> Vue is awesome! </h3>
<h1 v-else>Oh no ๐ข</h1>
</div>
<!-- v-show ๋ฅผ ์ด์ฉํด display css ์์ฑ์ none ์ฒ๋ผ ํ ์ ์๋ค. <์๋ฆฌ๋จผํธ๋ ๋ ๋๋ง์ด ๋๋ค.> -->
<table class="table table-bordered" v-show="tableShow">
<tr :key="index" v-for="(data,index) in options">
<td>{{data.v}}</td>
<td>{{data.t}}</td>
</tr>
</table>
</div>
</template>
<script>
export default {
// data ๋ฉ์๋๋ฅผ ํตํด ๋ค๋ฃจ๊ณ ์ถ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ํ๊ณ , ๋ค๋ฃฐ ์ ์๊ฒ ๋๋ค.
// ์ด๊ณณ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ํ๊ณ , template์ mustache bracket์ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ธ๋ฉ ํ ์ ์๋ค.
// ๋ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์ค๊ณ ์ถ๋ค๋ฉด(ex. input, select, etc), v-model๋ฅผ ์ฌ์ฉํด์ ์๋์ ๋ณ์์ ํ ๋นํ ์ ์๋ค.
// ์์ฒ๋ผ ์๋ฐฉํฅ์ผ๋ก ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ์ด ๊ฐ๋ฅํ๊ฒ ๋๋ค.
data() {
return {
title: "๋ทฐ ์ฐ์ต",
title2: "Seoul",
input1: "abcd",
options: [
{ v: "S", t: "Seoul" },
{ v: "J", t: "Jeju" },
{ v: "B", t: "Busan" },
],
region: "B",
tableShow: false,
awesome: false,
};
},
// ๋ง์ผ ๋ฐ์ดํฐ์ ์กฐ๊ธ์ด๋ผ๋ ๋ณ๊ฒฝ์ด ์ผ์ด๋๋ฉด ์์น ์์ ์ ์๋ ํด๋น ํจ์๊ฐ ์์ฉ๋๋ค.
// ์์น๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ์์์ ์บ์นํด์ค๋ค. (๋ชจ๋ํฐ๋ง ๊ธฐ๋ฅ) ํน์ ๋ฐ์ดํฐ๋ฅผ ํญ์ ์ฃผ์ํ๊ณ ์๋ค๊ฐ, ๋ณ๊ฒฝ์ด ์ผ์ด๋๋ฉด ๊ทธ ๋ฐ์ดํฐ๋ฅผ ์บ์นํด์ ์ฌ์ฉํ ์ ์๋ค.
// ์ฃผ๋ก ์ฌ์ฉ์๋ก๋ถํฐ์ ์ด๋ฒคํธ๊ฐ ์๋ ํ๋ก๊ทธ๋จ ์์์ ์ด๋ ํ ํน์ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝํ๋ ๊ฒ์ ํ์ธํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ฉด ์ข๋ค.
watch: {
// ์์น์์ ๋ฐ์ดํฐ ๋ช
์ ๊ทธ๋๋ก ๊ฐ์ง๊ณ ์์ ํจ์ํํ๋ก ์์ฑํด์ ์ฌ์ฉํ๋ค.
input1() {
console.log(this.input1);
},
title() {},
},
// Vue์์๋ ๋ชจ๋ ๋ฉ์๋๋ฅผ ์ด๊ณณ์ ์ ์๋ฅผ ํ๋ค.
// ๋ฐ์ดํฐ ์ปจํธ๋กค์ ๊ด๋ จ๋ ๋ชจ๋ ๊ฒ์ ์ด๊ณณ์์ ์ ์ํ๋ค.
methods: {
getData() {
alert(this.input1);
},
setData() {
this.input1 = "12345";
},
changeRegion() {
alert(this.region);
},
},
// Vue ์ธ์คํด์ค์ ๋ผ์ดํ ์ฌ์ดํด
// ๋ง์ผ ์ฒ์ ํ๋ฉด ๋ ๋๋ง์ด ๋๊ธฐ ์ ์ DB์ ๊ฐ์ ๊ณณ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ๋ฟ๋ ค์ผ ํ๋ค๊ณ ํ๋ค๋ฉด ์ด๊ณณ์์ ์ ์ฉํ๋ฉด ๋๋ค.
beforeCreate() {
console.log("beforeCreate");
},
created() {
console.log("created");
},
beforeMount() {
console.log("beforeMount");
},
// ํ๋ฉด์ ์ค์ ๋ก html์ด ๋ก๋ฉ์ด ๋์์ ๋
mounted() {
console.log("mounted");
},
// ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋ ๋, ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝํ๊ธฐ ์ ์ ๋ฌด์ธ๊ฐ๋ฅผ, ํจ์๋ฅผ ์ ์ฉํ๊ณ ์ถ์ ๋ ์ด๊ณณ์ ์ ์ํ๋ฉด ๋๋ค.
beforeUpdate() {
console.log("beforeUpdate");
},
updated() {
console.log("updated");
},
beforeDestroy() {
console.log("beforeDestroy");
},
destroyed() {
console.log("beforeDestroy");
},
};
</script>
๐ Vue ๊ฐ๋ฐ์ ๋์๋๋ ํด & ๋ผ์ด๋ธ๋ฌ๋ฆฌ
-
Vue Devtools
Vue ์ฑ์ ๋ณด๋ค ์ฌ์ฉ์ ์นํ์ ์ธ ์ธํฐํ์ด์ค์์ ๊ฒ์ฌํ๊ณ ๋๋ฒ๊น ํ ์์๊ฒ ๋์์ค๋ค.
-
Vue-cli
๋น ๋ฅด๊ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋๋ก ๋์์ค๋ค.
-
Vue Router
๋ทฐ๋ฅผ ์ด์ฉํ์ฌ SPA์ ์ ์ํ ๋ ์ ์ฉํ ๋ผ์ฐํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค. npm์ผ๋ก ์ค์นํ๊ฑฐ๋ CDN ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
๐ References
Posted on March 17, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024