Intro to Vue.js
What, Why, and How
1. What is Vue.js?
a progressive framework for building user interfaces
1. Front End
2. SPA (Single Page Application)
๋จ์ผ ํ์ด์ง๋ก ๊ตฌ์ฑ๋ ์น ์ดํ๋ฆฌ์ผ์ด์
ํ๋ฉด์ด๋ ์์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ์ฌ์ด๋์์ HTML์ผ๋ก ์ ๋ฌ๋ฐ์ง ์๊ณ (์๋ฒ์ฌ์ด๋ ๋ ๋๋ง X), ํ์ํ ๋ฐ์ดํฐ๋ง ์๋ฒ๋ก๋ถํฐ JSON์ผ๋ก ์ ๋ฌ ๋ฐ์ ๋์ ์ผ๋ก ๋ ๋๋ง
client side rendering!
๋ชจ๋ HTML์ ํด๋ผ์ด์ธํธ๊ฐ ๊ฐ๊ณ ์๊ณ ์๋ฒ์ฌ์ด๋์๋ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ณ JSON์ผ๋ก ๋ฐ๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด์ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋นํด ํ๋ฉด์ ๊ตฌ์ฑํ๋ ์๋๊ฐ ๋น ๋ฅด๋ค
์ฅ์
ํ๋ํ๋ ํ๋ฉด ์ ์ฒด๋ฅผ ๋ ๋๋งํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ํ๋ฉด์ด๋์ด ๋น ๋ฅด๋ค.
ํ๋ฉด์ ํ์ํ ๋ถ๋ถ์ ๋ฐ์ดํฐ๋ง ๋ฐ์์ ๋ ๋๋ง ํ๊ธฐ ๋๋ฌธ์ ์ฒ๋ฆฌ๊ณผ์ ์ด ํจ์จ์ ์ด๋ค.
์ ์ ์ ์ ์ฅํด์ ์ฌ์ฉํ๊ธฐ ํธ๋ฆฌํ๋ค.
๋จ์
์ฒ์ ํ๋ฉด์ ๋ก๋ฉํ ๋, ๋ชจ๋ ํ๋ฉด์ด ๋ฏธ๋ฆฌ ์ค๋น๋์ด ์์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ก๋ฉ์ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค.
์ดํ๋ฆฌ์ผ์ด์ ์ ๊ตฌํํ๋๋ฐ ๋ณด๋ค ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ฉฐ ๋ณต์กํ๋ค.
3. Client Side Rendering

4. MVVN (Model View ViewModel) Pattern

