차근차근/JAVA Script

[Vue.js] Vue.js란 (5) - Vue 컴포넌트

예쁜꽃이피었으면 2021. 12. 6. 11:27

컴포넌트 생성

한개 이상의 페이지를 레이아웃 또는 기능별로 쪼개어 분리하고,

상위 Vue파일에서 통합관리하는 것을 컴포넌트화라고 한다.

 

순서 
1) 폴더 안에 각 하위 컴포넌트 vue파일 생성
2) 상위 컴포넌트(app.vue) script내에 하위 컴포넌트로 import로 콜
3) export default, components 메소드 안, import한 하위 컴포넌트 export처리
4) 상위 컴포넌트 template태그 내 , 각 하위 컴포넌트 태그 삽입

 

https://goddino.tistory.com/88

 

[js] vue.js 컴포넌트 생성(컴포넌트로 쪼개기)

vue.js 하위 컴포넌트 만들기 한개 이상의 페이지를 레이아웃 또는 기능별로 쪼개어 분리하고, 상위 vue 파일에서 통합 관리 하는 것을 컴포넌트화 라고 합니다. 순서 1. 폴더 안에 각 하위 컴포넌

goddino.tistory.com

 


 

컴포넌트(component)란

: 화면의 영역을 분리하여 개발하는 것, Vue에서 최상위 컴포넌트는 root이다.

컴포넌트 구성의 장점은 요소들을 재사용함으로써 개발 생상성을 향상되고, 컴포넌트들은 서로 관계가 형성된다.

 

컴포넌트화 해야 하는 부분을 명확하게 나눠야 한다. A라는 부분이 N개의 페이지에서 사용하는 공통적인 항목이라면 컴포넌트로 분리해야하는 것이 바람직하다

 

컴포넌트는 원하는 만큼 재사용이 가능하다

컴포넌트는 사용할 때마다 컴포넌트의 인스턴스가 생성되기 때문에 컴포넌트마다 다른 값을 가진다.

* 컴포넌트의 data옵션은 반드시 함수형이어야 한다.
: newVue에서 옵션으로 넘겨주는 data는 객체형, 함수형 모두 가능하다. 그러나 컴포넌트에서 data는 반드시 함수형이어야 한다.
더보기

기본 예제

// Define a new component called button-counter
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button @click="count++">You clicked me {{ count }} times.</button>'
});

위의 예제는 <button-counter> 라는 이름으로 재사용이 가능한 컴포넌트입니다.

<div id="app">
  <button-counter><button-counter/>
</div>
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button @click="count++">You clicked me {{ count }} times.</button>'
});

new Vue({
  el: '#app'
});

위의 예제와 같이 컴포넌트를 사용할 수 있습니다. 컴포넌트를 생성할 때 사용되는 옵션은 new Vue에 사용되는 옵션(data, computed, watch, methods ...)과 동일 합니다. 단 하나의 예외는 컴포넌트에는 el 옵션을 사용할 수 없다는 것입니다.



출처: https://beomy.tistory.com/55 [beomy]

 

 

1) 전역(Global) 컴포넌트

- 모든 범위의 여러 인스턴스에서 공통으로 사용할 수 있음

- 컴포넌트 이름은 template속성에서 사용할 HTML사용자 정의 태그(HTML 표준태그들 이 외에도 개발자가 직접 정의하여 사용할 수 있는 태그)이름을 의미합니다.

- 컴포넌트 내용에는 컴포넌트 태그가 실제화면의 HTML요소로 변환될 때 표시될 속성들을 작성하며, temple,data,methods 등 인스턴스 옵션 속성을 정의할 수 있습니다.

- 주로 플러그인, 라이브러리 등 앱 전역에서 사용할 공통 컴포넌트를 작성한다. 

더보기
<html>
    <head>
        <title>Vue Component Registration</title>
    </head>
    <body>
        <div id="app>
            <button>컴포넌트 등록</button>
            <my-component></my-component>
        </div>

        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
        <script>
            Vue.component('my-component', {
                template: '<div>전역 컴포넌트가 등록되었습니다.</div>'
            });

            new Vue({
                el: '#app'
            });
        </script>
    </body>
