Vue.js 입문 코스
출처 VueMastery.com
🚫 아래의 내용은 사실과 다를 수 있다
코스의 내용 또한 임의로 생략하거나 순서를 바꾼 부분이 있다
2. 뷰 앱 생성
학습용 뷰 라이브러리 한줄 추가로 필요한 임포트가 끝난다
index.html
<script src="https://unpkg.com/vue@next"></script>
앱은 아래와 같은 방식으로 선언되는데
const app = Vue.createApp({Options object})
Options object는 옵션이 아니다 빈 오브젝트({})라도 넘겨줘야 작동을 한다
앱을 js 파일에 선언한다
main.js
const app = Vue.createApp({
data() {
return {
product: 'Socks',
image: './assets/images/socks_green.jpg',
stock: 55,
cart: 0,
...
}
},
methods: {
addToCart() {
this.cart += 1
},
...
},
computed: { // 기본적으로 method와 같으나 결과가 캐싱됨
title() {
return this.brand + ' ' + this.product
},
...
}
})
선언한 앱의 사용은 마운트를 통해 이루어진다
index.html
<body>
<div id="app">
<h1></h1>
</div>
<!-- Import Js -->
<script src="./main.js"></script>
<!-- Mount App -->
<script>
const mountedApp = app.mount('#app')
</script>
</body>
마운트가 되면 자바스크립트 표현식()으로 내부 변수들에 접근이 가능해진다
자바스크립트 표현식이기 때문에
main.js
{{ product }} // 변수
{{ firstName + ' ' + lastName }} // 산술
{{ clicked ? true : false }} // 삼항
{{ message.method() }} // 함수
등과 같은 처리도 가능하다
뷰는 값이 변하면 동적으로 반응한다(바로 바꾸고 적용함)
3. 속성연결 v-bind
v-bind는 태그 속성에 입력한 문자열을 표현식으로 인식할 수 있게 도와준다
:src=”image” == :src=
v-bind로 src 속성에 경로를 변수로 전달해보자
index.html
<div id="app">
...
<img v-bind:src="image" alt="">
...
</div>
v-bind는 class나 style도 적용 가능하고 생략도 가능하다
<div :class="[isActive ? activeClass(함수) : '']">
<div :style="{ backgroundColor: variant.color }"> camelCased
<div :style="{ 'background-color': variant.color }"> 'kebab-cased'
<div :style="variantStyle"> 변수에 담기
<img :disabled="stock <= 0">
<img v-bind:src="image" alt="">
== <img :src="image" alt="">
4. 조건부 출력 v-if
v-if와 v-else로 간단하게 조건문을 사용할 수 있다
index.html
<p v-if="stock > 10">In Stock</p>
<p v-else-if="stock > 0">Almost sold out!</p>
<p v-else>Out of Stock</p>
v-show는 조건문이 거짓일 때,
style=”display: none;”을 추가한다
<p v-show="stock > 0">In Stock</p>
5. v-for Iterator
아래와 같은 순환 가능한 형태의 변수는 main.js
variants: [
{ id: 2234, color: 'green', ...},
{ id: 2235, color: 'blue', ...},
]
v-for로 순환하며 출력이 가능하다
index.html
<ul>
<li v-for="variant in variants">
</li>
</ul>
또한 v-bind:key=”variant.id”와 같은 방식으로 식별키를 지정할 수도 있다
6. v-on 이벤트 리스너
v-on:이벤트 수신방식="이벤트 발생시 실행할 표현식"
click 이벤트 예시는 다음과 같다 index.html
<button class="button" v-on:click="addToCart">Add to Cart</button>
또한 v-on은 @로도 표현 가능하다
<button v-on:click="addToCart"></button>
== <button @click="addToCart"></button>
click 외에도 가능하다
ex) <div @mouseover="updateImage(variant.image)">
9. Components & Props
컴포넌트를 사용하면 코드의 재사용성을 크게 높일수 있다
컴포넌트의 이름은 임포트 후에 태그로 사용하므로 작명에 신경쓰자
<!-- Import Component -->
<script src="./components/ProductDisplay.js"></script>
...
<product-display :premium="premium"></product-display>
<!-- product-display props = premium -->
해당 컴포넌트보다 더 넓은 스코프에서 쓰이는 변수와 같은 항목들은
props로 지정해서 컴포넌트의 생성자 파라미터처럼 받아올 수 있다
이제 재사용할 부분들을 추출해서 컴포넌트를 만들어보자
ProductDisplay.js
app.component('product-display', { // <- 컴포넌트 이름
props: {
premium: {
type: Boolean,
required: true
}
},
template:
/*html*/ // <- ms code에서 이렇게 명시하면 보기 편하다
`<div class="product-display">
<div class="product-container">
<div class="product-image">
<img v-bind:src="image">
</div>
<div class="product-info">
<h1></h1>
<p v-if="inStock">In Stock</p>
<p v-else>Out of Stock</p>
<p>Shipping: </p>
<ul>
<li v-for="detail in details"></li>
</ul>
<div
v-for="(variant, index) in variants"
:key="variant.id"
@mouseover="updateVariant(index)"
class="color-circle"
:style="{ backgroundColor: variant.color }">
</div>
<button
class="button"
:class="{ disabledButton: !inStock }"
:disabled="!inStock"
v-on:click="addToCart">
Add to Cart
</button>
</div>
</div>
</div>`,
data() {
return {
product: 'Socks',
brand: 'Vue Mastery',
selectedVariant: 0,
details: ['50% cotton', '30% wool', '20% polyester'],
variants: [
{ id: 2234, color: 'green', image: './assets/images/socks_green.jpg', quantity: 50 },
{ id: 2235, color: 'blue', image: './assets/images/socks_blue.jpg', quantity: 0 },
]
}
},
methods: {
addToCart() {
this.$emit('add-to-cart', this.variants[this.selectedVariant].id)
},
updateVariant(index) {
this.selectedVariant = index
}
},
computed: {
title() {
return this.brand + ' ' + this.product
},
image() {
return this.variants[this.selectedVariant].image
},
inStock() {
return this.variants[this.selectedVariant].quantity
},
shipping() {
if (this.premium) {
return 'Free'
}
return 2.99
}
}
})
이제 복붙이 가능하다
<product-display :premium="premium"></product-display>
<product-display :premium="premium"></product-display>
<product-display :premium="premium"></product-display>
<product-display :premium="premium"></product-display>
<product-display :premium="premium"></product-display>
10. Emit
컴포넌트 내부에서 발생한 이벤트를 외부로 방출하는 방식을 설명한다
아래와 같이 컴포넌트에서 방출 받을 내용을
@이름=”실행할 표현식” 형식으로 미리 지정해주고
index.html
<product-display :premium="premium" @add-to-cart="updateCart"></product-display>
<!-- main.js에 updateCart(id) 메소드가 있다 -->
컴포넌트에서는
this.$emit(지정했던 이름, 함수 파라미터) 형식으로 지정하면 된다
ProductDisplay.js
...
methods: {
addToCart() {
this.$emit('add-to-cart', this.variants[this.selectedVariant].id)
},
...
12. Forms & v-model
form에 v-model 속성을 이용, 양방향 연결을 적용해보자
form 내부의 값들에 v-model 속성을 추가하고,
그 값들을 data() 내부의 연결할 값들로 지정해준다
<form ... @submit.prevent="onSubmit">
이것은 submit 버튼이 눌려도 onSubmit 함수가 실행될 때는
화면이 새로고침 되는것을 방지하라는 내용이다
ReviewForm.js
app.component('review-form', {
template:
/*html*/
`
<form class="review-form" @submit.prevent="onSubmit">
<h3>Leave a review</h3>
<label for="name">Name:</label>
<input id="name" v-model="name">
<label for="review">Review:</label>
<textarea id="review" v-model="text"></textarea>
<label for="rating">Rating:</label>
<select id="rating" v-model.number="rating">
<option>5</option>
<option>4</option>
<option>3</option>
<option>2</option>
<option>1</option>
</select>
<input class="button" type="submit" value="Submit">
</form>
`,
data() {
return {
name: '',
text: '',
rating: null
}
},
methods: {
onSubmit() {
if (this.name === '' || this.text === '' || this.rating === null) {
alert('Review is incomplete. Please fill out every field.')
return
}
const review = {
name: this.name,
text: this.text,
rating: this.rating
}
this.$emit('review-submitted', review)
this.name = ''
this.text = ''
this.rating = null
}
}
})
코스가 끝났다
3시간 배워서 깊이 있는 기술을 구현하기에는 부족하겠지만
이것들만 응용해도 충분히 많은것들이 가능할 것 같다
당장의 가성비에는 이 정도가 적당한듯 하다
댓글남기기