[Vue.js] Instance와 Template

geesuee·2021년 9월 27일
0

Vue.js

목록 보기
1/3
post-thumbnail

1. Vue.js란?

  • Front-End JavaScript Framework
  • 웹 페이지 화면을 개발하기 위한 오픈 소스 자바스크립트 프레임워크
  • 쉽고 유연한 방식의 데이터 바인딩과 재사용할 수 있는 컴포넌트 제공 → 신속한 프로토타이핑 가능

1) Vue 구조, MVVM 패턴

: Model + View + ViewModel

  • Model : 어플리케이션에서 사용되는 데이터와 그 데이터를 처리하는 부분
  • View : 사용자에게 보여지는 UI 부분
  • ViewModel : View를 나타내 주기 위한 Model이자, View를 나타내기 위한 데이터 처리(데이터 바인딩 및 데이터 수정) 부분

출처: 버미노트, [디자인패턴] MVC, MVP, MVVM 비교


2) Vue.js 사용 이유

  • HTML, CSS, JavaScript와 같은 친숙한 도구로 구성, 학습 시간 단축으로 개발 생산성 증대
  • 기존 프로젝트 적용 수월, 타 library들과 함께 사용 가능
  • 경량급 실행 library로 모바일 기기 위주 서비스에도 적합
  • 모듈화와 확장성을 염두해 둔 설계, 재사용 가능한 컴포넌트 사용 → 개발 및 확장 효율성 증대
  • 가상 DOM 사용으로 실행 성능, 속도 향상
  • v-model directive를 통한 양방향 데이터 바인딩
  • 활발한 커뮤니티와 지원 생태계

    이미지 출처: @cheershennah, 뷰 VUEJS란?

    잠깐🖐, 가상 DOM이란?

  • DOM = Document Object Model = HTML 문서를 하나의 tree 형태로 나타내고 tree는 node들로 구성
  • 브라우저 렌더링 과정
    - HTML 파싱하여 DOM tree 생성
    - css 파일, inline 스타일 파싱, DOM+CSSOM=render tree 생성
    - 스크린에서 좌표에 따라 위치 결정 Layout(reflow)
    - 실제 화면에 그리기 Paint(repaint)
  • 인터렉션에 의해 DOM에 변화가 발생하면, 그 때마다 render tree가 재생성됨
  • 어플리케이션이 커지면 DOM을 직접 조작하는 시간과 비용 증가 → 실행 속도 저하

  • Vue instance는 DOM의 복사본인 가상 DOM(Virtual DOM)을 활용하여 실제 변경된 부분만 DOM에 반영
    = 웹 브라우저 DOM을 직접 수정하지 않고 가상 DOM을 활용하여 필요 부분만 수정을 진행
  • DOM Listener가 DOM의 변경 내역에 대해 즉각적으로 반응하여 특정 로직 수행

잠깐🖐, 양방향 데이터 바인딩이란?

  • 사용자 입력과 데이터 소스 사이, 한 쪽 데이터에 변화가 생기면 즉각 반응하는 형태
  • 데이터의 변화를 감지해 템플릿과 결합하여 화면을 갱신하고, 화면에서의 입력에 따라 저장된 데이터를 즉각 갱신
  • DB 데이터와 사용자 화면 데이터가 계속해서 일치하게 되는 것



2. Instance

1) Vue instance code

new Vue({
  el : //Vue로 만든 화면이 표현되는 tag의 id, vue instance 적용 지점, 외부 접근 시 "변수.$el"
  data : //instance의 데이터 속성, 여러 데이터 저장 및 활용
  methods : //instance의 이벤트 정의
  template : //화면에 표시될 HTML/CSS 등 요소 정의
  created : //instance 라이프 사이클을 커스터마이징
});

2) Vue instance property

> template

Vue 화면에 표시될 html element나 style들을 설정, 미리 만들어둔 html(템플릿)

> methods

메소드들을 객체로 등록, 이벤트 처리 등 동적 작업 처리 시 사용, 함수처럼 호출하여 실행

> computed

Vue instance에 존재하는 데이터 조작시에 주로 사용, methods와 마찬가지로 함수처럼 호출하여 실행

data 객체 내 property에 변화가 발생할 때마다 반응

> watch

data 객체 내의 데이터를 모니터링 할 수 있으며, 특정 데이터에 변화가 발생하면 후속 처리 가능

> props

다른 컴포넌트와 데이터를 직접적으로 전달하는데 사용,
부모 컴포넌트 → 자식 컴포넌트로 데이터를 전달할 때 사용


3) Vue instance life cycle

  • instace 생성
  • template과 가상 DOM 생성
  • 이벤트 loop
  • instance 소멸



3. Template

  • Vue Template 구성 방식
    - 자바스크립트 표현식 : {{}}
    - 데이터 바인딩 : v-bind

1) 데이터 바인딩

  • {{}} (콧수염 괄호)를 사용하여 Vue instance의 데이터를 html 태그에 연결
  • Vue 외 다른 언어, 프레임워크에도 자주 사용되는 템플릿 문법
  • {{data}} 와 같이 사용

2) Vue directive

  • Vue에서 View에 데이터를 표현하는 등의 용도로 사용되는 특별한 속성
  • v-접두사 형태로 사용 : v-bind, v-for, v-if, v-model, ...
  • 화면의 요소를 직접 제어할 필요없이 Vue의 directive를 활용하여 화면 요소 조작 가능
  • +) v-model를 사용하여 양방향 데이터 바인딩(=화면에 입력한 값을 Vue instance 데이터와 즉시 동기화)
  • +) .number 수식어로 데이터 타입 변환 v-model.number="age"와 같이 사용