</html>

 

2) 지역(Local) 컴포넌트

- 특정 인스턴스에서만 유효

- 지역 컴포넌트 등록은 전역 컴포넌트 등록과는 다르게 인스턴스에 components속성을 추가하고 등록할 컴포넌트 이름과 내용을 정의하면 된다.

- Vue인스턴스 내에 직접 삽입하는 방식이고 components로 정의한다.

Tree구조로 구성할 수 있으면 부모<->자식 간 컴포넌트 사이 통신이 가능하다.

더보기

 

<html>
    <head>
        <title>Vue Component Registration</title>
    </head>
    <body>
        <div id="app>
            <button>컴포넌트 등록</button>
            <my-local-component></my-local-component>
        </div>

        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
        <script>
        <!-- 지역 컴포넌트 등록 형식 -->
           var cmp = {
                    // 컴포넌트 내용
                    template: '<div>지역 컴포넌트가 등록되었습니다.</div>'
                };

                new Vue({
                    el: '#app',
                    components: {
                        'my-local-component': cmp // '컴포넌트 이름': 컴포넌트 내용
                    }
                });
        </script>
    </body>
</html>

 

 

* 컴포넌트 통신 방식

- Vue컴포넌트는 각 고유한 데이터 유효범위를 갖는다.

- 부모 컴포넌트의 데이터가 바뀌면 하위 컴포넌트의 데이터가 바뀌지만, 반대로 하위 컴포넌트의 데이터가 바뀌면 부모 컴포넌트가 바꾸지 않는다. (=> 단방향 흐름)

 

 

 

3) props 사용하기 

- 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하기 위해 사용한다.

props는 data와 유사하게 사용 가능한 속성이다.

- vue에서는 v-bind디렉티브로 속성에 접근할 수 있는데, 하위 컴포넌트에서 상위 컴포넌트의 데이터 속성에 접근이 가능하다. v-bind로 해당 컴포넌트에서 정의된 props속성에 접근할 수 있고  props의 역할은 부모의 data영역에 접근할 수 있게 해주는 속성이라고 볼 수 있다.

 

더보기

 

<html>
    <head>
        <title>Vue Component Registration</title>
    </head>
    <body>
        <div id="app">
          <blog-post
            v-for="post in posts"
            v-bind:key="post.id"
            v-bind:title="post.title"
          ></blog-post>
        </div>

        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
        <script>
        Vue.component('blog-post', {
                                props: ['title'],
                                template: '<h3>{{ title }}</h3>'
                              })

                              new Vue({
                                el: '#app',
                                data: {
                                  posts: [
                                    { id: 1, title: 'My journey with Vue' },
                                    { id: 2, title: 'Blogging with Vue' },
                                    { id: 3, title: 'Why Vue is so fun' }
                                  ]    
                                }
                              });

        </script>
    </body>
</html>

 

 

 

3-1) 단일루트

컴포넌트는 단일루트로 감싸져야 한다.

여러 데이터를 자식 컴포넌트로 전달해야 할 때, 전달되어야 할 모든 값을 props로 전달하는 것이 아니라, 하나의 객체로 묶어 props로 넘기는 것이 효율적이다. 나중에 추가로 값을 전달해야 할 경우, props를 추가하는 것이 아니라 객체에 값을 추가하여 넘겨주는 것으로 코드 변경을 최소화 할 수 있다. 

 

더보기
<html>
    <head>
        <title>Vue Component Registration</title>
    </head>
    <body>
        <div id="app">
          <blog-post
            v-for="post in posts"
            v-bind:key="post.id"
            v-bind:post="post"
          ></blog-post>
        </div>

        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
        <script>
        Vue.component('blog-post', {
            props: ['post'],
            template: `
              <div class="blog-post">
                <h3>{{ post.title }}</h3>
                <div v-html="post.content"></div>
              </div>
            `
          })

          new Vue({
            el: '#app',
            data: {
              posts: [
                { id: 1, title: 'My journey with Vue', content: '1st' },
                { id: 2, title: 'Blogging with Vue', content: '2nd' },
                { id: 3, title: 'Why Vue is so fun', content: '3th' }
              ]
            }
          });


        </script>
    </body>
