Vue 앱 프로젝트는 index.html 페이지 하나를 생성하는 프로젝트
javascript로 구현한 기능은 다른 페이지로 넘어갈 때, 전 페이지에서 실행 중이던 javascript 코드를 모두 종료하고 새로운 페이지의 javascript 코드가 새로 시작
➡️ 새로고침하면, 실행 중이던 javascript 코드는 모두 초기화(종료 후 재시작)
<template> 부분은 표준 html 태그가 아니라 Virtual DOM 객체
<template> 부분에서는, 태그와 태그 사이의 공백문자들이 전부 제거
작은 여백이 전혀 없으므로 margin
값이 필요
src/MyCounter1.vue
<template>
<div>
<h2>{{ title }} - <small>{{ description }}</small></h2>
<input type="number" v-model="counter" />
<button type="button" @click="counter++"> ++ </button>
<button type="button" @click="counter--"> -- </button>
</div>
</template>
<script>
export default {
name: "MyCounter1",
props: [ "title", "description" ],
data() {
return { counter: 0 };
}
}
</script>
<style scoped>
div { border: 1px solid gray; padding: 0 20px 20px 20px; margin-top: 10px; }
input { padding: 5px; margin-right: 5px; }
button { padding: 0.4em 1em; margin-right: 5px; }
</style>
v-on: == @
props: [ "title", "description" ]
부모 컴포넌트로부터 자식 컴포넌트로 전달되는 값
<h2>{{ title }} - <small>{{ description }}</small></h2>
이 부분에 부모 컴포넌트로부터 전달 받은 값이 출력된다.(title props, description props)
src/App.vue
<template>
<div id="app">
<h1>MyCounter1</h1>
<MyCounter1 title="카운터" description="첫째 컴포넌트" />
<MyCounter1 title="카운터" description="둘째 컴포넌트" />
</div>
</template>
<script>
import MyCounter1 from './MyCounter1.vue'
export default {
name: "App",
components: { MyCounter1 }
}
</script>
<style scoped>
div#app { padding: 0 30px 30px 30px; margin: 30px auto; max-width: 400px;
border: 1px solid #ccc; box-shadow: 3px 3px 3px #aaa; }
</style>
<MyCounter1 title="카운터" description="첫째 컴포넌트" />
<MyCounter1 title="카운터" description="둘째 컴포넌트" />
MyCounter1 컴포넌트의 title props, description props으로 전달
export default {
name: "Counter1",
props: [ "title", "description" ],
}
<MyCounter1 title="카운터1" description="첫째 컴포넌트" />
➡️ props 값은 전달하지 않아도 에러X, props값은 undefined가 됨
props: {
title: String,
description: String
}
➡️ props 타입은 String, Number, Boolean, Array, Object, Function 등이 가능
```vue
```
따라서 v-bind: 접두어를 붙여야함
```vue
```➡️ props 값이 문자열이 아니라면 v-bind: 접두어 필수
required : true
가 선언된 props는 값 전달이 필수, 전달하지 않을 경우 에러 발생
props: {
title: { type: String, required: true },
description: { type: String, default: "안녕하세요" }
}
src/MyCounter2.vue
<template>
<div :style="{ backgroundColor: color }">
<h2>{{ title }} - <small>{{ description }}</small></h2>
<input type="number" v-model="counter" />
<button type="button" @click="counter++"> ++ </button>
<button type="button" @click="counter--"> -- </button>
<button type="button" @click="$emit('send', counter)"> 전달 </button>
</div>
</template>
<script>
export default {
name: "MyCounter1",
props: {
title: { type: String, required: true },
description: { type: String, default: "안녕하세요" },
color: { type: String, default: "#fff" }
},
data: function() {
return { counter: 0 };
}
}
</script>
<style scoped>
div { border: 1px solid gray; padding: 0 20px 20px 20px; margin-top: 10px; }
input { padding: 5px; margin-right: 5px; }
button { padding: 0.4em 1em; margin-right: 5px; }
</style>
<button type="button" @click="$emit('send', counter)"> 전달 </button>
이 버튼이 클릭되면 부모에개 'send' 이벤트를 전달, 이벤트의 파라미터로 counter 값 전달
<template> 영역의 태그에 css 서식을 적용하려면 v-bind:style
애트리뷰트를 사용해야함
⭐️ v-bind: == : , v-on: == @
: 자식 컴포넌트로부터 부모 컴포넌트에게 이벤트 전달
이밴트 이름은 'send'이고, 이벤트 파라미터 값으로 counter 값 전달
이벤트 파라미터의 수는 0개 이상
➡️ 이벤트를 전달하는 이유는, 자식 컴포넌트로부터 부모 컴포넌트에게 어떤 시점(event)을 알리거나, 어떤 값을 전달하기 위해
만일 $emit() 메소드를 method 본문에서 호출한다면, this.$emit()
형식이어야 함(태그 부분은 this 생략)
<MyCounter2 title="카운터2" v-on:send="showValue" />
v-on:이벤트명="메소드"
MyCounter2 컴포넌트에서 send 이벤트를 전달하면, 부모 컴포넌트의 showValue 메소드가 호출
MyCoutner2 컴포넌트가 전달한 이벤트 파라미터 값은, showValue 메소드의 파라미터로 전달
src/App.vue
<template>
<div id="app">
<h1>MyCounter2</h1>
<MyCounter2 title="카운터2" description="첫째 컴포넌트" color="#ffb" v-on:send="showValue" />
<MyCounter2 title="카운터2" color="#afa" v-on:send="showValue" />
</div>
</template>
<script>
import MyCounter2 from './MyCounter2.vue'
export default {
name: "App",
methods: {
showValue(value) {
alert(value);
}
},
components: { MyCounter2 }
}
</script>
<style scoped>
div#app { padding: 0 30px 30px 30px; margin: 30px auto; max-width: 400px;
border: 1px solid #ccc; box-shadow: 3px 3px 3px #aaa; }
</style>