드디어 뷰다뷰

04-1 뷰, 자바스크립트프레임워크의절대 강자

* 뷰 (Vue.js)

 - 2013년 출시 : 에반 유(Evan You) 개발 - 자바스크립트 프레임 워크

 - 앵귤러, 리액트에서 발견할 수 없는 콤팩트한 프레임워크 제작

 - 훌륭한 문서, 제이퀴리를 넘어선 좋은 아이디어 결합

 > 뷰 2.0부터 크게 주목

 

https://ko.vuejs.org/

 

Vue.js - The Progressive JavaScript Framework | Vue.js

접근성 HTML,CSS, 자바스크립트 표준을 기반으로, 쓰기 편한 API와 최고 수준의 문서를 제공합니다.

ko.vuejs.org

 

* 목적 : 인터랙티브 웹 인터페이스를 개발 - 프로그레시브 자바스크립트 프레임워크

 - 프로그레시브(progressive) : 프로그램 실행에 필요한 최소한의 모듈로부 터 점점 확장

 > 웹에서 UI, 비즈니스로직, 데이터 관리를 돕는 최고 성능의 콤팩트한 자바스크립트 라이브러리 

 

[뷰가 주목받는 4가지 이유]

 - 뷰의 기능 대부분이 앵귤러, 리액트와 유사하며 가상 돔(virtual DOM)을 제어하는 기능도 제공

① 디자이너와 개발자를 위해 쉽게 설계

 - HTML과 CSS 토대에서 동작 : 기존 웹 표준 작업과 유사

 - 접근성이 좋은 공식 문서

  (리액트 : JSX라는 새로운 문법 공부, 모두 자바스 크립트로만 관리 - 진입 장벽이 높음)

② MVC(model view controller) 모델을 지원

 - 리액티브 양방향 데이터 바인딩(reactive two-way data binding) 지원 (like 앵귤러)

 > 리액티브 : 데이터의 변화를 자동으로 체크해서 화면을 바꾸는 동기화

 - DOM 작업에 집중할 수 있도록 직관적으로 쓰기 편한 디렉티브를 제공

③ HTML5와 자바스크립트만 알면 되므로 쉽게 시작

 - 뷰는 HTML5와 자바 스크립트만 필요

 - 앵귤러 비

 > 정적 타입의 자바스크립트를 위해 만든 타입스크립트(TypeScripr)문법 필요

 > 파일 구조 복잡, 큰 덩치

④ 설치하기 쉽고 용량이 작아서 속도가 빠르다

 - 설치하기 쉽고 필요한 파일 용량이 작다.

 - HTML, CSS, 자바스 크립트환경에서 연결해 사용하기 편리

 

[뷰, 자바스크립트 프레임워크의 절대 강자!]

 - 뷰 : 출발은 늦었지만 두 프레 임 워크의 단점 보완 - 성능 우수

 > 앵귤러, 리액트에 비해 전망이 좋다.

 - 자바스크립트 관련 기술 트렌드 통계 :  bestofjs.org

 

 


04-2 ‘안녕하세요!’ 예제 만들기

* 핵심내용

 - 처음 시작을 CDN으로 설정 하는 방법

 - 머스태시 {{ }}  활용법

 - data 속성 바인딩 관계

 

* 010402 [DoIt!실습] 뷰로 ‘안녕하세요!’ 출력하기

- 0104/ex04_01 > hello_vuejs.html 파일 생성

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>hello_vuejs</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>

<body>
    <div id="main">
        <!-- sTitle값을 받아서 HTML의 엘리멘트값으로 변환하여 표시 -->
        <p>{{ sTitle }}</p>
    </div>    
    <script>
        // VUE 객체를 생성해 앱을 초기화하고 시작
        new Vue({
            // id 선택자인 'main'의 div 엘리먼트와 앱을 연결해서 구동
            el : '#main',
            data : {
                // {{ sTitle }}로 데이터값 전달
                sTitle : '안녕하세요!'
            }
        });
    </script>
</body>
</html>

