선언적 렌더링을 위해서 {{}}
템플릿 표현식만 사용할 수 있는 것은 아니다.
v-bind:value
와v-bind:src
에 Vue인스턴스의 속성을 바인드하고있다.
줄여서:value
:src
로 쓸 수 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>basic directive</title>
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="simple">
<input id="a" type="text" v-bind:value="message" />
<div> {{ message }} </div>
<br />
<img v-bind:src="imagePath" />
</div>
<script>
const model = {
message: "첫 번 째 Vue.js앱입니다.",
imagePath: "http://sample.bmaster.kro.kr/photos/61.jpg",
};
const simple = new Vue({
el: "#simple",
data: model,
});
</script>
</body>
</html>
v-model
은 텍스트 박스 뿐 아니라 여러가지 입력폼 필드에서도사용할 수 있다.
checkbox의 경우에는 배열 형태로 저장되고, select태그나 select태그 같은 경우는 단일값과 연결된다.
v-model에서는 몇가지 수식어를 지원한다.
v-model.lazy
의 경우 입력폼에서 이벤트가 발생할 때 입력한 값을 데이터와 동기화한다.
v-model.number
의 경우 number타입 값으로 자동으로 형변환해서 데이터를 변경한다.
v-model.trim
은 문자열의 앞뒤 공백을 자동으로 제거한다.
<body>
<div id="simple">
<div>좋아하는 과일을 모두 골라주세요 :</div>
<input type="checkbox" value="1" v-model="fruits" />사과,
<input type="checkbox" value="2" v-model="fruits" />키위,
<input type="checkbox" value="3" v-model="fruits" />포도,
<input type="checkbox" value="4" v-model="fruits" />수박,
<input type="checkbox" value="5" v-model="fruits" />참외,
</div>
<div id="simple2">선택한 과일들 : <span v-html="fruits"></span></div>
<script>
const model = {
fruits: [],
};
const simple1 = new Vue({
el: "#simple",
data: model,
});
const simple2 = new Vue({
el: "#simple2",
data: model,
});
</script>
</body>
display:none
이 된다.v-if는 조건에 부합되지 않으면 렌더링을 하지 않는다. 그렇기 때문에 자주화면이 변경되는 컴포넌트라면 v-show를 이용하는 것이 좋다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>basic directive</title>
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="account">
잔고 : <input type="text" v-model="balance" />
<br />
<span v-if="balance >= 100000"> Gold </span>
<span v-else-if="balance >= 50000"> Silver </span>
<span v-else-if="balance >= 10000"> Bronze </span>
</div>
<script>
const simple1 = new Vue({
el: "#account",
data: {
balance: 0,
},
});
</script>
</body>
</html>
리액트의 map과 동작은 다르지만 비슷하게 사용된다.
<div v-for="item in list">
<span> {{item.name}} </span>
<span> {{item.tel}} </span>
<span> {{item.address}} </span>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>basic directive</title>
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
</head>
<body>
<div id="example">
<select id="regions">
<option disabled="disabled" selected> 지역을 선택하세요 </option>
<option v-for="(val, key) in regions" v-bind:value="key">{{val}}</option>
</select>
</div>
<script>
const simple1 = new Vue({
el: "#example",
data: {
regions: {
"A": "Asia",
"B": "America",
"C": "Europe",
"D": "Africa",
"E": "Oceania"
}
},
});
</script>
</body>
</html>
배열 데이터인 경우
<tr v-for="(item, index) in list">
객체 데이터인 경우
<option v-for"(val, key, index) in list>
v-for디렉티브와 v-if는 함께 사용될 수 있다. 유의할 점은 v-for가 먼저 수행되고 v-if가 적용된다는 것.
<tr v-for="(item, index) in list" v-if="item.address.includes("서울")">
리스트 요소의 address가 "서울"을 포함한 데이터만 출력된다.
v-pre
디렉티브는 컴파일되지 않는다. <body>
<div id="example">
<span v-pre>{{message}}</span>
</div>
<script>
const simple1 = new Vue({
el: "#example",
data: {
message: "hello world",
},
});
</script>
</body>
때때로 많은 데이터를 출력할 때 콧수염 표현식이 화면에 일시적으로 나타나는 경우가 있다. Vue인스턴스가 el옵션의 템플릿을 컴파일 할 때 발생하는 시간때문에 일어나는 현상이다.
v-cloak을 사용하면 화면 초기에 컴파일 되지 않은 템플릿은 나타나지 않도록 할 수 있다.
computed라는 Vue인스턴스의 속성이다. React에서 props를 받아서 어떤 연산을 수행하는 경우에 해당한다.
<body>
<div id="example">
<input type="text" v-model="num" /> <br />
1부터 입력된 수 까지의 합 : <span> {{sum}} </span>
</div>
<script>
const a = new Vue({
el: "#example",
data: { num: 0 },
computed: {
sum() {
const n = Number(this.num);
if (Number.isNaN(n) || n < 1) return 0;
return ((1 + n) * n) / 2;
},
},
});
</script>
</body>
주의할 점은 this를 사용할 때 기본적으로 Vue인스턴스 자신을 참조하지만, 함수 내부에서 콜백 함수를 실행하거나 했을 때는 this가 다른 값으로 연결될 수 있으므로 주의해야 한다.
한 가지 더 주의할 점은 HTML요소 내부에서 모두 문자열로 다루어 지기 때문에 명시적으로 형변환을 해줄 필요가 있다.
화살표 함수가 this바인딩을 생성하지 않으므로 화살표 함수 내부에서도 Vue객체로접근이 가능한 것
computed: {
filtered: function () {
return this.countries.filter((item, index) => {
const cname = this.countryname.trim();
if (item.name.indexOf(cname) > -1) {
return true;
}
});
},
},
computed: {
filtered: function () {
return this.countries.filter(function (item, index) {
const cname = this.countryname.trim();
if (item.name.indexOf(cname) > -1) {
return true;
}
});
},
},
에러가 발생한다.
computed: {
filtered: function () {
const cname = this.countryname.trim();
return this.countries.filter(function (item, index) {
if (item.name.indexOf(cname) > -1) {
return true;
}
});
},
},
배열메서드를 어떻게 사용하느냐에 따라서 Vue객체에 접근 가능할 수도 불가능 할 수도 있다. 가능하면 배열메서드 외부에서 접근하도록 하자