ㅈㅔ일 부모 컴포넌트라고 가정하고 보자!
// ***************** App.vue
<template>
// * 하단에 설명 기재
<Banner v-bind:appValue="count"></Banner>
<ul>
<li v-for="(item, index) in products">
<h4 :style="red">{{ index }} 번</h4>
<div>{{ item.title }}</div>
<img @click="onPopup(item)" :src="item.image" alt=""/>
<button @click="item.count++"> ❤️ {{ item.count }}</button>
</li>
</ul>
<!-- 팝업 -->
<!-- v-bind:자식컴포넌트에 사용할 변수명="현재 컴포넌트 내의 modalItem" / @자식컴포넌트에서 작명한 변수명="현재 컴포넌트에서 자식컴포넌트의 데이터를 받을 메소드명" -->
<!-- v-bind를 제외 :modalItem도 가능 -->
<!-- 여러개 보낼 때 :item1="" :item2="" -->
<Modal v-bind:modalItem="modalItem" v-if="modal" @closeFromModal="onModalState"/>
</template>
<script>
import testData from './assets/data/data';
// 컴포넌트 import
import Banner from './components/Banner.vue';
import Modal from './components/Modal.vue';
export default {
name: 'App',
// state(변수 입력하는 곳)
data(){
return{
// 다른 js파일의 데이터를 가져온것임(객체형태)
products: testData,
modalItem: undefined,
count: 100,
}
}
// 함수 만드는 곳
methods: {
onPopup(item){
// modal창을 보여줌
this.modal = true;
// 자식 컴포넌트(modal)에 보낼 값을 넣어줌
this.modalItem = item;
},
onModalState(state){
console.log('modal에서 가져온 값', state)
this.modal = state; // false
}
},
// 컴포넌트 가져오는 곳
components: {
// 원하는태그이름 :Banner --> 원하는대로 작명할 수 있음
Banner, // 축약된 형태
Modal
}
}
</script>
<style>
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
ul,
.menu{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
.menu{
padding: 0 20px;
background: cornflowerblue;
height: 50px;
border-radius: 8px;
}
img{
width: 100%;
height: 30vw;
object-fit: cover;
}
ul{
padding: 20px;
}
ul li {
/* width: 100%; */
width: 30%;
list-style: none;
margin-right: 10px;
margin-bottom: 30px;
}
button{
margin-top: 10px;
}
</style>
컴포넌트 가져오는 법
- template에 컴포넌트 태그 입력해줌
- script 내 component import
- script 내 components에 컴포넌트 명 입력
Banner컴포넌트의 style은 Banner.vue 파일에서 적용되어 오기 때문에 생략한다!
컴포넌트간 데이터 전송하는법
app.vue 파일에 보면 Banner태그 옆에 v-bind:appValue="count" 라고 적혀있는 것이 자식 컴포넌트에 props 값을 전달하는 방법이다
v-bind는 속성에 데이터를 연결할 때 사용(축약된 형태로는 :만 속성 앞에 붙여서 사용한다)
:id="", :class="", :href="" 등
appValue는 자식 컴포넌트에 기재 된 변수명, ( ** banner.vue 파일을 확인)
count는 부모 컴포넌트에서 어떤 값을 보낼지에 따라 해당 변수명을 적어준다(여기서 count는 100임)
// ***************** Banner.vue
<template>
<div class="banner" @click="onClick()">
<p>클릭시 부모 컴포넌트의 count 값을 콘솔창에 찍는다</p>
<button @click="onParentValue()">클릭시 부모 component의 data값 변경</button>
</div>
</template>
<script>
export default {
name: 'Banner',
// 부모 component에서 입력한 props명을 적어줌
props: ["appValue"],
methods: {
onClick(){
// 클릭시 부모 컴포넌트의 count 값을 콘솔창에 찍는다
console.log(' -> ', this.appValue) // -> 100
},
onParentValue(){
this.$emit("childEvent")
}
}
}
</script>
<style>
.banner{
width: 90%;
background: lightgray;
padding: 10px;
box-sizing: border-box;
margin: 10px auto;
}
</style>
props: 에 appVaule로 부모 컴포넌트에서 가져온 값을 받을 변수명을 입력해준다
값이 여러개라면 ["appValue", "appList"] 이런식으로 여러개 입력하면 됨
예를 들어 modal 컴포넌트가 있다고 했을 때
// ***************** Modal.vue
<template>
<div class="modal-bg" @click="onClose()">
<div class="modal">
<p class="title">팝업창</p>
<Banner/>
<div class="content">
<p>{{ modalItem.title }}</p>
<img :src="modalItem.image" :alt="modalItem.image" />
<p>{{ modalItem.content }}</p>
<p>금액: {{ modalItem.price }}, 좋아요 수: {{ modalItem.count }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'Modal',
props: ["modalItem"],
data(){
// state 값
return {
}
},
// 함수 만드는 곳
methods: {
onClose(){
this.$emit("closeFromModal", false )
}
},
components: {
}
}
</script>
<style>
.modal-bg{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .3);
}
.modal-bg .modal{
width: 80%;
height: 500px;
background: white;
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 20px;
padding: 20px;
overflow: scroll;
}
.modal .title{
font-size: 20px;
font-weight: bold;
margin-bottom: 30px;
}
.modal img{
width: 100%;
height: 100%;
object-fit: cover;
margin: 20px 0;
}
</style>
modalItem 값을 props로 받아서 전달된 데이터로 화면에 보여주고
화면을 닫을 땐 emit으로 false값을 전달하여 자식 컴포넌트를 닫아준다
끝!
정리하자면
부모 컴포넌트 -> 자식 컴포넌트
- (부모 컴포넌트) html 컴포넌트 태그에 :변수명(작명)="보낼값이 들어있는변수" 입력
ex) 예를 들어 :이거옮길것임="itemList"
- (자식 컴포넌트) props:에 변수명(작명)했던 거 등록해
ex) props: ["이거옮길것임", "이거옮길것임2(여러개일때)"]
ex) props: {
"이거옮길것임": Array
},