'개발 > JavaScript30' 카테고리의 다른 글
5. Flex Panel Gallery (0) | 2017.04.05 |
---|---|
4. Array Cardio Day 1 (0) | 2017.04.04 |
3. CSS Variables (0) | 2017.04.03 |
1. JavaScript Drum Kit (0) | 2017.03.30 |
0. JavaScript30 Challenge (0) | 2017.03.30 |
5. Flex Panel Gallery (0) | 2017.04.05 |
---|---|
4. Array Cardio Day 1 (0) | 2017.04.04 |
3. CSS Variables (0) | 2017.04.03 |
1. JavaScript Drum Kit (0) | 2017.03.30 |
0. JavaScript30 Challenge (0) | 2017.03.30 |
v-model
디렉티브를 사용하여 폼 input과 textarea 엘리먼트에 양방향 데이터 바인딩 생성 가능
입력 유형에 따라 엘리먼트를 업데이트하는 방법을 자동으로 선택함
이때 v-model
은 기본적으로 사용자 입력 이벤트에 대한 데이터를 업데이트하는 “syntax sugar”이며 일부 경우에는 주의해야 함
v-model
은 모든 form 엘리먼트 초기 value
, checked
, selected
속성 무시,
컴포넌트의 data
옵션 안에 있는 JavaScript에서 초기값을 선언해야 한다.
v-model
는 한국어가 업데이트가 되지 않으므로 input
을 사용해야 함.
<input v-model="message" placeholder="수정해보세요">
<p>메시지: {{ message }}</p>
박스에 내용을 넣으면 실시간으로 message에 바인딩되어 결과가 나타남
<span>여러 줄을 가지는 메시지:</span>
<p style="white-space: pre">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="여러줄 입력하세요"></textarea>
마찬가지로 message에 바인딩 되어 결과 나타남
이때 <textarea>{{ text }}</textarea>
는 작동하지 않음
하나의 체크박스는 단일 boolean 값을 가짐
<input type="checkbox" id="checkbox" v-model="checked">
</label for="checkbox">{{ checked }}</label>
//HTML
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>체크한 이름: {{ checkedNames }}</span>
//JavaScript
new Vue({
el: '...',
data: {
checkedNames: []
}
})
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>선택: {{ picked }}</span>
//HTML
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>선택함: {{ selected }}</span>
//JavaScript
new Vue({
el: '...',
data: {
selected: ''
}
})
<select v-model="selected" multiple>
을 쓰면 다중선택 가능
v-for
를 이용한 동적 욥션 렌더링
//HTML
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
//JavaScript
new Vue({
el: '...',
data: {
selected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
})
라디오, 체크박스, 셀렉트 옵션의 경우 v-model
바인딩 값은 보통 정적인 문자열이다
<!-- `picked` 는 선택시 문자열 "a" 입니다 -->
<input type="radio" v-model="picked" value="a">
<!-- `toggle` 는 true 또는 false 입니다 -->
<input type="checkbox" v-model="toggle">
<!-- `selected`는 "ABC" 선택시 "abc" 입니다 -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
그러나 동적 속성에 바인딩 할때는 v-bind
를 사용하면 되고, 이것을 사용하면 입력값을 문자열이 아닌 값에 바인딩 할 수 있다.
//HTML
<input type="checkbox"
v-model="toggle"
v-bind:true-value="a"
v-bind:false-value="b"
>
//JavaScript
// 체크 하면:
vm.toggle === vm.a
// 체크하지 않으면:
vm.toggle === vm.b
//HTML
<input type="radio" v-model="pick" v-bind:value="a">
//JavaScript
vm.pick === vm.a
//HTML
<select v-model="selected">
<!-- inline object literal -->
<option v-bind:value="{ number: 123 }">123</option>
</select>
//JavaScript
typeof vm.selected
vm.selected.number
.lazy
기본적으로, v-model
은 각 입력 이벤트 후 입력과 데이터를 동기화 함
.lazy
를 추가해 change
이벤트 이후에 동기화 할 수 있음
<!-- "input" 대신 "change" 이후에 동기화 됩니다. -->
<input v-model.lazy="msg>
뭔말인지 모르겠다..
.number
사용자 입력이 자동으로 숫자로 바뀌게 하려면 다음과 같이 사용
<input v-model.number="age" type="number">
.trim
input을 자동으로 trim 하려면 다음과 같이 하면 된다.
<input v-model.trim="msg">
추가적으로 재사용 가능한 input을 컴포넌트로 만들 수 있고 v-model
에도 작동함
Vue 기본자료 포스팅 완료! (0) | 2017.04.06 |
---|---|
10. 컴포넌트 (0) | 2017.04.06 |
8. 이벤트 핸들링(v-on) (0) | 2017.03.31 |
7. 리스트 렌더링(v-for, v-if) (0) | 2017.03.31 |
6. 조건부 렌더링(v-if, v-else-if, v-else, v-show) (0) | 2017.03.30 |
v-on
디렉티브를 사용, DOM 이벤트를 듣고 트리거 될 때 JavaScript 실행 가능
//HTML
<div id="example-1">
<button v-on:click="counter += 1">Add 1</button>
<p>버튼 클릭 횟수는 {{ counter }} 입니다.</p>
</div>
//JavaScript
var example1 = new Vue({
el: '#example-1',
data: {
counter: 0
}
});
많은 이벤트 핸들러의 로직은 복잡할 것이므로, Javascript를 v-on
속성값으로 보관하는 것은 간단하지 않음. 이 때문에 v-on
이 호출하고자 하는 메소드의 이름을 받는 이유이다
//HTML
<div id="example-2">
<button v-on:click="greet">Greet</button>
</div>
//JavaScript
var example2 = new Vue({
el: '#example-2',
data: {
name: 'Vue.js'
},
methods: {
greet: function (event) {
alert('Hello ' + this.name + '!' )
if (event) {
alert(event.target.tagName)
}
}
}
})
example2.greet()
//HTML
<div id="example-3">
<button v-on:click="say('hi')">Say hi</button>
<button v-on:click="say('what')">Say what</button>
</div>
//JavaScript
new Vue({
el: '#example-3',
methods: {
say: function (message) {
alert(message)
}
}
})
때로 인라인 명령문 핸들러에서 원본 DOM 이벤트에 엑세스 해야할 수도 있음
$event
를 사용함
//HTML
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
//JavaScript
methods: {
warn: function (message, event) {
if (event) event.preventDefault()
alert(message)
}
}
이벤트 핸들러 내부에서 event.preventDevault()
또는 event.stopPropagation()
를 호출하는 것은 매우 보편적인 일이다.
메소드 내에서 쉽게 이 작업을 할 수 있지만, DOM 이벤트 세부 사항을 처리하는 대신 데이터 로직에 대한 메소드만 사용할 수 있으면 더 좋을 것같다
고 문서에 써있는데 무슨말인지 잘 모르겠지만, 저걸 해결하기 위해 v-on
이벤트에 이벤트 수식어를 제공함
- .stop
- .prevent
- .capture
- .self
- .once
<!-- 클릭 이벤트 전파가 중단됩니다 -->
<a v-on:click.stop="doThis"></a>
<!-- 제출 이벤트가 페이지를 다시 로드 하지 않습니다 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 수식어는 체이닝 가능합니다 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 단순히 수식어만 사용할 수 있습니다 -->
<form v-on:submit.prevent></form>
<!-- 이벤트 리스너를 추가할 때 캡처모드를 사용합니다 -->
<!-- 즉 내부 엘리먼트를 대상으로 한 이벤트가 해당 엘리먼트에서 처리되기 전에 처리됩니다. -->
<div v-on:click.capture="doThis">...</div>
<!-- event.target이 엘리먼트 자체인 경우에만 트리거를 처리합니다 -->
<!-- 자식 엘리먼트에서는 안됩니다 -->
<div v-on:click.self="doThat">...</div>
<!-- 클릭 이벤트는 최대 한번만 트리거 됩니다. -->
<a v-on:click.once="doThis"></a>
키보드 이벤트를 청취할 때 v-on
에 키 수식어를 추가할 수 있음
키코드를 전부 기억하는 것은 어렵기 때문에 Vue는 일반적으로 사용되는 키의 별칭을 제공함
<!-- keyCode가 13일 때만 vm.submit()을 호출합니다 -->
<input v-on:keyup.13="submit">
<!-- 위와 같습니다 -->
<input v-on:keyup.enter="submit">
<!-- 약어 사용도 가능합니다 -->
<input @keyup.enter="submit">
.enter
.tab
.delete
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
(맥에서 commad, 윈도우는 윈도우키) .left
.right
.middle
// v-on:keyup.f1 이 가능합니다
Vue.config.keyCodes.f1 = 112
HTML로 된 리스너를 사용하는 이유를 모른다면 왜 HTML에 JS요소를 넣어서 쓰냐 하고 이해하기 힘들 수 있다. 다음은 그 이유다
10. 컴포넌트 (0) | 2017.04.06 |
---|---|
9. 폼 입력 바인딩 (0) | 2017.03.31 |
7. 리스트 렌더링(v-for, v-if) (0) | 2017.03.31 |
6. 조건부 렌더링(v-if, v-else-if, v-else, v-show) (0) | 2017.03.30 |
5. 클래스와 스타일 바인딩(Class and Style Bindings) (0) | 2017.03.29 |
v-for 디렉티브를 사용해 배열기반 리스트 렌더링
item in items 형태로 특별한 문법이 필요험(items은 원본 데이터 배열, item은 반복되는 배열의 값) / in 대신 of 사용 가능
//HTML
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
//JavaScript
var example1 = new Vue({
el: "#example-1",
data: {
items: [
{ message: "Foo" },
{ message: "Bar" }
]
}
})
위의 코드는 렌더링 되어 아래와 같은 결과가 나온다
v-for 블록 안에는 부모 범위 속성에 대한 모든 권한이 있고 현재 항목의 인덱스에 대한 두 번째 전달인자 옵션을 제공
//HTML
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
//JavaScript
var example2 = new Vue({
el: "#example-2",
data: {
parentMessage: "Parent",
items: [
{ message: "Foo" },
{ message: "Bar" }
]
}
})
결과는 아래와 같다
- Parent - 0 - Foo
- Parent - 1 - Bar
템플릿 v-if와 마찬가지로, 태그를 사용해 여러 엘리먼트의 블럭을 렌더링 할 수 있음
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divivder"></li>
</template>
</ul>
v-for을 사용하여 객체의 속성을 반복할 수도 있음
//HTML
<ul id="repeat-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
//JavaScript
new Vue({
el: "#repeat-object",
data: {
object: {
firstName: "John",
lastName: "Doe",
age: 30
}
}
})
결과
- John
- Doe
- 30
v-for은 정수를 사용할 수 있음. 이 경우 템플릿을 여러번 반복 함
<div>
<span v-for="n in 10">{{ n }}</span>
</div>
결과
1 2 3 4 5 6 7 8 9 10
나중에 다시 작성 예정
v-for
와 v-if
가 같은 노드에 존재하면 v-for
이 우선 순위를 가짐.
둘을 같이 쓰는건 아래 코드와 같이 일부 항목만 렌더링 할때 유용함
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
위의 경우는 완료되지 않은 todo가 렌더링 된다
엘리먼트를 전부 렌더링 하고, 조건문으로 보여지고 싶은 부분만 추리고 싶으면
v-if를 래퍼 엘리먼트로 옮기면 된다
<ul v-if="shouldRenderTodos">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
v-for
에서 렌더링된 엘리먼트 목록을 갱신할 때 “in-place patch” 전략 사용
데이터 항목의 순서가 변경된 경우 항목의 순서와 일치하도록 DOM요소를 이동하는 대신 Vue는 각 요소를 적절한 위치에 패치하고 해당 인덱스에서 렌더링할 내용을 반영하는지 확인함
이때 재정렬 할 수 있도록 각 항목에 고유속성 key
를 제공해야 함
<div v-for="item in items" :key="item.id">
<!-- content -->
</div>
v-for
에는 항상 key
를 추가하는 것이 좋음
예외 : 반복되는 DOM 내용이 단순하지 않거나, 의도적인 성능 향상을 위해 기본 동작에 의존하는 경우 => 그냥 복잡하게 반복문을 썼을때를 제외하고는 key
를 쓰라는 것.
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
filter()
concat()
slice()
JavaScript의 제한으로 Vue는 2가지 경우를 감지할 수 없음
1. 인덱스로 배열에 있는 항목을 직접 설정하는 경우 vm.items[indexOfItem] = newValue
=> Vue.set(example1.items, indexOfItem, newValue)
사용
2. 배열의 길이를 수정하는 경우 vm.items.length = newLength
=> splice
사용
9. 폼 입력 바인딩 (0) | 2017.03.31 |
---|---|
8. 이벤트 핸들링(v-on) (0) | 2017.03.31 |
6. 조건부 렌더링(v-if, v-else-if, v-else, v-show) (0) | 2017.03.30 |
5. 클래스와 스타일 바인딩(Class and Style Bindings) (0) | 2017.03.29 |
4. 계산된 속성과 감시자 (0) | 2017.03.28 |
5. Flex Panel Gallery (0) | 2017.04.05 |
---|---|
4. Array Cardio Day 1 (0) | 2017.04.04 |
3. CSS Variables (0) | 2017.04.03 |
2. CSS + JS Clock (0) | 2017.04.03 |
0. JavaScript30 Challenge (0) | 2017.03.30 |
5. Flex Panel Gallery (0) | 2017.04.05 |
---|---|
4. Array Cardio Day 1 (0) | 2017.04.04 |
3. CSS Variables (0) | 2017.04.03 |
2. CSS + JS Clock (0) | 2017.04.03 |
1. JavaScript Drum Kit (0) | 2017.03.30 |
Vue에서는 v-if 디렉티브를 사용해 조건문을 작성
여느 다른 언어의 조건문과 같이 v-if , v-else-if, v-else 사용
v-if 는 디렉티브이기 때문에 하나의 엘리먼트에 추가 해야함
여러개의 엘리먼트를 전환할 때는 보이지 않는 래퍼 역할을 하는 엘리먼트에 v-if 를 사용할 수 있고 렌더링 결과는 엘리먼트는 포함되지 않음
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
v-else 디렉티브를 사용해 v-if 에 대한 “else 블록”을 나타낼 수 있음
<div v-if="Math.random() > 0.5">
you can see me
</div>
<div v-else>
you can't see me
<div>
v-else-if 는 v-if 에 대한 “else if 블록” 역할, 여러 개 사용 가능
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
순서는 v-if > v-else-if > v-else
Vue는 효율적으로 엘리먼트를 렌더링하려 시도하며, 종종 처음부터 렌더링을 하지 않고 다시 사용함.
아래 예는 사용자가 여로 로그인 유형을 전환할 수 있도록 허용하는 경우
<template v-if="loginType === 'username'">
<label>사용자 이름</label>
<input placeholder="이름을 입력하세요">
</template>
<template v-else>
<label>이메일</label>
<input placeholder="이메일 주소를 입력하세요">
</template>
위의 코드에서 로그인타입을 바꿔도 원래 작성한 내용은 유지되는데
이때 placeholder 속성 뒤에 key=”username-input”, key=”email-input” 을 각각 적어주면 로그인 유형 변경시 내용도 초기화가 된다
엘리먼트를 조건부로 표시하기 위한 또 다른 옵션은 v-show 디렉티브이다
<h1 v-show="ok">안녕</h1>
위와같이 사용하며 v-if 와의 차이점은 v-show 가 있는 엘리먼트는 항상 렌더링 되어 DOM에 남아있고, display CSS 속성을 토글해 나타내고 감춤
v-if 는 조건부 블럭 안의 내용에 따라 제거되고 만들어지고
v-show 는 우선 렌더링이 되고 CSS 속성으로 감추고 보여줌
따라서 v-if 는 토글 할 때의 비용이 높고, v-show 는 초기 렌더링 비용이 높으므로
자주 바뀐다면 v-show , 바뀌지 않는다면 v-if 를 권장함
뒤에 나오겠지만 v-if 보다 v-for 이 높은 우선순위를 가지고 있음
8. 이벤트 핸들링(v-on) (0) | 2017.03.31 |
---|---|
7. 리스트 렌더링(v-for, v-if) (0) | 2017.03.31 |
5. 클래스와 스타일 바인딩(Class and Style Bindings) (0) | 2017.03.29 |
4. 계산된 속성과 감시자 (0) | 2017.03.28 |
3. Vue 템플릿 문법 (0) | 2017.03.27 |
데이터 바인딩은 엘리먼트의 클래스 목록과 인라인 스타일을 조작하기 위해 사용되며 v-bind 로 처리함
클래스를 동적으로 토글하기 위해 v-bind:class 에 객체 전달
<div class="static" v-bind:class="{ active : isActive }"></div>
data: {
isActive: true
}
위의 코드에서 볼수있다시피 일반 class 속성과 v-bind:class 를 같이 쓸수 있으며
이때 data는 참 속성으로 active에 렌더링되어 아래와 같은 코드가 된다
<div class="static active"></div>
객체를 반환하는 계산된 속성(computed)에도 바인딩 할 수 있으며, 이것이 일반적이며 가장 강력한 방법이다.
//HTML
<div v-bind:class="classObject"></div>
//JavaScript
data: {
isActive: true,
error: null
},
computed: {
classObject: function() {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal',
}
}
}
위의 예제 코드에서 computed > classObject의 함수 안에서 계산 후 반환값으로 active 와 ‘text-danger’ 값을 정하고 HTML의 v-bind:class 에 전해주면 렌더링되어 원하는 결과를 얻을 수 있다.
v-bind:class=”[ ]” 와같이 배열로 담을 수 잇고 이때는 data 에 참, 거짓 속성이 아닌 원하는 클래스명의 이름을 적어주면 그대로 렌더링 되어 결과로 나타남. 아래의 예제로 이해를 해보자
//HTML
<div v-bind:class="[activeClass, errorClass]"></div>
//JavaScript
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
<div class="active text-danger"></div>
또한 조건부 토글도 가능하며 이는 삼항 연산자를 사용함
<div v-bind:class="[isActive ? activeClass : '', errorClass]">
<div v-bind:class="[isActive && activeClass, errorClass]">
<div v-bind:class="[{ active: isActive }, errorClass]">
이런식으로도 줄여서 작성이 가능하다고 함
위에서 isActive 가 참이면 active 클래스가 적용되고, 거짓이면 error 클래스가 적용됨
-컴포넌트란?
기본 HTML 엘리먼트를 확장해 재사용 가능한 코드를 캡슐화 하는데 사용
컴포넌트를 어떤식으로 생성을 하나보면
Vue.component('my-component', {
template: '<p class="foo var">Hi</p>'
})
이렇게 컴포넌트를 정의를 하면 HTML에서 작성할 수 있음
<my-component class="baz boo"></my-component>
위와 같이 작성을 하면 렌더링 되어 아래 코드로 나타남
<p class="foo bar baz boo">Hi</p>
클래스 바인딩도 동일함
<my-component v-bind:class=" { active: isActive }"></my-component>
여기서 isActive 가 참일 때 렌더링 된 HTML은 아래 코드와 같다
<p class="foo bar active">Hi</p>
v-bind:style 객체 구문은 CSS 처럼 보이지만 JavaScript 객체이다
속성 이름에는 camelCase와 kebab-case를 사용해야함
camelCase는 들어봤는데 kebab-case는 처음 들어봐서 검색을 해봄
-camelCase에서 대문자 대신에 소문자로 고치고 - 를 붙인다
camelCase => ‘camel-case’
이때 kebab-case를 사용하려면 따옴표를 함께 사용해야 함
<div v-bind:style=" { color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
v-bind:style 에 대한 배열 구문은 같은 스타일의 엘리먼트에 여러 개의 스타일 객체를 사용 할 수 있음
<div v-bind:style="[baseStyles, overridingStyles]">
v-bind:style 에 브라우저 벤더 접두어(ex: -webkit-, -moz- 등등)가 필요한 CSS 속성을 사용하면 Vue는 자동으로 해당 접두어를 감지해 스타일을 적용함
7. 리스트 렌더링(v-for, v-if) (0) | 2017.03.31 |
---|---|
6. 조건부 렌더링(v-if, v-else-if, v-else, v-show) (0) | 2017.03.30 |
4. 계산된 속성과 감시자 (0) | 2017.03.28 |
3. Vue 템플릿 문법 (0) | 2017.03.27 |
2. Vue 인스턴스 (0) | 2017.03.23 |