HTML에 기반을 둔 커스텀 엘리먼트인 컴포넌트를 제작하고 활용

컴포넌트의 상탯값 관리와 뷰 간의 이동을 도와주는 Vuex와 라우터제공

 

05-1 복잡한 로직과 computed 속성  

computed 속성 : 머스태시를 이용해 HTML 엘리먼트값 변경에 따른 연산 작업지원

 - 원본 data를 수정으로 필요성 확인

 

* 010501 [DoIt!실습] 대문자로 변환하는 프로그램 만들기

- 0105/ex05_01 > computed.html 파일 생성

<!DOCTYPE html>
<html lang="KO">
<head>
    <meta charset="UTF-8">
    <title>computed</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
    <div id="main">
        <p>원본 문장 : "{{ sOriginalMessage }}"</p>
        <p>대분자로 변환된 문장 : "{{ fnUpperCaseMsg }}"</p>
    </div>
    <script>
        new Vue({
            el:'#main',
            // data는 머스태시 안에 넣을 값이 간달할 때 사용
            data:{
                sOriginalMessage: 'How are you?'
            },
            computed:{
                // sOriginalMessage의 데이터를 모두 대문자로 변환
                // 이때 데이터에 접근하기 위해 this 사용
                fnUpperCaseMsg: function(){
                    return this.sOriginalMessage.toUpperCase();
                }
            }
        })
    </script>
    
</body>
</html>

 

* 머스태시 사용 : 문자열을 {{}} 로 감싸고 엘리먼트(P) 값 표시 
 - {{ sOriginalMessage }} : 문자열 변수 대체

 - {{ fnUpperCaseMsg }} : 함수실행결과 대체

* data 속성

 - 문자열 변수(sOriginalMessage - 속성 : JSON 형식내 값 > 뷰에서는 변수처럼 처리됨) 값 초기화

* computed 속성 : computed 속성은 캐시 메모리에 저장 - 속도개선 효과 기대

 - 머스태시 내용이 복잡한 경우 함수로 전환하여 사용

 - fnUpperCaseMsg() 함수에서 this를 사용하여 data에 정의된 변수(sOriginalMessage)를 사용하여 처리함


05-2 이벤트 핸들러 로직과 methods 속성  

* 메서드 :  뷰 인스턴스에 포함해 사용하는함수

 - methods 속성 : 이벤트 핸들러를 사용해 이벤트 실행로직 작성(마우스 클릭 등)
 - 예제 : 버튼을 누를 때마다 10부터 거꾸로 세는 예제

 > computed 속성 : 머스태시 확장할 때 사용

 > methods 속성 : 이벤트 핸들러에 사용

 

* 010502 [DoIt!실습] 카운트다운 프로그램 만들기

- 0105/ex05_02 > computed.html 파일 생성

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>mothods</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
    <div id="main">
        <p>클릭 숫자 : {{nClicks}}</p>
        <p>카운트다운 : {{fnCounter}}</p>
        <!-- 버튼을 누르면 fnIncrement 메서드 실행 -->
        <button v-on:click="fnIncrement">눌러주세요!</button>
    </div>
</body>
<script>
    new Vue({
        el:'#main',
        data:{
            nClicks:0
        },
        // computed는 머스태시 안의 로직이 복잡할 때 사용
        computed: {
            fnCounter(){
                // nClicks 값이 10을 기준으로 카운트다운 되도록 1만큼 감소시킴
                return 10 - this.nClicks;
            }
        },
        // 메서드는 이벤트 핸들러 로직을 실행할 때 사용
        methods:{
            // nClicks 값을 1만큼 증가시킴
            fnIncrement(){
                this.nClicks++;
            }
        }
    });
</script>
</html>

* 머스태시적용

 - nClicks : 클릭개수 정보 변수를 바인딩 - 엘리먼트(p)

 - fnCounter() : 카운트로 변경되는 값 반환 - 10부터 시작하는 카운트다운 처리

* v-on 디렉티브 적용

 - 버튼을 누르면 fnlncrement() 함수를 이벤트 핸들러로 연결하여 실행

 > fnlncrement() 함수의 구체적인 기능을 methods 속성에서 정의한다