* 보완 : cdn 참조링크
 - 교제 : https://cdn.jsdelivr.net/npm/vue 

 > 수정 : https://cdn.jsdelivr.net/npm/vue@2

 

 * 뷰 적용시 가장 쉬운 방법 : cdn 연결
  -  방법 : 뷰 모듈 주소를 head 테그 사이에 설정

 * 머스태시 사용 : 변수, 함수 결과를 html의 엘리먼트 값으로 변환하여 브라우저에 출력 - 랜더링(rendering)

  -  중괄호 2개를 겹쳐서 표현 : 콧수염 모양과 미슷하여 '머스태시'라고 함

  > {{ sTitle }} : sTitle 문자열 값을 p 엘리먼트의 값으로 변환하여 표시

 * 뷰 앱 구동 

  - 뷰 객체 생성 : HTML의 body 엘리먼트 중, 뷰 화면이 표시될 영역을 el(element) 속성에 선택자로 지정

  > [el : '#main'] - el속성에 #main 으로 div 엘리먼트 부분을 연결 : #main 부분에 뷰 실행내용이 렌더링 됨

 * data 속성

  - 뷰안에서 사용할 데이터를 변수명으로 선언하여 관리

  > 객체, 함수 선언 - 데이터를 읽고 저장하는 일 지원 : 리엑티브(reactive) 하다고 표현?

  - [sTitle : '안녕하세요!'] 문자열의 제목을 저장하는 sTitle 변수의 초기값 정의

  > 뷰에서 HTML 엘리먼트와 함께 머스태시 안에 바인되어 자동으로 표시할 때 sTitle 값 활용

  (sTitle 값을 HTML 구조 안에서 직관적으로 활용 가능)


04-3 단방향 바인딩과 v-bind 디렉티브

 

데이터 바인딩 : HTML의 어트리뷰트값을 수정할 때 V-bind라는 디렉티브를 이용해서 데이터를 브라우저 화면에 지동으로 반영하는 것

 - 변수값을 HTML 어트리뷰트값에 연결 : 변수가 새로운 값으로 바뀔 때마다 HTML 엘리먼트에 실시간으로 렌더링

 > v-bind 디렉터브는 데이터가 한쪽으로만 바인딩되는 단방향 바인딩 (양방향 : v-model - 04-4절)

    (HTML 엘리먼트의 어트리뷰트값 변경시, 연결된 변수값은 변경안됨)

 

* 010402 [DoIt!실습] 올해 연도를 자동으로 표기하는 프로그램 만들기

# 0104/ex04-02/v-bind.html

<!DOCTYPE html>
<html lang="kr">
<head>
    <meta charset="UTF-8">
    <title>v-bind</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <style>
        /* 화면에 렌더링할 때 사용할 제목의 색상을 파란색으로 정의 */
        .blue_style {color: blue;}
    </style>
</head>
<body>
    <div id="main">
        <!-- v-bind 안에서도 자바스크립트를 사용할 수 있으므로 변수와 문장을 연결 -->
        <h1 v-bind:class="sColorName + '_style'">안녕하세요!</h1>
        <!-- 콜론(:) 앞은 생략 가능 -->
        <!-- <input:value="sDate"/> 화면깨짐 -->
        <input v-bind:value="sDate"/>
    </div>
    <script>
        let app = new Vue({
            el: '#main',
            data:{
                // Data 객체의 getFullYear() 메서드로 올해 연도 문장 준비
                sDate: '올해 연도: ' + new Date().getFullYear(),
                sColorName: 'blue'
            }
        })
    </script>
</body>
</html>

* 제목에 CSS 스타일 적용 : 뷰는 CSS 스타일을 그대로 활용 - 웹 표준 활용 가능
 - 제목의 글자 색상 스타일 파란색으로 변경

 > .blue_style 클래스 선택자 이용 : color: blue 정의

* v-bind 디렉티브 적용
 - <h1> 태그 안에서 class 어트리뷰트와 뷰의 속성 바인딩 : v-bind 디렉티브 활용

 > v-bind 입력 > 콜론(:)  > 바인딩할 뷰의 속성 연결
 - sColorName 색상 문자열 제목 + _style 연결 : 클래스 선택자 이름

 > class 어트리뷰트에 대입 : sColorName 값이 blue > blue_style 완성된 선택자 이름

 > v-bind 디렉티브를 통해 바인딩 : class="blue_style" 대입

 > h1 엘리먼트 : 파란색 제목으로 표시

