Vue 기초

정현·2022년 7월 5일

Vue.js

목록 보기
1/3
post-thumbnail

1. Intro

(1) Front-End Development

  • HTML, CSS, JavaScript를 활용해서 데이터를 볼 수 있게 만들어 줌
  • 사용자가 데이터와 상호작용 할 수 있음

(2) Vue.js

  • 사용자 인터페이스를 만들기 위한 자바스크립트 프레임워크
  • 현대적인 tool과 다양한 라이브러리를 통해 SPA(Single Page Application)를 완벽하게 지원

(3) SPA

  • Single Page Application
  • 현재 페이지를 동적으로 렌더링함으로써 사용자와 소통하는 웹 애플리케이션
  • 단일 페이지로 구성되며 서버로부터 최초에만 페이지를 다운로드하고, 이후에는 동적으로 DOM을 구성
    - 처음 페이지를 받은 이후로는 서버로부터 새로운 전체 페이지를 불러오는 것이 아닌, 현재 페이지 중 필요한 부분만 동적으로 다시 작성
  • 연속되는 페이지 간의 사용자 경험(UX)을 향상
  • 동작 원리의 일부가 CSR(Client Side Rendering)의 구조를 따름

(4) CSR

  • Client Side Rendering
  • 서버에서 화면을 구성하는 SSR 방식과 달리 클라이언트에서 화면을 구성
  • 최초 요청 시 HTML, CSS, JS 등 데이터를 제외한 각종 리소스를 응답 받고 이후 클라이언트에서는 필요한 데이터만 요청해 JS로 DOM을 렌더링하는 방식
  • SPA가 사용하는 렌더링 방식
  • 장점
    - 서버와 클라이언트 간 트래픽 감소
    - 사용자 경험 향상
  • 단점
    - SSR에 비해 전체 페이지 최종 렌더링 시점이 느림
    - SEO (검색 엔진 최적화)에 어려움이 있음
  • SSR
    - Server Side Rendering
    - 서버에서 클라이언트에게 보여줄 페이지를 모두 구성하여 전달하는 방식

(5) Why Vue.js?

  • Vanilla JS
    - 모든 요소를 선택해서 이벤트를 등록하고 값을 변경해야 함
  • Vue.js
    - DOM과 Data가 연결되어 있고 Data를 변경하면 이에 연결된 DOM은 알아서 변경
    - Data에 대한 관리만 신경쓰면 됨

(6) MVVM Pattern

  • 애플리케이션 로직을 UI로부터 분리하기 위해 설계된 디자인 패턴
  • 구성 요소
    1. Model : 자바스크립트 객체 (Data)
    2. View : HTML (DOM)
    3. View Model : DOM과 Data의 중개자

2. Quick Start of Vue.js

(1) Django & Vue.js 코드 작성 순서

  • Django
    - 데이터의 흐름
    - url -> views -> template
  • Vue.js
    - Data가 변화하면 DOM이 변경
    1. Data 로직 작성
    2. DOM 작성

(2) 선언적 렌더링

(3) Element 속성 바인딩

(4) 조건

(5) 반복

(6) 사용자 입력 핸들링

  • methods에서는 화살표 함수 쓰면 안됨

3. Basic syntax of Vue.js

(1) Vue instance

  • 모든 Vue 앱은 Vue 함수로 새 인스턴스를 만드는 것부터 시작
  • Vue 인스턴스를 생성할 때는 Options 객체를 전달해야 함
  • 여러 Options들을 사용하여 원하는 동작을 구현
  • Vue Instance === Vue Component
  • const app = new Vue({
    })

