728x90
[목표]
1. 부모 - 객체 간의 데이터 전달에 필요한 기능들을 익숙해져 보자
1-1) @submit.prevent란 무엇인가
1-2) App.vue(부모)에서 컴포넌트 형식으로 사용하려면 어떻게?
1-3) emit를 하기위한 순서는?
1-1) @submit.prevent란 무엇인가
form 태그 사용시 페이지가 넘어가는 동작을 한다.
이것을 막아주는 기능이다.
1-2) App.vue(부모)에서 컴포넌트 형식으로 사용하려면 어떻게?
1st: main.js에서 등록한다
import { createApp } from 'vue';
import App from './App.vue';
import FriendContact from './components/FriendContact.vue';
import NewFriend from './components/NewFriend.vue';
const app = createApp(App);
app.component('friend-contact', FriendContact);
// app.component('사용할 태그명', 태그명 적용파일);
app.component('new-friend', NewFriend);
app.mount('#app');
2nd: App.vue 안에 전언한 태그명으로 사용한다.
[App.vue]
<template>
<section>
<ul>
<new-friend
@new-freind="emitNewFriend"
>
</new-friend>
<FriendContact
v-for="friend in friends"
:key="friend.id"
:id="friend.id"
:name="friend.name"
:phone-number="friend.phoneNumber"
:email-address="friend.emailAddress"
:isFavorite="friend.isFavorite"
@toggle-favorite="emitToggle"
>
</FriendContact>S
</ul>
</section>
</template>
<script>
import FriendContact from './components/FriendContact.vue'
import NewFriend from './components/NewFriend.vue'
export default{
components: {
FriendContact,
NewFriend,
},
data(){
return{
friends:[
{
id: 'manuel',
name: 'Manuel Lorenz',
phone: '1234 5678 90',
email: 'manuel@localhost.com',
isFavorite: true,
},
{
id: 'tom',
name: 'Tom Hoon',
phone: '9281 238 2910',
email: 'tomhoon@localhost.com',
isFavorite: false,
},
{
id: 'Ann',
name: 'Ann Kim',
phone: '9523 591 2330',
email: 'ann@localhost.com',
isFavorite: false,
},
],
}
},
methods: {
emitToggle(value){
const result = this.friends.find(function(x){
return x.id == value;
});
result.isFavorite = !result.isFavorite;
},
emitNewFriend(){
alert('emitNewFriend');
},
},
computed: {
}
}
</script>
<style>
/* @import url('https://fonts.googleapis.com/css2?family=Jost&display=swap'); */
* {
box-sizing: border-box;
}
html {
font-family: 'Jost', sans-serif;
}
body {
margin: 0;
}
header {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
margin: 3rem auto;
border-radius: 10px;
padding: 1rem;
background-color: #58004d;
color: white;
text-align: center;
width: 90%;
max-width: 40rem;
}
#app ul {
margin: 0;
padding: 0;
list-style: none;
}
#app li {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
margin: 1rem auto;
border-radius: 10px;
padding: 1rem;
text-align: center;
width: 90%;
max-width: 40rem;
}
#app form {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
margin: 1rem auto;
border-radius: 10px;
padding: 1rem;
text-align: center;
width: 90%;
max-width: 40rem;
}
#app h2 {
font-size: 2rem;
border-bottom: 4px solid #ccc;
color: #58004d;
margin: 0 0 1rem 0;
}
#app button {
font: inherit;
cursor: pointer;
border: 1px solid #ff0077;
background-color: #ff0077;
color: white;
padding: 0.05rem 1rem;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.26);
}
#app button:hover,
#app button:active {
background-color: #ec3169;
border-color: #ec3169;
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.26);
}
</style>
1-3) emit를 하기위한 순서는?
1st: 부모객체로 보낼 자식객체에서 emit 변수명 선언
2nd: form에서 다양한 설정을 한다. 설정은 다음과 같다.
2-1) v-model
2-2) @submit.prevent="submit 시에 작동할 메소드명"
3rd: App.vue(부모)에서 자식이 보낸 emit를 등록한다.
4th: 자식이 emit를 보내면 부모가 반응하여 작동할 method 생성
여기까지 설명이였고 밑에 연습문제와 해답을 올리겠음
[연습문제]
[App.vue]
<template>
<section>
<ul>
<FriendContact
v-for="friend in friends"
:key="friend.id"
:id="friend.id"
:name="friend.name"
:phone-number="friend.phoneNumber"
:email-address="friend.emailAddress"
:isFavorite="friend.isFavorite"
@toggle-favorite="emitToggle"
>
</FriendContact>S
</ul>
</section>
</template>
<script>
import FriendContact from './components/FriendContact.vue'
export default{
components: {
FriendContact,
},
data(){
return{
friends:[
{
id: 'manuel',
name: 'Manuel Lorenz',
phone: '1234 5678 90',
email: 'manuel@localhost.com',
isFavorite: true,
},
{
id: 'tom',
name: 'Tom Hoon',
phone: '9281 238 2910',
email: 'tomhoon@localhost.com',
isFavorite: false,
},
{
id: 'Ann',
name: 'Ann Kim',
phone: '9523 591 2330',
email: 'ann@localhost.com',
isFavorite: false,
},
],
}
},
methods: {
emitToggle(value){
const result = this.friends.find(function(x){
return x.id == value;
});
result.isFavorite = !result.isFavorite;
},
},
computed: {
}
}
</script>
<style>
/* @import url('https://fonts.googleapis.com/css2?family=Jost&display=swap'); */
* {
box-sizing: border-box;
}
html {
font-family: 'Jost', sans-serif;
}
body {
margin: 0;
}
header {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
margin: 3rem auto;
border-radius: 10px;
padding: 1rem;
background-color: #58004d;
color: white;
text-align: center;
width: 90%;
max-width: 40rem;
}
#app ul {
margin: 0;
padding: 0;
list-style: none;
}
#app li {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
margin: 1rem auto;
border-radius: 10px;
padding: 1rem;
text-align: center;
width: 90%;
max-width: 40rem;
}
#app form {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
margin: 1rem auto;
border-radius: 10px;
padding: 1rem;
text-align: center;
width: 90%;
max-width: 40rem;
}
#app h2 {
font-size: 2rem;
border-bottom: 4px solid #ccc;
color: #58004d;
margin: 0 0 1rem 0;
}
#app button {
font: inherit;
cursor: pointer;
border: 1px solid #ff0077;
background-color: #ff0077;
color: white;
padding: 0.05rem 1rem;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.26);
}
#app button:hover,
#app button:active {
background-color: #ec3169;
border-color: #ec3169;
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.26);
}
</style>
[NewFriend.vue]
<template>
<form>
<div>
<label for="name">name: </label>
<input type="text" v-model="newFriend.name">
</div>
<div>
<label for="phone">phone: </label>
<input type="text" v-model="newFriend.phone">
</div>
<div>
<label for="email">email: </label>
<input type="text" v-model="newFriend.email">
</div>
<button>Submit</button>
</form>
</template>
<script>
export default{
data: function(){
return{
}
},
methods: {
},
}
</script>
[main.js]
import { createApp } from 'vue';
import App from './App.vue';
import FriendContact from './components/FriendContact.vue';
const app = createApp(App);
app.component('friend-contact', FriendContact);
// app.component('사용할 태그명', 태그명 적용파일);
app.mount('#app');
[해답]
[App.vue]
더보기
<template>
<section>
<ul>
<new-friend
@add-friend="addFriend"
>
</new-friend>
<FriendContact
v-for="friend in friends"
:key="friend.id"
:id="friend.id"
:name="friend.name"
:phone-number="friend.phoneNumber"
:email-address="friend.emailAddress"
:isFavorite="friend.isFavorite"
@toggle-favorite="emitToggle"
>
</FriendContact>S
</ul>
</section>
</template>
<script>
import FriendContact from './components/FriendContact.vue'
export default{
components: {
FriendContact,
},
data(){
return{
friends:[
{
id: 'manuel',
name: 'Manuel Lorenz',
phone: '1234 5678 90',
email: 'manuel@localhost.com',
isFavorite: true,
},
{
id: 'tom',
name: 'Tom Hoon',
phone: '9281 238 2910',
email: 'tomhoon@localhost.com',
isFavorite: false,
},
{
id: 'Ann',
name: 'Ann Kim',
phone: '9523 591 2330',
email: 'ann@localhost.com',
isFavorite: false,
},
],
}
},
methods: {
emitToggle(value){
const result = this.friends.find(function(x){
return x.id == value;
});
result.isFavorite = !result.isFavorite;
},
addFriend(value){
const newFriend = {
id:new Date().toISOString(),
name:value.name,
phone:value.phone,
email:value.email,
};
this.friends.push(newFriend);
}
},
computed: {
}
}
</script>
<style>
/* @import url('https://fonts.googleapis.com/css2?family=Jost&display=swap'); */
* {
box-sizing: border-box;
}
html {
font-family: 'Jost', sans-serif;
}
body {
margin: 0;
}
header {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
margin: 3rem auto;
border-radius: 10px;
padding: 1rem;
background-color: #58004d;
color: white;
text-align: center;
width: 90%;
max-width: 40rem;
}
#app ul {
margin: 0;
padding: 0;
list-style: none;
}
#app li {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
margin: 1rem auto;
border-radius: 10px;
padding: 1rem;
text-align: center;
width: 90%;
max-width: 40rem;
}
#app form {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
margin: 1rem auto;
border-radius: 10px;
padding: 1rem;
text-align: center;
width: 90%;
max-width: 40rem;
}
#app h2 {
font-size: 2rem;
border-bottom: 4px solid #ccc;
color: #58004d;
margin: 0 0 1rem 0;
}
#app button {
font: inherit;
cursor: pointer;
border: 1px solid #ff0077;
background-color: #ff0077;
color: white;
padding: 0.05rem 1rem;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.26);
}
#app button:hover,
#app button:active {
background-color: #ec3169;
border-color: #ec3169;
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.26);
}
</style>
[NewFriend.vue]
더보기
<template>
<form @submit.prevent="addFriend">
<div>
<label for="name">name: </label>
<input type="text" v-model="newFriend.name">
</div>
<div>
<label for="phone">phone: </label>
<input type="text" v-model="newFriend.phone">
</div>
<div>
<label for="email">email: </label>
<input type="text" v-model="newFriend.email">
</div>
<button>Submit</button>
</form>
</template>
<script>
export default{
emit:['add-friend'],
data: function(){
return{
newFriend:{
name: '',
phone: '',
email: '',
}
}
},
methods: {
addFriend(){
this.$emit('add-friend', this.newFriend);
}
},
}
</script>
[main.js]
더보기
import { createApp } from 'vue';
import App from './App.vue';
import FriendContact from './components/FriendContact.vue';
import NewFriend from './components/NewFriend.vue';
const app = createApp(App);
// app.component('사용할 태그명', 태그명 적용파일);
app.component('friend-contact', FriendContact);
app.component('new-friend', NewFriend);
app.mount('#app');
'데일리 공부 기록' 카테고리의 다른 글
hands on vue - component의 global, local 이해(연습예제 고민하고 풀기!) (0) | 2023.03.09 |
---|---|
hands on vue - 부모의 손자에게 바로 다이렉트로 값 보내기(provide&inject) (0) | 2023.03.09 |
hands on vue - emit와 익숙해지는 연습문제(해답) (0) | 2023.03.06 |
hands on vue - emit와 익숙해지는 연습문제 (0) | 2023.03.06 |
hands on vue - v-bind를 사용하여 자식에게 넘기기 (1) | 2023.03.06 |