* data, computed 속성

 - data : nClicks 변수 초기값 설정 - 0

 - computed : 머스태시 선언 함수 기술 - fnCounter()
 > fnCounter() 함수는 10을 기준으로 지금까지 클릭한 횟수를 저장

 > nClicks 변수값과 뺄셈을 수행

 * 머스태시에 선언된 내용의 로직이 복갑해지면 함수로 바꿔서 computed 속성에 정의

* methods 속성

 - fnlncrement() 함수 : nClicks 변수(클릭한 횟수 저장) 값을 ++ 연산자로 증가시킨 후 반환

 > data 속성에 정의된 nClicks 변수에 접근하기 위 해 this를 사용

 

* [하나만 더 배워요!] computed 속성과 methods 속성의 차이점

 - 함수 정의 시 두 속성의 역할 : 함수 실행

 • computed 속성 : 복잡한 로직으로 머스태시 작업을 함수로 정의 - 계산량이 많아 캐시가 필요할 때
 • methods 속성 : 뷰의 이벤트 핸들러 로직을 함수로 정의


05-3 컴포넌트로 HTML 엘리먼트 만들기  

* 컴포넌트(component) : HTML의 기본 엘리먼트 외에 자신만의 엘리먼트 제작 지원

 

* 컴포넌트의 동작 원리 이해하기

 - 컴포넌트 사용법 : HTML 엘리 먼트와 동일.  여는 태그 <>, 닫는 태그 </>에 적용해 사용
  > <my-element></my-element>

 - 템플릿(template) : 컴포넌트를 등록하여 엘리먼트처럼 사용
 - 컴포넌트를 신규 엘리먼트로 구성 시 화면에 표시할 부분을 대응하는 속성 : 템플릿 속성

  > 기존 HTML, CSS, 자바스크립트를 사용해서 화면에 표시할 내용 구현

  > 사용 방법 : [template:] 속성 선언 > 문자열로 HTML 문서의 내용을 작성

 ** 문자열 줄바꿈을 고려한 이스케이프 문자 사용 : 역따음표(',backtic-백틱) - 예제 참고 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>component</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
    <div id="main">
        <my-element></my-element>
    </div>
</body>

<script>
    // my-element 엘리멘트용 컴포넌트 등록
    Vue.component('my-element',{
        // 컴포넌트의 data 속성은 반드시 함수로 정의!
        data: function(){
            return {
                strHello: '안녕하세요',
            }
        },
        // 템플릿은 화면에 표시할 엘리멘트 구조를 정의
        template: `<h1>{{strHello}}</h1>`
    });
    new Vue({
        el:'#main',
    });
</script>
</html>

* 010503 [DoIt!실습] 좋아하는 과일 나열하기

- 0105/ex05_03 > component_basic.html 파일 생성

- 화면에 표시할 내용 : template 속성으로 HTML, CSS, 자바스크립트를 함께 사용하면서 작성
- 백틱을 사용한 가독성 확보
 > 예제 활용 : template, data 속성만 사용하지 만 computed, methods 속성도 활용

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>component_basic</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <style>
        .fruit_style {/* 테두리 스타일과 안쪽 여백을 넣어줌*/
            border: 1px solid #ccc;
            background-color: #fff;
            padding-left: 1em;
        }
    </style>
</head>
<body>
    <div id="main">
        <h1>{{ sTitle }}</h1>
        <!-- 신규 컴포넌트 엘리먼트 2개 사용 -->
        <favorite-fruits></favorite-fruits>
        <favorite-fruits></favorite-fruits>
    </div>
</body>
<script>
    // 좋아하는 과일 3개를 표시하는 컴포넌트 정의
    Vue.component('favorite-fruits',{
        // 컴포넌트의 data 속성은 반드시 함수로 정의
        data: function(){
            return {
                aFruits:[{sFruit_name:'사과'}, {sFruit_name:'오렌지'},{sFruit_name:'수박'}]
            }
        },
        // 컴포넌트 템플릿 화면에 표시할 엘리먼트 구조 정의
        template:`
        <div>
            <div v-for="item in aFruits" class="fruit_style">
                <p>좋아하는 과일:{{item.sFruit_name}}</p>
            </div><br>
        </div>`
    });
    new Vue({
        el:'#main',
        data:{
            sTitle:'안녕하세요!'
        }
    });
</script>
</html>

* 박스 스타일

 - 화면에 표시할 영역을 눈으로 쉽게 확인하기 위해 CSS 스타일 적용

 - [.fruit_ style]이라는 클래스 선택자로 경계선 구성

 > 선 : 직선, 두께 : 1px, 색상 : #ccc(회색) 설정

 > 배경색 : 흰색

* 컴포넌트 사용

 - sTitle(제목 문자열) 변수 : h1 엘리먼트의 값으로 표시.

 - h1 엘리먼트 : HTML5 예약어는 커스텀 불가

 - favorite-fruits 커스텀 엘리먼트 : HTML 엘리먼트와 같은 방식으로 사용

 > 좋아하는과일 세 가지 목록을 표시

 > 두 번 연속 사용 : 두 번 표시됨

* 컴포넌트 등록 - 뷰 객체의 component() 함수를 사용해 엘리먼트 등록

 - 매개변수1 : [favorite-fruits] 전달

 - 매개변수2 : [data, template] 속성 정의

 > data 속성 : aFruits 배열을 JSON 형식으로 정의 - 변수나 함수로 선언

 > aFruits 배열 :  sFruit_name, 과일 이름(사과, 오렌지, 수박) 항목 3개 구성

 - function() 함수에서 return 문으로 반환

** 컴포넌트에서 data 속성을 사용할 때는 반드시 함수로 사용

 - 컴포넌트 안에 data 속성을 변 수로 선언하면 실행 시 인스턴스가 생성되지 않음
 > ‘ReferenceError: aFruits is not defined’라는 오류 발생

 - 같은 컴포넌트를 여러 개 사용 시, data 속성의 변숫값들이 별도의 메모리 공간에서 개별적으로 관리되도록 하려는 의도 

 - 따라서 컴포 넌트 내부는 반드시 함수로 작성해야 합니 다.

* 컴포넌트 템플릿 작성

 - div 엘리먼트로 그룹

 - v-for 디렉티브를 사용해서 aFruits 배열 변수에 있는 항목을 하나씩 꺼내서 표시

 - p 엘리먼트에 머스태시로 바인딩하기 위해 {{ item.sFriiit_name }} 입력

 > 항목이 3개 표시, fruit_ style 클래스 선택자로 스타일 적용

 

* [하나만 더 배워요!] 목록의 구조를 잡을 때 사용하는 ul, ol, li 엘리먼트
 - ul(unordered list)과 ol(ordered list) : 목록 영역 결정
 > ul : 순서 없는 목록 - 글머리 기호 항목 앞에 표시

 - li(list) : 목록의 각 항목 표시

 > ol : 순서 있는 목록 - 항목 앞에 번호가 하나씩 커지면서 표시

<!-- ul, ol, li 엘리먼트사용 예 -->

<ul>
  <li>사과 </li> <li> 바나나 </li> <li> 수박 </li>
</ul> 

<ol>
  <li> 커피 </li> <li> 홍차 </li> <li> 녹차 </li>
</ol>




05-4 컴포넌트 속성 props  

* 컴포넌트 속성(props) : 컴포넌트에서 전달되는 어트리뷰트의 값
 - 문자열, 객체 배열 형식

 > 좋아하는과일 나열 예제 변경 : 컴포넌트 엘리먼트로 props 속성 사용

 

* 010504 [DoIt!실습] 컴포넌트 속성을 활용해 좋아하는 과일 나열하기

- 0105/ex05_04 > component_prop.html 파일 생성

 

* 뷰 컴포넌트의 어트리뷰트를 선언하는 방법, 값을 전달받아 사용하는 방법 확인

 - 뷰의 컴포넌트 기능은 HTML의 일반엘리먼트처럼 사용할 수 있으므로 기능을 무한대로 확장가능

 > 다양한 주제별로 그에 맞는 엘리먼트 설계해서 사용
 > 의미있는 컴포넌트 엘리먼트 이름으로 심플코드 개발 가능(어트리뷰트 설계 유의) : 유지보수 용이

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>component_prop</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script>
        // Vue 인스턴스에 신규 엘리먼트 컴포넌트 등록
        // props에 엘리먼트에 사용될 속서 이름 선언
        // template에 전달받은 속성 객체의 text 제목을 렌더링에 활용
        Vue.component('favorite-fruits', {
            props: ['fruit'],
            template:`<li>{{ fruit.text }}</li>`
        })
    </script>
</head>
<body>
    <div id="app">
        <h1>좋아하는 과일!</h1>
        <ol>
            <!-- 
                favorite-fruits 신규 엘리먼트 사용
                aFruits 배열의 값을 반복문으로 가져와 fruit 속성에 바인딩하여 컴포넌트에 전달
                key 속성은 반드시 고유한 값으로 전달되어야 하므로 item의 id값 대입
             -->
             <favorite-fruits
              v-for="item in aFruits"
              v-bind:fruit="item"
              v-bind:key="item.id">
             </favorite-fruits>
        </ol>
    </div>
    <script>
        var app = new Vue({
            el:'#app',
            data:{
                aFruits:[
                      {id:0, text: '사과'}
                    , {id:1, text: '오렌지'}
                    , {id:2, text: '수박'}
                ]
            }
        });
    </script>
</body>
</html>

* 컴포넌트등록 

 - 컴포넌트 : HTML 엘리먼트와 동일하게 사용 - 어트리뷰트 사용가능

 > props 속성 선언

 - 선언된 이름을 다른 속성에서 전달받아 매개변수처럼 사용

* 컴포넌트 등록 (이름 : favorite-fruits)

 - props 속성에 대괄호([])를 사용해서 어트리뷰트 이름을 문자열로 선언
 > HTML에서 favorite-fruits 엘리먼트를 사용할 때 다음과 같이 fruit 어트리뷰트에 값 전달

 <favorite-fruits fruit="사과"></favorite-fruits>

* template 속성에 li 엘리먼트로 속성값 표시

 - 머스태시로 <li>{{ fruit.text }}</li> 작성 :  li 엘리먼 트값으로 바인딩
 > 속성값으로 전달받은 fruit 변수는 text 속성으로 전달

 > 유의 : props 속성에 선언하여 어트리뷰트로 전달받은 fruit 변수 : 일반 변수처럼 사용가능

* 컴포넌트사용 

 - favorite-fruits 컴포넌트를 등록 > 일반적인 HTML 엘리먼트처럼 사용

 > 소스에서는 먼저 ol로 순서 있는 목록의 영역 지정

 - 목록의 개별 항목은 li 엘리먼트 대신에 favorite-fruits 엘리먼트 사용

 > favorite-fruits 엘리먼트 : 내부적으로 li 엘리 먼트를 가지 면서 전달받은 속성값을 표시하도록 설계

 - 신규로 등록한 컴포넌트의 엘리 먼트에 어트리뷰트를 어 떻게 사용하는지 잘 표현

 - v-for 디렉티브도 사용가능 : aFruits 배열 변수에서 값을 꺼내 item에 하나씩 저장

 - v-bind 디렉티브를 사용해서 fruit 어트리뷰트에 바인딩하여 항목값을 전달

 > v-bind:key 바인딩은 v-for 디렉티브를 사용할 때는 key 어트리뷰트에 고유한 값 전달해 사용하도록 강제
 > item.id의 값을 전달하면 간단히 해결

* data 속성 

 - aFruits 배열 변수 : data 속성에 정의

 > JSON 형태로 id와 text에 번호와 과일 이름을 저장

 


05-5 상탯값 관리와 Vuex  

 

 


05-5 상탯값 관리와 Vuex  

 

 


05-6 내비게이션과 라우터  

 

 


05-7 새로 고침이 필요 없는 SPA 만들기  

 

 

+ Recent posts