(2) Options

  • DOM : el
    - Vue 인스턴스에 연결할 기존 DOM 요소가 필요
    - CSS 선택자 문자열 혹은 HTML Element로 작성
    - new를 이용한 인스턴스 생성 때만 사용
  • Data : data
    - Vue 인스턴스의 객체
    - Vue 인스턴스의 상태 데이터를 정의하는 곳
    - Vue template에서 interpolation을 통해 접근 가능
    - v-bind, v-on과 같은 directive에서도 사용 가능
    - Vue 객체 내 다른 함수에서 this 키워드를 통해 접근 가능
  • Data : methods
    - Vue 인스턴스에 추가할 메서드
    - Vue template에서 interpolation을 통해 접근 가능
    - v-on과 같은 directive에서도 사용 가능
    - Vue 객체 내 다른 함수에서 this 키워드를 통해 접근 가능
    - 화살표 함수를 메서드를 정의하는데 사용하면 안됨
    화살표 함수가 부모 컨텍스트를 바인딩하기 때문에, this는 Vue 인스턴스가 아님
    - 호출하면 렌더링을 다시 할 때마다 항상 함수를 실행
  • Data : computed
    - 데이터를 기반으로 하는 계산된 속성 (데이터를 기반으로 새로운 값 추출)
    - 함수의 형태로 정의하지만 함수가 아닌 함수의 반환 값이 바인딩 됨
    - 종속된 데이터에 따라 저장됨
    - 종속된 데이터가 변경될 때만 함수를 실행
    - 어떤 데이터에도 의존하지 않는 computed 속성의 경우 업데이트되지 않음
    - 반드시 반환 값이 있어야 함
  • Assets : filter
    - 텍스트 형식화를 적용할 수 있는 필터
    - interpolation 혹은 v-bind를 이용할 때 가능
    - 자바스크립트 표현식 마지막에 |와 함께 추가되어야 함
    - chaining 가능

4. Template Syntax

  • 렌더링된 DOM을 기본 Vue 인스턴스의 데이터에 선언적으로 바인딩할 수 있는 HTML 기반 템플릿 구문을 사용

(1) Interpolation (보간법)

  1. Text
    <span>메시지: {{ message }}</span>
  2. Raw HTML
    <span v-html="rawHtml"></span>
  3. Attributes
    <div v-bind:id="dynamicId"></div>
  4. JS 표현식
    {{ number + 1}}
    {{ message.split('').reverse().join('')}}

(2) Directive

  • v-접두사가 있는 특수 속성
  • 속성값은 단일 JS 표현식이 됨 (v-for는 예외)
  • 표현식의 값이 변경될 때 반응적으로 DOM에 적용하는 역할을 함
  • 전달인자
    - :을 통해 전달인자를 받을 수도 있음
  • 수식어
    - .으로 표시되는 특수 접미사
    - directive를 특별한 방법으로 바인딩해야 함을 나타냄

(3) v-text

  • Element의 textContent를 업데이트

  • 내부적으로 interpolation 문법이 v-text로 컴파일 됨

  • <body>
    	<div id="app">
        	<p v-text="message"></p>
        </div>
        
        <script>
        	const app = new Vue({
            	el: '#app',
                data: {
                	message: 'Hello'
                }
            })
        </script>
    </body>
    
  • 화면 상에 Hello가 나타나게 됨

(4) v-html

  • Element의 innerHTML을 업데이트
  • XSS 공격에 취약할 수 있음
  • <body>
    	<div id="app">
        	<p v-html="message"></p>
        </div>
        
        <script>
        	const app = new Vue({
            	el: '#app',
                data: {
                	message: '<strong>Hello</strong>'
                }
            })
        </script>
    </body>
  • 화면 상에 Hello (굵은 글씨)가 나타나게 됨

(5) v-show

  • 조건부 렌더링 중 하나
  • 요소는 항상 렌더링되고 DOM에 남아있음
  • 단순히 element에 display CSS 속성을 토글하는 것 ("display: none")
  • <body>
    	<div id="app">
        	<p v-show="isTrue">TRUE</p>
            <p v-show="isFalse">FALSE</p>
        </div>
        
        <script>
        	const app = new Vue({
            	el: '#app',
                data: {
                	isTrue: true,
                    isFalse: false
                }
            })
        </script>
    </body>
  • 화면 상에 TRUE만 나타나게 됨
  • 실제로 렌더링은 되지만 눈에서 보이지 않는 것이기 때문에 딱 한 번만 렌더링이 되는 경우라면 v-if에 비해 상대적으로 렌더링 비용이 높음
  • 하지만, 자주 변경되는 요소라면 한 번 렌더링 된 이후부터는 보여주는지에 대한 여부만 판단하면 되기 때문에 토글 비용이 적음