기능디렉티브 목록
텍스트 표현v-text, v-html, v-once
html 속성 바인딩v-bind
양방향 데이터 바인딩v-model
제어문v-if, v-else, v-else-if, v-show
반복문v-for

3) computed vs methods

  • computed : 데이터 연산들을 정의하는 영역
    데이터 값의 변화에 따라 자동으로 연산 수행
    데이터가 변경되지 않는 한 이전의 계산값 보유(캐싱⭕), 필요시 반환 → 동일한 연산을 반복수행 하지 않음
    복잡한 연산을 반복 수행해서 화면에 나타내야한다면 computed 속성 이용 권장
  • method : 메소드 호출시에만 해당 로직 수행, 수행할 때마다 연산(캐싱❌)



4. 리뷰 코드(아이러브 카페인☕)

오늘 학습한 내용을 복습하면서 작성해 본 코드 ☕아이러브 카페인🍰

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>step08-myArt.html</title>

        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <h1>아이러브 카페인</h1>

            <h2>메뉴</h2>
            <div id="menu">
                <span>coffee</span>
                <ul>
                    <li v-for="(value, key) in coffee">{{key}} - {{value}}</li>
                </ul>

                <span>juice</span>
                <ul>
                    <li v-for="(value, key) in juice">{{key}} - {{value}}</li>
                </ul>

                <span>bread</span>
                <ul>
                    <li v-for="(value, key) in bread">{{key}} - {{value}}</li>
                </ul>
            </div>

            <br />

            <div id="order">
                <h2>주문하기</h2>

                <label for="coffee-select">coffee 메뉴 선택 : </label>
                <select name="coffee-menu" id="coffee-select" v-model="sCoffee">
                    <option value="">--커피 메뉴를 고르세요--</option>
                    <option value="아메리카노">아메리카노</option>
                    <option value="카페라떼">카페라떼</option>
                    <option value="카푸치노">카푸치노</option>
                    <option value="바닐라라떼">바닐라라떼</option>
                </select>

                <br />

                <label for="juice-select">juice 메뉴 선택 : </label>
                <select name="juice-menu" id="juice-select" v-model="sJuice">
                    <option value="">--쥬스 메뉴를 고르세요--</option>
                    <option value="딸기쥬스">딸기쥬스</option>
                    <option value="오렌지쥬스">오렌지쥬스</option>
                    <option value="키위쥬스">키위쥬스</option>
                </select>

                <br />

                <label for="bread-select">bread 메뉴 선택 : </label>
                <select name="bread-menu" id="bread-select" v-model="sBread">
                    <option value="">--브레드 메뉴를 고르세요--</option>
                    <option value="레몬마들렌">레몬마들렌</option>
                    <option value="허니브레드">허니브레드</option>
                </select>

                <br />
                <h2>주문내역</h2>
                <ul>
                    <li
                        id="s-coffee"
                        v-for="(value, key) in coffee"
                        v-if="sCoffee == key"
                    >
                        {{key}} - {{value}}
                    </li>
                    <li
                        id="s-juice"
                        v-for="(value, key) in juice"
                        v-if="sJuice == key"
                    >
                        {{key}} - {{value}}
                    </li>
                    <li
                        id="s-bread"
                        v-for="(value, key) in bread"
                        v-if="sBread == key"
                    >
                        {{key}} - {{value}}
                    </li>
                </ul>
            </div>
        </div>

        <script>
            let model = {
                coffee: {
                    아메리카노: 2300,
                    카페라떼: 2500,
                    카푸치노: 2800,
                    바닐라라떼: 2900,
                },
                juice: {
                    딸기쥬스: 3000,
                    오렌지쥬스: 2900,
                    키위쥬스: 3100,
                },
                bread: {
                    레몬마들렌: 1000,
                    허니브레드: 4000,
                },
                sCoffee: "",
                sJuice: "",
                sBread: "",
                //price: "", 총 가격을 출력하려고 했던 시도..
            };

            new Vue({
                el: "#app",
                data: model,
            });
        </script>
    </body>
</html>

아쉬운 점 💧

  • option tag 안 내용은 v-for로 표현할 수 없는 것 같은데..방법이 있을까?
  • 주문내역에 출력된 가격의 합을 연산하여 총 가격을 출력하고 싶었는데 실패ㅜ
<h2>주문내역</h2>
	<ul>
    	<li id="s-coffee" v-for="(value, key) in coffee" v-if="sCoffee == key">
          {{key}} - {{value}} {{totalPrice(value)}}
        </li>
        <li id="s-juice" v-for="(value, key) in juice" v-if="sJuice == key">
          {{key}} - {{value}} {{totalPrice(value)}}
        </li>
        <li id="s-bread" v-for="(value, key) in bread" v-if="sBread == key">
          {{key}} - {{value}} {{totalPrice(value)}}
        </li>
    </ul>
...
new Vue({
	el: "#app",
	data: model,
    methods: {
      	totalPrice : function(n) {
       	this.price += n;
        }
    }
});

위와 같이 코드를 작성했는데,
무한루프 관련 에러 메세지가 찍히고 vue.js:634 [Vue warn]: You may have an infinite update loop in a component render function.,
price값은 아래와 같이 문자열을 주루루룩 붙인 것 처럼 나왔다...
- console.log(typeof(n))을 찍어본 결과 number가 나왔고..
- console.log(n)을 찍으면 선택한 메뉴 값 하나가 잘 찍힌다..
- 왜 무한루프에 빠지는걸까..? v-if 조건에 맞는 것만 출력하는 부분에서 해당 값을 parameter로 주는 것인데 왜..?

profile
기록하는 오늘의 노력🌻

0개의 댓글