써치킴의 우당탕탕 개발 블로그

[Vue.js][Ch2][Vue 문법] 컴포넌트 - 기초 본문

완벽하게 Vue.js

[Vue.js][Ch2][Vue 문법] 컴포넌트 - 기초

써치킴 2022. 4. 18. 19:04

부모 - 자식 컴포넌트 데이터 통신

App.vue라는 부모 컴포넌트에서 MyBtn이라는 자식 컴포넌트로 데이터를 전달할 때 쓰는 것props라고 한다.

 

App.vue

<template>
  <MyBtn />   <!-- 만들어놓은 컴포넌트는 재활용에 유용하다 -->
  <MyBtn color="royalblue" />   <!-- type이 String이기 때문에 문자 데이터만 가능 -->
  <MyBtn color="#000" />
  <MyBtn :color="color" />    <!-- color 변수는 문자이기 때문에 데이터처럼 읽힐 수 있도록 v-bind(:) 사용 --> 
</template>

<script>
import MyBtn from '~/components/Ex13_MyBtn'

export default {
  components: {
    MyBtn
  },
  data() {
    return {
      color: '#000'
    }
  }
}
</script>

MyBtn.vue

<template>
  <div 
    :style="{ backgroundColor: color }"
    class="btn"> 
    Apple
  </div>
</template>

<script>
export default {
  /*
  * props : 컴포넌트가 실행될 때, 속성처럼 내용을 받아줌
  */
  props: {
    color: {
      type: String,
      default: 'gray'
    }
  }
}
</script>


<style scoped>
 .btn {
   display: inline-block;
   margin: 4px;
   padding: 6px 12px;
   border-radius: 4px;
   background-color: gray;
   color: white;
   cursor: pointer;
 }
</style>

출력

MyBtn 컴포넌트에 large라는 속성을 추가해보자.

App.vue

<template>
  <!-- props : 컴포넌트에 html에 속성이 붙어있을 때, 컴포넌트 내부에서 어떻게 처리할지 정의 -->
  <MyBtn />
  <MyBtn color="royalblue" />   <!-- type이 String이기 때문에 문자 데이터만 가능 -->
  <MyBtn color="#000" />
  <MyBtn :color="color" />    <!-- color 변수는 문자이기 때문에 데이터처럼 읽힐 수 있도록 v-bind(:) 사용 --> 
  <MyBtn large />
  <MyBtn large color="royalblue"/>  <!-- props를 여러개 사용할 수 있다.  -->
</template>

<script>
import MyBtn from '~/components/Ex13_MyBtn'

export default {
  components: {
    MyBtn
  },
  data() {
    return {
      color: '#000'
    }
  }
}
</script>

MyBtn.vue

<template>
    <!-- :class="{large: large}"   속성과 값의 데이터가 같으면 large로 생략 가능 -->
  <div 
    :class="{ large }"
    :style="{ backgroundColor: color }"
    class="btn"> 
    Apple
  </div>
</template>

<script>
export default {
  /*
  * props : 컴포넌트가 실행될 때, 속성처럼 내용을 받아줌
  */
  props: {
    color: {
      type: String,
      default: 'gray'
    },
    large: {
      type: Boolean,
      default: false
    }
  }
}
</script>


<style scoped lang="scss">
 .btn {
   display: inline-block;
   margin: 4px;
   padding: 6px 12px;
   border-radius: 4px;
   background-color: gray;
   color: white;
   cursor: pointer;
   &.large {
   font-size: 20px;
   padding: 10px 20px;
  }
 }
</style>

출력

Props

컴포넌트에 html에 속성이 붙어있을 때, 컴포넌트 내부에서 어떻게 처리할지 정의한다.

props를 여러개 사용할 수 있다.

MyBtn 컴포넌트에 text라는 속성을 추가해보자.

1. props 속성에 text 추가

text: {
  type: String,
  default: ''
}

2. MyBtn 컴포넌트 템플릿에 context 내용을 text로 변경

<template>
  <div 
    :class="{ large }"
    :style="{ backgroundColor: color }"
    class="btn"> 
    {{ text }}
  </div>
</template>

3. App.vue > MyBtn 태그에서 text 속성 사용

<template>
  <!-- props : 컴포넌트에 html에 속성이 붙어있을 때, 컴포넌트 내부에서 어떻게 처리할지 정의 -->
  <MyBtn text="Banana" />
  <MyBtn text="Banana" color="royalblue" />   <!-- type이 String이기 때문에 문자 데이터만 가능 -->
  <MyBtn text="Banana" color="#000" />
  <MyBtn text="Banana" :color="color" />    <!-- color 변수는 문자이기 때문에 데이터처럼 읽힐 수 있도록 v-bind(:) 사용 --> 
  <MyBtn text="Banana" large />
  <MyBtn text="Banana" large color="royalblue"/>  <!-- props를 여러개 사용할 수 있다.  -->
</template>

출력

text="Banana"를 <button>Banana</button> 방식과 동일하게 바꿔보자.

<MyBtn>Banana</MyBtn> 컴포넌트 사이에 Content를 받아줄 수 있는 내용을 MyBtn에 정의해야한다.
 
1.  MyBtn.vue -> 만들어놓은 속성 {{ text }}를 제거하고 <slot></slot> 태그 추가
<template>
  <div 
    :class="{ large }"
    :style="{ backgroundColor: color }"
    class="btn"> 
    <slot></slot>
  </div>
</template>

2. App.vue -> <MyBtn>Content</MyBtn> 방식 사용

<template>
  <!-- props : 컴포넌트에 html에 속성이 붙어있을 때, 컴포넌트 내부에서 어떻게 처리할지 정의 -->
  <MyBtn>Banana</MyBtn> <!-- 컴포넌트 사이에 Content를 받아줄 수 있는 내용을 MyBtn에 정의해야한다. -->
  <MyBtn color="royalblue" >Banana</MyBtn>  
  <MyBtn color="#000" >Apple</MyBtn> 
  <MyBtn :color="color" >Apple</MyBtn>   
  <MyBtn large >Cherry</MyBtn> 
  <MyBtn large color="royalblue">Cherry</MyBtn>
</template>

출력

<MyBtn></MyBtn> 태그 사이의 모든 내용을 <slot></slot>이라는 태그로 대체할 수 있다.

<MyBtn color="royalblue" >     <!-- type이 String이기 때문에 문자 데이터만 가능 -->
	<span style="color: red">Banana</span>  <!-- 태그 사이의 모든 내용을 slot이라는 태그로 대체할 수 있다. -->
</MyBtn>

 

Comments