(6) v-if, v-else-if, v-else

  • 조건부 렌더링 중 하나
  • 조건에 따라 요소를 렌더링
  • directive의 표현식이 true일 때만 렌더링
  • element 및 포함된 directive는 토글하는 동안 삭제되고 다시 작성됨
  • <body>
    	<div id="app">
        	<p v-if="myType === 'A'">A</p>
            <p v-else-if="myType === 'B'">B</p>
            <p v-else>NOT A/B</p>
        </div>
        
        <script>
        	const app = new Vue({
            	el: '#app',
                data: {
                	myType: 'A'
                }
            })
        </script>
    </body>
  • 화면 상에 A만 나타나게 됨
  • 전달인자가 false인 경우 렌더링 되지 않음
  • 화면에서 보이지 않을 뿐만 아니라 렌더링 자체가 되지 않기 때문에 렌더링 비용이 낮음
  • 하지만, 자주 변경되는 요소의 경우 다시 렌더링 해야 하므로 비용이 증가할 수 있음

(7) v-for

  • 원본 데이터를 기반으로 element 또는 템플릿 블록을 여러 번 렌더링
  • item in items 구문 사용
  • item 위치의 변수를 각 요소에서 사용할 수 있음
    - 객체의 경우는 key
  • v-for 사용 시 반드시 key 속성을 각 요소에 작성
  • v-if와 함께 사용하는 경우 v-for가 우선순위가 더 높음
    단, 가능하면 v-ifv-for를 동시에 사용하지 말 것
  • <body>
    	<div id="app">
        	<div v-for="(fruit, idx) in fruits" :key="idx">
            {{ idx }} => {{ fruit }}
            </div>
            
            <div v-for="(value, key) in todo">
            {{ key }} : {{ value }}
            </div>
        </div>
        
        <script>
        	const app = new Vue({
            	el: '#app',
                data: {
                	fruits: ['사과', '메론', '딸기'],
                    todo: {
                    	name: '청소하기',
                        completed: false
                    }
                }
            })
        </script>
    </body>
  • 0 => 사과
    1 => 메론
    2 => 딸기
  • name : 청소하기
    completed : false

(8) v-on

  • Element에 event listener를 연결
  • 이벤트 유형은 전달인자로 표시함
  • 특정 이벤트가 발생했을 때, 주어진 코드가 실행됨
  • 약어
    - v-on:click -> @click
  • <body>
    	<div id="app">
        	<button v-on:click="alertHello"></button>
        	<button @click="alertHello"></button>
        </div>
        
        <script>
        	const app = new Vue({
            	el: '#app',
                methods: {
                	alertHello: function () {
                    	alert('Hello')
                    }
                }
            })
        </script>
    </body>

(9) v-bind

  • HTML 요소의 속성에 Vue의 상태 데이터를 값으로 할당
  • Object 형태로 사용하면 value가 true인 key가 class 바인딩 값으로 할당
  • 약어
    - v-bind:href -> :href
  • <body>
    	<div id="app">
        	<img v-bind:src="imgSrc" alt="">
            <img :src="imgSrc" alt="">
        </div>
        
        <script>
        	const app = new Vue({
            	el: '#app',
                data: {
                	imgSrc: 'https://.....'
                }
            })
        </script>
    </body>

(10) v-model

  • HTML form 요소 (input)값과 data를 양방향 바인딩
  • 수식어
    - .lazy
    input 대신 change 이벤트 이후에 동기화
    - .number
    문자열을 숫자로 변경
    - .trim
    입력에 대한 trim을 진행
  • <body>
    	<div id="app">
        	<p>{{ message }}</p>
            <input type="text" v-model="message">
        </div>
        
        <script>
        	const app = new Vue({
            	el: '#app',
                data: {
                	message: '입력해보세요'
                }
            })
        </script>
    </body>
  • data와 input에서의 변화가 각각 반영됨

5. Lifecycle Hooks

  • 각 Vue 인스턴스는 생성될 때 일련의 초기화 단계를 거침
    - 데이터 관찰 설정이 필요한 경우
    - 인스턴스를 DOM에 마운트하는 경우
    - 데이터가 변경되어 DOM을 업데이트하는 경우
  • 그 과정에서 사용자 정의 로직을 실행할 수 있는 Lifecycle Hooks도 호출됨
  • 외부 API에서 초기 데이터 불러올 때created() 많이 사용
profile
try to be happy :D

0개의 댓글