* v-bind 생략 : 되나? 된다. 책 코드 자세히 보면 input 뒤에 스페이스가 있...
 - v-bind는 콜론(:)만 남기고 생략 가능

 > input 엘리먼트에서 :value만 사용 : value 어트리뷰트에 sDate의 날짜를 문장으로 받아서 대입

 > input 엘리먼트를 통해서 만들어진 텍스트 박스 안에 오늘 날짜 표시

 > (:) 만 있고 엘리먼트의 어트리뷰트 이어서 표시 : 'v-bind' 디렉티브 생략

* sDate와 sColorNamedata 속성
 - 올해 연도 저장 : sDate 문자열 변수

 - CSS 스타일에 사용 : sColorNam 문자열 변수

 > 올해 연도 : 자바스크립트의 Date객체 생성 - getFullYear() 메서드 : 올해 연도를 숫자로 반환 - sDate에 저장

 > ‘blue’라는 문장을 sColorName 변수에 초기값으로 대입

 > sDatesColorName 두 변수에 담긴 문자열은 v-bind 디렉티브를 사용해서 바인딩할 때 적용

 

* 화면깨짐 : <input:value="sDate"/>
 - Vue 버전 영향인 둣  > input 다음에 공백(스페이스) 있었...

* 개선소스 결과

 

* 하나만 더 배워요! - 머스태시와 v-bind의 차이점

 - 머스태시({{ }}) : HTML의 값을 만들 때 사용

 - v-bind : HTML 어트리뷰트에 바인당할 때 사용

머스태시와 v-vind 차이점
<p>{{ sTitle }}</p> // HTML 엘리먼트값을 만듬
<input v-bind:value=”sDate"> // HTML 어트리뷰트값을 만듬

04-4 양방향 바인딩과 v-model 디렉티브

* 양방향 데이터 바인딩 : v-model 디렉티브를 사용
 - HTML 어트리뷰트에 양방향 데이터 바인딩을 수행

 > 작성 : v-model:[HTML 엘리먼트의 어트리뷰트]

 - 바인딩된 값이 해당 엘리먼트의 어트리뷰트에 대입

 > 엘리먼트의 어 트리 뷰트값이 변수와도 연동

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>v-model</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
    <div id="main">
        <p>{{ sMsg }}</p>
        <!-- v-model은 데이터를 가져오는 동시에 입력이 동기화 됨 -->
        <!-- 엘리먼트의 어트리뷰트는 'v-model:' 다음에 명시 -->
        <input v-model:value="sMsg">
    </div>
    <script>
        var main = new Vue({
            el:'#main',
            data: {
                sMsg:'안녕하세요!'
            }
        })
    </script>
    
</body>
</html>

 - v-model 디 렉티브 : v-bind와 비슷하지만 양방향으로 바인딩됨

 - 변수에 있는 값을 바인딩하여 HTML 어트리뷰트에 렌더링

 > sMsg라는 문자열 변숫값은 p 엘리먼트에 머스태시로 바인딩되어 HTML값을 표시

 > input 엘리먼트의 value 어트리뷰트는sMsg라는문자열 변수와 바인딩되어 input 엘리먼트 안에 값을 표시

 -  HTML 어트리뷰트의 값이 바뀌면 바인딩된 변수의 내용도 함께 동기화

 > input 엘리먼트의 입력값 변경 시 value 어트리뷰트에 저장

 > 저장된 값은 실시간으로 sMsg 변수와 연동되어 자동으로 저장

 >> input 엘리먼트에 입력된 값은sMsg 변수와 일치됨(동기화)

 - sMsg 문자열 변수는 상탯값을 저장하고 있으므로 data 속성에 정의 : 초기값 설정

 

* [ 하나만 더 배워요! ] v-bind v-model의 차이점

<input v-bind:value=’’sDate"> // sDate 값을 HTML 어트리뷰트에 보내기만 함
<input v-model:value="sMsg"> // sMsg 값과 입력값이 서로 연동됨