๊ตฌ์กฐ
Model
์ดํ๋ฆฌ์ผ์ด์ ์์ ์ฌ์ฉ๋๋ ๋ฐ์ดํฐ์ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ถ๋ถ
View
์ฌ์ฉ์์์ ๋ณด์ฌ์ง๋ UI ๋ถ๋ถ์ ๋๋ค.
View Model
View๋ฅผ ํํํ๊ธฐ ์ํด ๋ง๋ View๋ฅผ ์ํ Model
View๋ฅผ ๋ํ๋ด ์ฃผ๊ธฐ ์ํ Model์ด์ View๋ฅผ ๋ํ๋ด๊ธฐ ์ํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ํ๋ ๋ถ๋ถ
๋์ ์์
์ฌ์ฉ์์ Action๋ค์ View๋ฅผ ํตํด ๋ค์ด์ค๊ฒ ๋จ
View์ Action์ด ๋ค์ด์ค๋ฉด, Command ํจํด์ผ๋ก View Model์ Action์ ์ ๋ฌ
View Model์ Model์๊ฒ ๋ฐ์ดํฐ๋ฅผ ์์ฒญ
Model์ View Model์๊ฒ ์์ฒญ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์๋ต
View Model์ ์๋ต ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณตํ์ฌ ์ ์ฅ
View๋ View Model๊ณผ Data Bindingํ์ฌ ํ๋ฉด์ ๋ํ๋
์ฅ์
MVVM ํจํด์ View์ Model ์ฌ์ด์ ์์กด์ฑ์ด ์๋ค
๋ํ Command ํจํด๊ณผ Data Binding์ ์ฌ์ฉํ์ฌ View์ View Model ์ฌ์ด์ ์์กด์ฑ ๋ํ ์์ค ๋์์ธํจํด
๊ฐ๊ฐ์ ๋ถ๋ถ์ ๋ ๋ฆฝ์ ์ด๊ธฐ ๋๋ฌธ์ ๋ชจ๋ํ ํ์ฌ ๊ฐ๋ฐํ ์ ์์
์ถ์ฒ: https://beomy.tistory.com/43 [beomy]
Vue.js ๋ MVVM ํจํด์ ViewModel ๋ ์ด์ด์ ํด๋นํ๋ View ๋จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค
5. ๋ฐ์ํ (Reactive)
Vue vs React
๊ณตํต์
๊ฐ์ DOM์ ํ์ฉ
๋ฐ์์ ์ด๊ณ ์กฐํฉ ๊ฐ๋ฅํ component ์ ๊ณต
core library
์๋ง ์ง์คํ๊ณ ์๊ณ routing ๋ฐ ์ ์ญ ์ํ๋ฅผ ๊ด๋ฆฌํ๋companion library
๊ฐ ์์
+
Vue.js ์ ๋ค๋ฅธ ํ๋ ์์ํฌ์์ ๋น๊ต
https://kr.vuejs.org/v2/guide/comparison.html
2. Why Vue.js?
๋ฐฐ์ฐ๊ธฐ ์ฝ๋ค!
$ (์ ์ฝ)
Client Side Rendering
UX ํฅ์
๋น๋๊ธฐ / SPA
ํ๋ ์์ํฌ (ํ๋ ์ฒด์ด์ฆ)์ ์ฅ์ (DX ํฅ์ - ๊ฐ๋ฐ์ ๊ฒฝํ ํฅ์)
No etc, ์ ํ๊ณผ ์ง์ค
์ ์ง/๋ณด์ ์ฉ์ด
Community์ library
3. How?
Setups
VS Code
Vetur
์ค์น
Chrome Web Store
Vue.js devtools
๋ฐ์ ๋ ๊ฐ์ง ์ ํํ๊ธฐ
image-20200525103628912
CDN
(์ง๊ธ์) ์์ ๊ฐ๋ฐ version ์ฌ์ฉํ๊ธฐ
<br>
<br>
### Docs
https://kr.vuejs.org/v2/guide/index.html
- ์ ๋ง ์ ์ ๋ฆฌ๋์ด ์๋ค! ๋ฐ๋ผํด๋ณด๋ฉฐ ์ตํ๊ธฐ!
<br>
<br>
## 4. Getting started with Vue.js
<br>
### 4-0. `el` attribute
- Vue instance ์์ `el` ์์ฑ์ ํตํด Vue instance๊ฐ ๊ทธ๋ ค์ง ์ง์ ์ ์ง์
ex)
> 00_el.html
```html
<body>
<div id="app">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// el์ Vue instance์ ์์ฑ์ด๋ค
const app = new Vue({
el: '#app', // ์ด๋ค ์์์ mount ํ ์ง ๊ฒฐ์ ํ๋ ๊ตฌ๊ฐ
})
console.log(app)
console.log(app.$el)
</script>
</body>
4-1. data
attribute
data
attributeํ๋ฉด์ ๋ณด์ฌ์ง ๋ฐ์ดํฐ๋ฅผ ์ ์
ex)
01_data.html
<body>
<div id="app">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
// Data๋ฅผ ์ ์ธํ๋ ๋ฐฉ๋ฒ
data: { // MVVM ์ Model์ ๋ด๋นํ๋ ๊ตฌ๊ฐ
message:'Hello Vue!'
}
})
console.log(app.message)
</script>
</body>
4-2. Interpolation
ex)
02_interpolation.html
<body>
{{ message }}
<div id="app">
{{ message }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data: {
message:'Hello Vue!'
}
})
console.log(app.message)
</script>
</body>
4-3. v-text
v-text
Vannila JS์ DomElement.innertext์ ๊ฐ์
v- ์ ๋์ฌ๋ก ์์ํ๋ ๊ฒ๋ค์ ๋ชจ๋ directive(๋ช ๋ น)๋ผ๊ณ ๋ถ๋ฅธ๋ค
ex)
03_v-text.html
<div id="app">
<p v-text="message"></p>
<p> {{message}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data: {
message:'์์ ํ ๊ฐ์์!'
}
})
console.log(app.message)
</script>
</body>
4-4. v-if
v-if
if ํ๊ฐ์์ false์ด๋ฉด ํ๋ฉด์ ๋์ค์ง ์๋๋ค
ex)
04_v-if.html
<body>
<div id="app">
<p v-if="bool1">
true
</p>
<p v-if="bool2">
false
</p>
<p v-if="str1">
'Yes'
</p>
<p v-if="str2">
''
</p>
<p v-if="num1">
1
</p>
<p v-if="num2">
0
</p>
<!-- JavaScript ๋ empty array๋ true-->
<p v-if="arr">
[] => js๋ ๋น ๋ฐฐ์ด์ด true ํ๊ฐ
</p>
<p v-if="arr.length">
[].length๋ฅผ ํตํด 0์ธ์ง๋ก ํ์ธ
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data: {
bool1: true,
bool2: false,
str1: 'Yes',
str2: '',
num1: 1,
num2: 0,
arr: [],
}
})
console.log(app.message)
</script>
</body>
4-5. v-if
, v-else-if
, v-else
v-if
, v-else-if
, v-else
ex)
05_v-if-elseif-else.html
<body>
<div id="app">
<p v-if="username === 'master'">
Hello Master
</p>
<p v-else>
Hello User
</p>
<p v-if="number > 0">
์์
</p>
<p v-else-if="number < 0">
์์
</p>
<p v-else>
0
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data: {
username: 'master',
number: 0,
}
})
</script>
</body>
4-6. v-for
v-for
ex)
06_v-for.html
<body>
<div id="app">
<ul>
<li v-for="number in numbers">{{ number +1 }}</li>
</ul>
<ol>
<li v-for="teacher in teachers"> {{ teacher.name }}</li>
</ol>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data: {
numbers: [0,1,2,3,4,5],
teachers: [
{ name: 'neo'},
{ name: 'tak'},
],
}
})
</script>
</body>
4-7. v-bind
v-bind
ํ์ค HTML ์์ฑ๊ณผ Vue Instance๋ฅผ ์ฐ๋ํ ๋ ์ฌ์ฉ (+ a)
v-bind:
๋ฅผ ์ค์ฌ์:
์ผ๋ก ์ธ ์ ์๋ค!
ex)
07_v-bind.html
<body>
<div id="app">
<a href=" {{ googleUrl }}">Bad Google link</a>
<a v-bind:href="googleUrl">Good Google link</a>
<a :href="naverUrl">Naver link</a>
<img :src="randomImageUrl" v-bind:alt="altText">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data: {
googleUrl: 'https://google.com',
naverUrl: 'https://naver.com',
randomImageUrl: 'https://picsum.photos/200',
altText: 'random-image',
}
})
</script>
</body>
4-8. methods
attribute
methods
attributeex)
08_methods.html
<body>
<div id="app">
{{ message }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data: {
message:'Hello Vue!'
},
methods: {
alertWarning: function() {
alert('WARNING!')
},
// Syntatic sugar : ์์ ์๋๋ ์์ ํ ๊ฐ๋ค!
alertMessage(){
alert(this.message)
// Vue ์ธ์์ this -> JS์ ๋ค๋ฅด๊ฒ ์ ์ฉ๋จ
// : ๋ด๋ถ์ ์ผ๋ก proxy system์ด ์ ์ฉ๋๊ธฐ ๋๋ฌธ
},
changeMessage(){
this.message = 'Changed message'
}
}
})
</script>
4-9 v-on
v-on
listener๋ฅผ ๋ฑ๋กํ๋ ๊ฒ
v-on:
์ ์ค์ฌ์@
์ผ๋ก ์ธ ์ ์๋ค!
ex)
09_v-on.html
<body>
<div id="app">
<h1>{{ message }}</h1>
<button v-on:click="alertWarning"> Alert Warning </button>
<button v-on:click="alertMessage"> Alert Message </button>
<button @click="changeMessage"> Change Message </button>
<hr/>
<!-- enter key ๋๋ ธ์ ๋ event ๋ฐ์-->
<input v-on:keyup.enter="onKeyUp" type="text">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data: {
message:'Hello Vue!'
},
methods: {
alertWarning: function() {
alert('WARNING!')
},
alertMessage(){
alert(this.message)
},
changeMessage(){
this.message = 'Changed message'
},
onKeyUp(event) {
this.message = event.target.value
}
}
})
</script>
</body>
4-10. v-model
v-model
input, select, textarea ์์๋ง ๊ฐ๋ฅํ ์๋ฐฉํฅ binding
v-model
๋๋ ํฐ๋ธ๋ฅผ ์ฌ์ฉํ์ฌ ํผ input๊ณผ textarea ์๋ฆฌ๋จผํธ์ ์๋ฐฉํฅ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ์ ์์ฑํ ์ ์๋คv-model
์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ฉ์ ์ ๋ ฅ ์ด๋ฒคํธ์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฐ์ดํธํ๋ โsyntax sugarโ ๋คv-model
์ ๋ชจ๋ form ์๋ฆฌ๋จผํธ์ ์ด๊ธฐvalue
์checked
๊ทธ๋ฆฌ๊ณselected
์์ฑ์ ๋ฌด์ํ๋คํญ์ Vue ์ธ์คํด์ค ๋ฐ์ดํฐ๋ฅผ ์๋ณธ ์์ค๋ก ์ทจ๊ธ
์ปดํฌ๋ํธ์
data
์ต์ ์์ ์๋ JavaScript์์ ์ด๊ธฐ๊ฐ์ ์ ์ธํด์ผํจ!
ex)
10_v-model.html
<body>
<div id="app">
<h1> {{ message }}</h1>
<!-- ์ฌ์ฉ์ ์
๋ ฅ <=> data๋ฅผ ์์ ํ ๋๊ธฐํ ์ํค๊ณ ์ถ๋ค! -->
<!-- v-model => input, select, textarea ์์๋ง ๊ฐ๋ฅํ ์๋ฐฉํฅ binding -->
<hr/>
<!-- ๋จ๋ฐฉํฅ binding ( input => data )-->
1way:
<input @keyup="onInputChange" type="text">
<hr/>
<!-- ์๋ฐฉํฅ binding ( input <=> data )-->
2way:
<input @keyup="onInputChange" type="text" :value="message" />
<hr/>
<!-- v-model -->
v-model/2way:
<input v-model="message" type="text">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hi',
},
methods: {
onInputChange(event){
this.message = event.target.value
}
}
})
</script>
</body>
4-11. v-show
v-show
v-if ๋ ํ๊ฐ(t/f) ๊ฐ ์์ฃผ ๋ฐ๋์ง ์์ ๋ ์ ๋ฆฌํ๋ค
=> ์ด๊ธฐ rendering cost๊ฐ ์ ๋ค
v-show๋ ํ๊ฐ (t/f)๊ฐ ์์ฃผ ๋ฐ๋ ๋ ์ข๋ค
=> toggle cost๊ฐ ์ ๋ค
v-show๋ ์ด๋ฏธ DOM ์ ์ค๋น ํด๋จ๋๋ฐ display๋ง none ์!
ex)
11_v-show.html
<div id="app">
<button @click="changeF">changeF</button>
<p v-if="t">
This is v-if with true
</p>
<p v-if="f">
This is v-if with false
</p>
<p v-show="t">
This is v-show with true
</p>
<p v-show="f">
This is v-show wit false
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data: {
t: true,
f:false,
},
methods: {
changeF(){
this.f = !this.f
}
}
})
</script>
</body>
+
Lodash
A modern JavaScript utility library delivering modularity, performance & extras.
CDN
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
Last updated
Was this helpful?