</html>

 

 

 

4) $emit 부모 컴포넌트로 데이터 전달

- 자식 컴포넌트에서 부모 컴포넌트로 데이터를 전달해야 할 때 사용되는 것이 $emit다.

- 이벤트를 전달함으로써, 콜백내 this를 통해 상위 데이터에 접근하는 방법

컴포넌트 methods속성 내에 여러 이벤트들을 정의할 수 있는데, 정의한 custom event를 트리거하려면 $emit메서드에 이벤트 이름을 전달하면 된다. 

더보기

 

<html>
    <head>
        <title>Vue Component Registration</title>
    </head>
    <body>
          <div id="app">
            <div :style="{ fontSize: postFontSize + 'em' }">
              <blog-post
                v-for="post in posts"
                v-bind:key="post.id"
                v-bind:post="post"
                @enlarge-text="postFontSize += 0.1"
              ></blog-post>
            </div>
          </div>

        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
        <script>
       Vue.component('blog-post', {
            props: ['post'],
            template: `
              <div class="blog-post">
                <h3>{{ post.title }}</h3>
                <button @click="$emit('enlarge-text')">Enlarge text</button>
                <div v-html="post.content"></div>
              </div>
            `
          })

          new Vue({
            el: '#app',
            data: {
              posts: [
                { id: 1, title: 'My journey with Vue', content: '1st' },
                { id: 2, title: 'Blogging with Vue', content: '2nd' },
                { id: 3, title: 'Why Vue is so fun', content: '3th' }
              ],
              postFontSize: 1
            }
          });


        </script>
    </body>
</html>

 

 

4-1 ) $emit으로 부모 컴포넌트에 데이터 전달하기 (무슨소리지..)

$emit메소드의 두번째 파라미터를 사용하면, 부모 컴포넌트로 데이터 전달이 가능하다. 

 

 

더보기

 

<html>
    <head>
        <title>Vue Component Registration</title>
    </head>
    <body>
       <div id="app">
          <div :style="{ fontSize: postFontSize + 'em' }">
            <blog-post
              v-for="post in posts"
              v-bind:key="post.id"
              v-bind:post="post"
              @enlarge-text="onEnlargeText"
            ></blog-post>
          </div>
        </div>

        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
        <script>
        Vue.component('blog-post', {
              props: ['post'],
              template: `
                <div class="blog-post">
                  <h3>{{ post.title }}</h3>
                  <button @click="$emit('enlarge-text', 0.1)">Enlarge text</button>
                  <div v-html="post.content"></div>
                </div>
              `
            })

            new Vue({
              el: '#app',
              data: {
                posts: [
                  { id: 1, title: 'My journey with Vue', content: '1st' },
                  { id: 2, title: 'Blogging with Vue', content: '2nd' },
                  { id: 3, title: 'Why Vue is so fun', content: '3th' }
                ],
                postFontSize: 1
              },
              methods: {
                onEnlargeText: function (enlargeAmount) {
                  this.postFontSize += enlargeAmount
                }
              }
            });




        </script>
    </body>
</html>

 

 

 

4-2 ) 컴포넌트에서 v-model사용하기

input태그에서 v-model을 사용할 경우,

value attribute는 컴포넌트의 value prop와 바인딩 된다.

input이벤트는 컴포넌트에서 $emit으로 호출되는 이벤트이다.

 

https://beomy.tistory.com/57

 

[Vue.JS] 컴포넌트 (고급:Custrom Events)

1. 이벤트 이름 $emit 을 이용하여 커스텀 이벤트를 만들 때, 이벤트 이름은 kebab-case를 사용하는 것이 좋습니다. 컴포넌트의 이름이나 prop의 이름과 달리 이벤트 이름은 자동으로 변환(camelCase kebab-

beomy.tistory.com

 

5) slot사용하기