04-5 조건 판단과 v-if, v-else 디렉티브

* v-if 디렉티브 : 조건이 충족될 때만 렌더링을 수행하도록 돕는 어트리뷰트

 - HTML 엘리먼트중에서 어떤 것을사용할지 특정 조건을 기준으로 판단 시 사용

 > v-if 디렉티브에 조건을 바인딩해서 대입하면 true 또는 faIse에 따라 사용할 HTML 엘리먼트를 결정

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>v-if</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
    <div id="app">
        <h1>{{ bFlag }}</h1>
        <!-- v-if, v-else 로 직접 bFlag 데이터에 접근해 조건 판단 -->
        <p v-if="bFlag == true">앞면!</p>
        <p v-else>뒷면!</p>
    </div>
    <script>
        var app = new Vue({
            el:'#app',
            data:{
                // 난수(0~1) 생성 후 0.5보다 크면 true, 아니면 false 지정
                bFlag:Math.random() > 0.5
            }
        })
    </script>
</body>
</html>

 - h1 엘리먼트를 사용해서 true 또는 false라는 값을 가진 bFlag 변숫값을 제목으로 표시

 > v-if 디렉티브를 이용해서 true이면 p 엘리먼트값으로 ‘앞면!'

 > false이면 v-else 디렉티브에 지정한 엘리먼트를 실행하므로 ‘뒷면!'

 - 상황을 연출하기 위해서 random() 함수를 사용

 > random() 함수는 01 사이의 부동소수점 난수(임의의 수)를 생성
 >> 0.5보다 큰지 확인하는 조건을 설정 > 동전 던지기처럼 truefalse값을 bFlag에 저장


04-6 반복문과 v-for 디렉티브

* v-for 디렉티브 : 반복문으로 배열값을 읽어서 목록의 항목과 인덱스 변수에 저장하도록 돕는 어트리뷰트
- 반복문으로 데이터를 하나씩 차례로 꺼내서 사용할 때 유용

 > 값을 하나 꺼내 저장해 두는 항목변수(item)를활용해 원하는 데이터 속성에 접근

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-for</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
    <div id="main">
        <h1>좋아하는 과일은?</h1>
        <ol>
            <!-- v-for를 통해서 반복문으로 aFruits 과일 배열 데이터를 가져옴 -->
            <li v-for="item in aFruits">
                <!-- aFruits 안의 항목을 하나씩 꺼내서 HTML로 렌더링 -->
                {{ item.sFruitName}}
            </li>
        </ol>
    </div>
    <script>
        var main = new Vue({
            el:'#main',
            data:{
                // 과일 이름으로 이루어진 aFruits 배열을 데이터로 정의
                aFruits:[
                    {sFruitName : '사과'},
                    {sFruitName : '오렌지'},
                    {sFruitName : '포도'}
                ]
            }
        })
    </script>
</body>
</html>

 - 데이터를 하나씩 차례로 읽어 원하는 항목만 선택해서 표시 : 배열 데이터를 주로 활용

> 처음부터 끝까지 값을 하나씩 읽고 원하는 로직으로 바인딩한 후 HTML로 렌더링 하는 방식

 - aFruits라는 배열에 저장된 데이터 : v-for디렉터브를 이용해서 값을 하나씩 차례로 꺼낸 후 item이라는 변수에 대입

 - 머스태시를 이용해서 순서 있는 목록을 만드는 ol 엘리먼트의 리스트 항목인 li로 하나씩 연결

 > 과일 이름은 item 변수의 sFruitName 문자열 변수에 저장되었으므로 점(.)을 이용해서 접근

 - 과일 이름을 배열로 정의하기 위해 대괄호를 이용 : JSON 형식으로 저장

 > JSON : 중괄호를 사용하고 키(sFruitName)와 값(과일 이름)을 콜론(:) 으로 구분



04-7 이벤트 핸들러 실행과 v-on 디렉티브

