Front-End/vue

[vue] 컴포넌트의 필요성과 특성

찐코딩 2022. 12. 12. 22:13

해당 포스팅은 인프런 웹 게임을 만들며 배우는 Vue 강의를 참고하여 작성하였습니다.

https://www.inflearn.com/course/web-game-vue

 

[무료] 웹 게임을 만들며 배우는 Vue - 인프런 | 강의

간단한 8가지 웹 게임을 만들며 Vue.js와 Vue와 함께 사용되는 Vuex, Vue Router를 배워봅니다., - 강의 소개 | 인프런...

www.inflearn.com

🔎 왜 컴포넌트를 사용하나요?

반복되는 코드 사용....
각기 다른 변수 사용...

만약 반복되는 div를 사용하고 싶을때 가장 먼저 떠올리는 방식은 복붙

이런식으로 전부 복붙하고 하나하나 변수를 달리 설정해줘야 할 것이다..

하지만..너무 불편해! 귀찮아! 심지어 지저분해보여...

 

그래서 도입된 것이 컴포넌트!

Vue 컴포넌트는 아래와 같이 작성한다.

Vue.component(‘wordReplay’);
📌 Vue 인스턴스
<script> 
    const app = new Vue({
        el: '#root',
        data: {},
        methods: {},
    });
</script>​

이런 구조를 가진 것이 vue 인스턴스

📌 Vue 컴포넌트
<script>
    Vue.component('wordRelay', {
        template: `
            <div>
                <div>{{ word }}</div>
                    <form v-on:submit="onSubmitForm">
                        <input type="text" v-model="value" ref="answer">
                        <button type="submit">입력!</button>
                    </form>
                <div>{{ result }}</div>
            </div>
        `,
        data() {
            return {
                word: '진진자라',
                result: '',
                value: '',
            }
        },
        methods: {
            onSubmitForm(e) {
                e.preventDefault();
                if (this.word[this.word.length - 1] === this.value[0]) {
                    this.result = '딩동댕';
                    this.word = this.value;
                } else {
                    this.result = '땡';
                }
                this.value = '';
                this.$refs.answer.focus();
            }
        }
    });
</script>
<script>
    const app = new Vue({
        el: '#root',
    });
</script>

이런 구조를 가진 것이 vue 컴포넌트
사용할 때는 아래와 같이 하면 된다.

<!--HTML에서 vue 컴포넌트 사용 시 -->
<div id="root">
   <word-relay></word-relay>
</div>

😇 Vue 컴포넌트의 특징

🔎 컴포넌트에서의 Data 

  • 컴포넌트에서도 data값을 이용하여 데이터를 관리한다 
  • 컴포넌트에서는 data객체 값을 선언할때 객체리터럴을 이용해 값을 선언하는 것이 아니라 
    return값을 통해 객체 리터럴을 반환한다. (객체를 반환하는 함수를 만든다)
  • 컴포넌트는 data가 각각 컴포넌트마다 달라야하기 때문에 return을 이용하여 컴포넌트의 data를 관리한다.
    (데이터의 분리) 
// 일반 Vue객체에서의 Data (객체 리터럴)
const app = new Vue({
  data: {
    word: '안녕하세요',
    result: '',
    value: '',  
  }
});

// 컴포넌트에서의 Data (return 객체 리터럴)
export default() { 
  data() {
    return {
      data: {
        word: '안녕하세요',
        result: '',
        value: '',
      }
    };
  },
}

 

🔎 컴포넌트에서의 Template

  • 컴포넌트의 template속성에서 반환하는 html 엘리먼트는 항상 하나의 최상위 root element를 가져야 한다.
    • root element로 사용되는 <div>태그는 <template>태그로 대체할 수 있다.
    • CDN을 이용하여 script를 vue를 import하여 사용할 경우에는 해당 template 태그가 동작하지 않는다. (지원 x)
    • webpack을 이용하여 컴포넌트를 import하여 사용할 경우에는 가능하다 (webpack을 쓰는 이유중 하나)
  • template와 백틱 (``) 문자열의 사용이 필요하다.

 

🔎 Vue 컴포넌트의 선언 위치

  • Vue.component(뷰 컴포넌트)는 new Vue() (뷰의 선언) 보다는 상단에 와야 동작한다.
    • 위 예제 코드를 전역 컴포넌트라고 부른다.
  • 서버는 모든 컴포넌트를 처음에 내려받고 화면을 랜더링한다.
    (이미 화면은 처음부터 정해져있다, 데이터만 변경되는것이다)

 

🔎 Vue 컴포넌트에서 Props 사용 및 표기법

  • 뷰 템플릿에서 컴포넌트의 속성값으로 명시하여 준 이름을 props 키값을 통해 배열로 매칭시킨다.
  • Vue의 HTML상의 props는 kebab-case로 작성하여야 한다. (camel-case로는 작성이 불가능)
  • HTML Tag의 속성은 대소문자를 구별하지 않는다. 따라서 Vue의 컴포넌트나 props등을 등을 가져오기위해 HTML에서 태그를 사용할때는 반드시 kebab case를 사용해야한다.
  • JS에서 props를 가져올때는 보통 camel-case로 가져온다. (❗️ template에서 camel-case를 사용하면 안된다 ❗️)
  • props는 컴포넌트의 선언시의 {props: [배열]} 형식의 속성값으로 들어간다.
<div id="root">
  <word-relay start-word="진진자라"></word-relay> <!-- 컴포넌트나 props는 kebab-case로 표현함 -->
  <word-relay start-word="진진"></word-relay>
  <word-relay start-word="자라"></word-relay>
</div>
  • 자바스크립트 쪽에서는 camel-case로 받을수 있다. (알아서 뷰가 처리를 해준다)
Vue.component('word-relay', {
    template: `...`,
    props: ['startWord'], // camel-case로 props전달 받음
 }

 

🔎 Vue 에서 웹팩을 사용해야 하는 이유

  • 웹팩을 사용해야 되는 이유(느끼게되는 이유는) JS파일이 커지다보면
    js파일을 <script></script>로 import해서 계속 사용하고 점점 커지게 되는데, 
    코드의 복잡성이 증가하고 꼬이게 되는 문제가 발생한다. 
  • 그래서 나온것이 CommonJS, RequiredJS이다.
  • 웹팩이 나오면서 스크립트가 여러개 있을때 하나로 합쳐주는 역활을 한다.
  • 스크립트의 관리를 효율적으로 할수 있도록 도와준다.