컴포넌트를 사용할 때 HTML엘리먼트와 같이 컴포넌트에 콘텐츠를 전달해야 하는 경우가 있을 때 사용하는 것

https://beomy.tistory.com/58

 

[Vue.JS] 컴포넌트 (고급:slot)

1. Slot Content Your Profile 부모 컴포넌트에서 자식 컴포넌트를 위의 코드와 같이 사용하여 자식 컴포넌트의 하위 엘리먼트의 값들을 보여주고 싶다면, 위의 코드와 같이 자식 컴포넌트가 작성되어

beomy.tistory.com

 

6) 동적 컴포넌트

<component> is사용

https://beomy.tistory.com/59

 

[Vue.JS] 컴포넌트 (고급:Dynamic & Async Components)

1. 동적(Dynamic) 컴포넌트와 keep-alive [Vue.JS] 컴포넌트 (기본) 에서 동적 컴포넌트에 관한 이야기를 하였습니다. 위의 코드와 같이 is 를 사용하여 동적으로 컴포넌트를 랜더링 할 수 있습니다, is 를

beomy.tistory.com

 

 

7) DOM템플릿 문법 경고 해결

<ul>,<ol>,<table>,<select>등의 HTML태그들의 자식 태그로는 <li>,<tr>,<option>등으로 항상 정해져 있다. 이런한 규칙을 어기면 DOM은 경고를 뱉어낸다.

<table> 
	<blog-post-row></blog-post-row> 
</table>

이런 코드가 있을 때 teble의 자식은 tr 등이다. 그렇지 않은 경우 DOM은 경고를 발생시킨다.

이 때 DOM이 발생하는 경고를 피하기 위한 is를 사용할 수 있다.

<table> 
	<tr is="blog-post-row"></tr> 
</table>

위와 같이 is를 사용하거나

- template속성을 사용한다. (template : '...')

- .vue파일로 컴포넌트를 생성한다

- <script type="text/x=emplate">를 사용한다.

 

 

8) 동등 컴포넌트 간 통신

- 같은 레벨의 컴포넌트(부모가 동일한)가 데이터를 전달하려면 

emit (상위 컴포넌트로 전달) -> props(하위 컴포넌트로 전달)과정을 거쳐야 한다. 

 

 

 


[참조]

https://vuejs.org/v2/guide/components.html

 

Components Basics — Vue.js

Vue.js - The Progressive JavaScript Framework

vuejs.org

https://jinyisland.kr/p/vue-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B0%9C%EB%85%90/

 

Vue 컴포넌트에 대한 개념

컴포넌트 개념 화면의 영역을 분리하여 개발하는 것, Vue에서 최상위 컴포넌트는 root이다. 컴포넌트 구성의 장점은 요소들을 재사용함으로써 개발 생산성이 향상되고, 컴포넌트들은 서로 관계가

jinyisland.kr

https://goddino.tistory.com/88

 

[js] vue.js 컴포넌트 생성(컴포넌트로 쪼개기)

vue.js 하위 컴포넌트 만들기 한개 이상의 페이지를 레이아웃 또는 기능별로 쪼개어 분리하고, 상위 vue 파일에서 통합 관리 하는 것을 컴포넌트화 라고 합니다. 순서 1. 폴더 안에 각 하위 컴포넌

goddino.tistory.com

https://beomy.tistory.com/55

 

[Vue.JS] 컴포넌트 (기본)

이번 포스트에서는 SPA에서 가장 중요하다 이야기 되는 컴포넌트에 관해 이야기 할 것입니다. 1. 기본 예제 // Define a new component called button-counter Vue.component('button-counter', { data: function..

beomy.tistory.com

 

반응형

'차근차근 > JAVA Script' 카테고리의 다른 글

자바스크립트 위치..?  (0) 2021.12.07
[Vue.js] v-cloak  (0) 2021.12.06
[Vue.js] Vue.js란 (4) - Vue 인스턴스  (0) 2021.12.03
[Vue.js] Vue.js란 (3) - Vue 문법  (0) 2021.12.03
[Vue.js] Vue.js란 (2)  (0) 2021.12.03