오늘의 공부(22.08.15)

조지성·2022년 8월 15일
0

TIL

목록 보기
69/78
post-thumbnail

컴포넌트 심화 학습

컴포넌트 안에 다른 컴포넌트 사용하기

부모 컴포넌트와 자식 컴포넌트

  • 컴포넌트에서 다른 컴포넌트를 사용하는 방법은 사용할 컴포넌트를 import한 후 현재 컴포넌트의 템플릿에서 사용할 컴포넌트를 components에 등록

부모 컴포넌트에서 자식 컴포넌트로 데이터 전달하기 props

  • props에는 부모 컴포넌트로 전달받은 데이터가 저장

    • props에 정의된 키는 저장될 데이터 타입 , 부모 컴포넌트로부터 데이터가 전달되지 않았을 때의 default값을 정의
    <template>
      <h2>{{title}}</h2>
    </template>
    <script>
    export default {
      props:{
        title :{
          type:String,
          default : "페이지 제목입니다."
        }
      }
    }
    </script>

정적/동적 Prop 전달

  • v-bind:를 사용해서 prop에 동적인 값을 전달

  • 숫자형 , 논리형 , 배열 , 객체 , 객체의 속성

    • v-bind를 사용해서 전달

Prop 유효성 전달

자식 컴포넌트에서 props 옵션을 정의할 때, 전달받는 데이터 타입, 기본값, 필수여부, 유효성 검사 함수인 함수를 통해서 유효성을 검사

부모 컴포넌트에서 자식 컴포넌트의 이벤트 직접 발생

<template>
  <child-component @send-message="sendMessage" ref="child_component" />
</template>

<script>
  import ChildComponent from './ChildComponent.vue'
  export default {
    components : {
      ChildComponent
    },
    mounted() {
      this.$refs.child_component.$refs.btn.click();
    },
  }
</script>

<style lang="scss" scoped>

</style>
<template>
  <button type="button" @click="childFunc" ref="btn">Click</button>
</template>

<script>
  export default {
    methods : {
      childFunc(){
        console.log('부모 컴포넌트에서 직접 발생시킨 이벤트');
      }
    }
  }
</script>

<style lang="scss" scoped>

</style>

부모 컴포넌트에서 자식 컴포넌트의 함수 직접 호출

<template>
  <div></div>
</template>

<script>
  export default {
    methods : {
      callFromParent(){
        console.log('부모 컴포넌트에서 직접 호출한 함수');
      }
    }
  }
</script>

<style lang="scss" scoped>

</style>
<template>
  <child-component @send-message="sendMessage" ref="child_component" />
</template>

<script>
  import ChildComponent from './ChildComponent2'
  export default {
    components : {
      ChildComponent
    },
    mounted() { 
      this.$refs.child_component.callFromParent();
    }
  }
</script>

<style lang="scss" scoped>

</style>

부모 컴포넌트에서 자식 컴포넌트의 데이터 옵션 값 직접 변경

<template>
  <h1>{{msg}}</h1>
</template>

<script>
  export default {
    data() {
      return {
        msg: '',
      }
    },
  }
</script>

<style lang="scss" scoped>

</style>
<template>
  <child-component @send-message="sendMessage" ref="child_component" />
  <button type="button" @click="changeChildData">Change Child Data</button>
</template>

<script>
  import ChildComponent from './ChildComponent3'
  export default {
    components : {
      ChildComponent
    },
    methods: {
      changeChildData(){
        this.$refs.child_component.msg = "부모컴포넌트가 변경한 데이터"
      }
    },
  }
</script>

<style lang="scss" scoped>

</style>

자식 컴포넌트에서 부모 컴포넌트로 이벤트 / 데이터 전달

<template>
  <div></div>
</template>

<script>
  export default {
    data() {
      return {
        msg: '자식 컴포넌트로부터 보내는 메시지',
      }
    },
    mounted() {
      this.$emit('send-message',this.msg)
    },
  }
</script>

<style lang="scss" scoped>

</style>
<template>
  <child-component @send-message="sendMessage"/>
</template>

<script>
  import ChildComponent from './ChildComponent4'
  export default {
    components : {
      ChildComponent
    },
    methods: {
      sendMessage(data){
        console.log(data);
      }
    },
  }
</script>

<style lang="scss" scoped>

</style>

부모 컴포넌트에서 자식 컴포넌트의 데이터 옵션 값 동기화

<template>
  <button type="button" @click="childFunc" ref="btn">자식 컴포넌트 데이터 변경</button>
</template>

<script>
  export default {
    data() {
      return {
        msg: '메시지',
      }
    },
    methods: {
      childFunc(){
        this.msg = '변경된 메시지';
      }
    },
  }
</script>

<style lang="scss" scoped>

</style>
<template>
  <button type="button" @click="checkChild">자식 컴포넌트 데이터 조회</button>
  <child-component ref="child_component" />
</template>

<script>
  import ChildComponent from './ChildComponent5'
  export default {
    components : {
      ChildComponent
    },
    computed: {
      msg(){
        return this.$refs.child_component.msg;
      }
    },
    methods: {
      checkChild(){
        alert(this.msg);
      }
    }
  }
</script>

<style lang="scss" scoped>

</style>

Slot

slot은 컴포넌트 내에서 다른 컴포넌트를 사용할 때 쓰는 컴포넌트의 마크업을 재정의ㅏ거나 확장하는 기능

<template>
  <div class="modal-container">
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

<script>
  export default {
    
  }
</script>

<style lang="scss" scoped>

</style>
<template>
  <modal-layout>
    <template v-slot:header>
      <h1>팝업 타이틀</h1>
    </template>
    <template v-slot:default>
      <p>팝업 컨텐츠 1</p>
      <p>팝업 컨텐츠 2</p>
    </template>
    
    <template v-slot:footer>
      <button type=“button”>닫기</button>
    </template>
    </modal-layout>
</template>
<script>
import ModalLayout from './SlotModalLayout';
export default {
 components: {'modal-layout':ModalLayout}
}
</script>

Provide / Inject

컴포넌트 계층 구조가 복잡하게 얽혀 있어서 부모 컴포넌트로부터 자식 컴포넌트, 그리고 그 자식 컴포넌트의 자식 컴포넌트로 데이터를 전달하는 경우가 생긴다면 props 를 통해 데이터를 전달하는 것은 굉장히 복잡한 코드를 양산 => provide / inject 사용

<template>
  <div>
    <ProvideInjectChild />
  </div>
</template>
<script>
import ProvideInjectChild from './ProvideInjectChild';
export default {
  components: {ProvideInjectChild},
  data() {
    return {
      items: ['A','B']
    };
  },
  provide() {
    return {
      itemLength: this.items.length
    };
  }
}
</script>
<template>
<div></div>
</template>
<script>
export default {
  inject: ['itemLength'],
  mounted() {
    console.log(this.itemLength);
  }
}
</script>

Template refs

어쩔수 없이 자바스크립트안에서 HTML 객체에 바로 접근해야 한다면 ref를 사용

profile
초보 개발자의 성장기💻

0개의 댓글