# Vue JS - The Complete Guide
# Why vue?
- 16kb밖에 안된다: 용량만 작은게 아니고 런타임도 빠르다(앵귤러나 리액트보다)
# Vue 기본
: interpolation이나 string interpolation이라고 부른다.
- data오브젝트 안에 있는 것은 모두
{{}}
를 통해 접근 가능. data.title 이 아니고 그냥 title - Directives:
v-bind
: vue js 인스턴스에 있는 데이터를 바인드해줘라. 다이나믹 데이터를 html attribute에 적용할 수 있는 방법임.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>VueJS</title>
<script type="text/javascript" src="./vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-on:input="changeTitle">
<p v-once>{{ title }}</p> <!-- v-once를 쓰지 않으면 "No Hello"라고 나온다. property가 바뀔때마다 re-rendering하기 때문. -->
<p>{{ sayHello() }}</p>
<a href="{{link}}"></a> <!-- 이러면 안 된다. HTML의 attribute 안에 있는 변수는 디코딩해서 들어가기 때문... 이상한 글자로 깨져서 나옴 -->
<a v-bind:href="link"></a> <!-- 이렇게 v-bind해서 쓰면 원본 그대로 가져옴. 여기에는 {{}}을 쓰지 않는다. 데이터를 다이나믹하게 bind해줌 -->
<a :href="link"></a> <!-- v-bind는 shorthand로 그냥 뗄 수 있다. -->
<p v-html="finishedLink"></p> <!-- Cross-site문제가 안 일어난다는게 확실하면 v-html써서 태그를 그대로 렌더링할 수 있음 -->
</div>
<script>
new Vue({
el: '#app',
data: {
title: "Hello Jaylynn!",
link: 'http://google.com',
finishedLink: '<a href="https://naver.com">Naver</a>'
},
methods: {
changeTitle: function(e) {
this.title = event.target.value;
},
sayHello: function() {
this.title = "No hello";
return 'Hello!';
}
}
});
</script>
</body>
</html>
# Vue 예제: counter
<div id="app">
<button v-on:click="increase(2, $event)">Click</button>
<button v-on:click="counter++">Click</button>
<p>{{counter}}</p>
<p v-on:mousemove="updateCoordinates">
{{x}} / {{y}}
<span v-on:mousemove.stop="">DEAD SPOT</span>
<!-- .stop하면 e.stopPropagation 된다. 여기 mouseover했을 땐 updateCoordinates이벤트 발생 안 됨. .stop.prevent하면 stopPropagation이랑 preventDefault둘 다 된다.-->
</p>
<input type="text" v-on:keyup.enter.space="alertMe">
<!-- keyup이벤트면서 enter랑 space 누를 때 alertMe이벤트 발발된다.-->
<input type="text" v-on:keydown.enter="value = $event.target.value">
<p>{{ value }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
counter: 0,
x: 0,
y: 0,
value: ''
},
methods: {
increase: function(step, event) {
this.counter += step;
},
updateCoordinates: function(e) {
this.x = e.clientX;
this.y = e.clientY;
},
alertMe: function() {
alert('Alert!');
}
}
})
</script>
# Vue 예제: computed, watch
<div id="app">
<input type="text" v-model="name"> <!-- Two-way binding 된다. -->
<p>{{name}}</p>
<button v-on:click="counter++">Click+</button>
<button v-on:click="counter--">Click-</button>
<button @click="counter--">Click</button> <!-- v-on:은 많이 써서 @ shorthand로 줄여쓸 수 있다. -->
<p>Counter: {{counter}}</p>
<p>Result: {{result()}} | {{output}}</p>
</div>
<script>
new Vue({
el: 'app',
data: {
name: 'Jay',
counter: 0
},
computed: { // data에 있는 거랑 똑같이 쓸 수 있지만, 여기선 계산을 할 수 있다.
output: function() { // 이 함수를 methods에 쓴다면, 다른 property가 바뀔때마다 re-rendering을 하겠지(필요 없는데도). 여기 놓으면 counter가 바뀔때만 re-rendering을 한다.
return this.counter > 5 ? '5보다 큼' : '5보다 작음';
}
},
watch: {
counter: function(value) { // counter데이터가 바뀔때마다 불린다. 3초뒤에 리셋함.
var vm = this;
setTimeout(function() {
vm.counter = 0;
}, 2000);
}
},
methods: { // 여기 두면 cache하지 않고 dom이 update할때마다 매번 calculate한다.
result() {
return this.counter > 5 ? '5보다 큼' : '5보다 작음';
}
}
})
</script>
# Vue 예제: Dynamic Styling
<style>
.red{
background-color: red;
}
.green{
background-color: green;
}
</style>
<div id="app">
<div class="demo"
@click="attachRed = !attachRed"
:class="{red: attachRed, blue: !attachRed}"></div>
<div class="demo" :class="divClasses"></div>
<div class="demo" :class="color"></div>
<div class="demo" :class="[color, {red: attatchRed}]"></div>
<div class="demo" :style="{'background-color': color}"></div>
<div class="demo" :style="{backgroundColor: color}"></div>
<div class="demo" :style="myStyle"></div>
<input type="text" v-model="color">
</div>
<script>
new Vue({
el: '#app',
data: {
attachRed: false,
color: 'green',
width: 100
},
computed: {
divClasses: function() {
return {
red: attatchRed,
blue: !attatchRed
}
},
myStyle: function() {
return {
width: this.width + 'px';
}
}
}
})
</script>
# Vue 예제: if, for
<div id="app">
<p v-if="show">이게 보이니</p>
<p v-else>아니면 이게 보이니</p>
<template v-if="show"> <!-- HTML5 태그. DOM에는 안 나온다. 코드에서 그루핑 용도.-->
<h1>Heading</h1>
<p>Inside template</p>
</template>
<p v-show="show">이거슨 쇼이다</p> <!-- v-if는 아예 돔을 없애버리는데 v-show는 display:none 클래스를 추가한다.-->
<button @click="show = !show">Switch</button>
<ul>
<li v-for="(ingredient, i) in ingredients">{{ingredient}} ({{i}})</li>
</ul>
<!-- key를 안 적으면 그냥 돔의 순서만 기억하는데, key 적으면 element자체를 기억한다. 그래서 reorder등이 가능함 -->
<template v-for="(ingredient, i) in ingredients" :key="ingredient">
<h1>{{ingredient}}</h1>
<p>{{i}}</p>
</template>
<button @click="ingredients.push('spices')">Add ingredients</button>
<ul>
<li v-for="person in persons">
<div v-for="(v, k, i) in person">[{{i}}] {{k}} : {{v}}</div>
</li>
</ul>
<span v-for="n in 10">{{n}}</span>
</div>
<script>
new Vue({
el: '#app',
data: {
show: true,
ingredients: ['meat', 'fruit', 'cookies'],
persons: [
{name: 'Max', age: 27},
{name: 'Anna', age: 10},
]
}
})
</script>
# Vue 예제:
- passedData child component 거꾸로...