* v-on 디렉티브 : 뷰에서 발생하는 이벤트를 지켜보면서 DOM 엘리먼트를 제어

 - 이벤트가 발생했을 때 이에 해당하는 함수를 실행하는 방식으로 사용자와 상호 작용시 사용

  > 작성 : v-on:[이벤트 이름]

 - 이벤트 핸들러 :  이벤트가 발생했을 때 실행되는 함수

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>v-on</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
    <div id="app">
        <h1>{{ sTitle }}</h1>
        <!-- 버튼을 누르면 fnChangeTitle 메서드로 이벤트 핸들러 수정 -->
        <button v-on:click="fnChangeTitle">눌러주세요.</button>
    </div>
</body>
<script>
    new Vue({
        el:'#app',
        data:{
            // sTitle의 초기값 설정
            sTitle:'안녕하세요!'
        },
        methods:{
            // 버튼을 눌렀을 때 sTitle의 제목값 변경
            fnChangeTitle(){
                // this는 Vue 객체의 인스턴스를 가리킴
                this.sTitle = 'Hello!'
            }
        }
    });
</script>
</html>

 - v-on 디렉티브를 이용해 button 엘리먼트를 click 이벤트에 바인딩해서 fnChangeTitleQ 함수를 실행

 - 화면에 표시되는 값이 실시간으로 바뀌도록 sTitle이라는 문자열 변수를 정의 : 초기값 설

 - methods 속성 : 이벤트를 발생시키거나 뷰 안에서 어떤 기능을 수행하는 모듈 형식의 함수를 만들 때 사용

 > methods 속성 안에 fnChangeTitleQ 함수정의 : 사용자가 버튼을 클릭했을 때 이벤트 핸들러로 실행

 - this 키워드는 methods 속성의 소유자를 지목 : this는 생성된 뷰 객체 자신

 > this를 사용하는 이유 : methods 속성의 소유자만이 바깥에 있는 data 속성에 접근 - sTitle값 사용

 

 

Uncaught TypeError: Cannot read properties of undefined (reading 'browserObject')
at webcontent.js:1:266
at webcontent.js:2:463
at webcontent.js:2:467

methods 를 method 로 오타 상태에서 라이브서버를 실행하니 화면이 안떴다. 그래서 오타를 수정하고 새로고침 상태에서 실행하니 위와 같은 오류메시지가 표시되며 이벤트가 동작하지 않았다. 
수정없이 라이브서버를 재실행 했더니 이벤트가 잘 동작했다.

그랬다9.


미션 코딩! v-for 디렉티브로 고객 정보 출력하기

 

1차 html 코딩

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>v-for-mission</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
    <div id="main">
        <h1>고객정보</h1>
        <!-- 
        * 번호 : 0
          이름 : 홍길동
          나이 : 27
        * 번호 : 1
          이름 : 이순신
          나이 : 30
        * 번호 : 2
          이름 : 김유신
          나이 : 40
        -->
        <ul >
            <li>
                번호 : 0
            </li>
            <p>이름 : 홍길동</p>
            <p>나이 : 27</p>
            <li>
            번호 : 1
            </li>
            <p>이름 : 이순신</p>
            <p>나이 : 30</p>
            <li>
            번호 : 2
            </li>
            <p>이름 : 김유신</p>
            <p>나이 : 40</p>
        </ul>
    </div>
    <script>
        var main = new Vue({
            el:'#main',
            data:{
            }
        })
    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>v-for-mission</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
    <div id="main">
        <h1>고객정보</h1>
        <!-- 
        * 번호 : 0
          이름 : 홍길동
          나이 : 27
        * 번호 : 1
          이름 : 이순신
          나이 : 30
        * 번호 : 2
          이름 : 김유신
          나이 : 40
        -->
        <ul v-for="item in customers">
            <li>
                번호 : {{item.no}}
            </li>
            <p>이름 : {{item.name}}</p>
            <p>나이 : {{item.age}}</p>
        </ul>
    </div>
    <script>
        var main = new Vue({
            el:'#main',
            data:{
                customers : [
                    {no:0, name:"홍길동", age:27}, 
                    {no:1, name:"이순신", age:30}, 
                    {no:2, name:"김유신", age:40}, 
                ]
            }
        })
    </script>
</body>
</html>

 


 

+ Recent posts