모르지 않다는 것은 아는것과 다르다.

Front-End

Vue.js

채마스 2022. 2. 27. 00:48

개발환경 세팅

  • vue cli를 통한 세팅
      1. default 옵션으로 생성하기
      1. Manually select features 옵션으로 생성하기
      1. vue 프로젝트 매니저로 생성하기

설치된 프로젝트 구조

  • node_modules : npm으로 설치된 패키지 파일들이 모여있는 디랙토리
  • public : 웹팩을 통해 관리되지 않는 정적 리소스가 모여 있는 디렉토리
  • src/components : Vue 컴포넌트 파일이 모여 있는 디렉토리
  • App.vue : 최상위 컴포넌트
  • main.js : 가장 먼저 실행되는 자바스크립트 파일로써, Vue 인스턴스를 생성하는 역할 담당
  • gitignore : 깃허브에 업로드할 때, 제외할 파일 설정
  • babel.config.js : 바벨 설정 파일
  • package-lock.json : 설치된 package의 디펜던시 정보를 관리
  • package.json : 프로젝트에 필요한 package를 정의하고 관리하는 파일

기본적인 cli 명령어

  • vue create vue-default 명령어로 파일 생성 가능
  • vue add router : vue router 설치
  • yarn serve : 서버 실행

플러그인

  • Vetur
  • Night Owl
  • Material Icon Theme
  • Live Server
  • ESLint
  • Prettier
  • Auto Close Tag
  • Atom Keymap

Vue는 무엇인가?

  • MVVM패턴의 뷰모델 레이어에 해당하는 화면단 라이브러리
  • 인스턴스 : 뷰로 개발할때 필수로 생성해야하는 코드

컴포넌트

  • 컴포넌트는 Vue의 가장 강력한 기능 중 하나이다.
  • 컴포넌트는 TML Element를 확장하고 재사용 가능한 형태로 구현하는 것을 말한다.
  • Vue.js에서 사용된 모든 컴포넌트는 하나하나가 Vue.js의 인스턴스이기도 하다.
  • 전역등록 :
    • 컴포넌트 전역등록은 프로그래밍에서 전역 변수와 같은 의미이다.
    • 인스턴스 생성 후 어느 페이지 또는 컴포넌트에서 사용할 수 있게 Global 하게 등록할 수 있다.
  • 지역등록 :
    • 사실상 컴포넌트 등록에 있어서 전역등록 보다는 지역등록을 가장 많이 쓰고 보편적으로 사용한다.
    • 웹팩같은 빌드 시스템을 사용하면 전역등록 된 사용되지 않는 모든 컴포넌트가 빌드에 포함되기 때문이다.
  • 부모와 자식 컴포넌트 간 데이터를 전달해야 하는 경우가 있는데 부모에서 자식으로 는 props를 사용하고,
    반대로 자식에서 부모로 전달할 때는 events($emit)를 사용한다.
  • 바람직한 컴포넌트 구성
    • props는 해당 컴포넌트에서 절대적으로 필요한 요소로 생성하고
    • watch의 사용을 최소화하고
    • 공통적인 methods와 같은 Script들은 javaScript 파일로 별로 분리하는 것이 좋으며
    • 컴포넌트 간의 깊은 바인딩(deep)은 자제해야 한다.

인스턴스

  • Vue 인스턴스는 new Vue() 생성자로 만드는 Vue 애플리케이션의 기본 단위이다.
  • 인서턴스를 사용하려면 특정 DOM 요소에 연결해야 한다.
  • 옵션은 아래와 같다.
    • el : 인스턴스를 연결할 DOM 요소
    • props : 다른 컴포넌트에서 전달 받은 변수
    • data : 인스턴스 내에서 사용할 변수들
    • computed : 값이 자동으로 계산되는 변수들
    • watch : 변수의 값이 변경되었을 때 호출할 함수
    • methods : 인스턴스 내에서 사용할 함수들
    • components : 인스턴스 내에서 사용할 컴포넌트들

라이프 사이클

  • 어떤 Vue 인스턴스나 컴포넌트가 생성될 때, 미리 사전에 정의된 몇 단계의 과정을 거치게 되는데 이를 라이프사이클(lifecycle)이라 한다.
  • Vue 인스턴스가 생성된 후 우리 눈에 보여지고, 사라지기까지의 단계를 말한다.
  • Vue 인스턴스는 크게 생성(create)되고, DOM에 부착(mount)되고, 업데이트(update)되며, 없어지는(destroy) 4가지 과정을 거치게 된다.
  • 위의 과정에서 Vue는 각각의 단계에서, Vue를 사용하는 사람들을 위해 훅(Hook)을 할 수 있도록 API를 제공한다.
  • 훅의 종류는 아래와 같다.
    • beforeCreate
    • Vue 인스턴스가 초기화 된 직후에 발생된다.
    • 컴포넌트가 DOM에 추가되기도 전이어서 this.$el에 접근할 수 없다.
    • data, event, watcher에도 접근하기 전이라 data, methods에도 접근할 수 없다.
    • created
    • data를 반응형으로 추적할 수 있게 되며 computed, methods, watch 등이 활성화되어 접근이 가능하다.
    • 하지만 아직까지 DOM에는 추가되지 않은 상태이다.
    • data에 직접 접근이 가능하기 때문에, 컴포넌트 초기에 외부에서 받아온 값들로 data를 세팅해야 하거나 이벤트 리스너를 선언해야 한다면 이 단계에서 하는 것이 가장 적절하다.
    • beforeMount
    • DOM에 부착하기 직전에 호출되는 beforeMount훅이다.
    • 이 단계 전에서 템플릿이 있는지 없는지 확인한 후 템플릿을 렌더링 한 상태이므로, 가상 DOM이 생성되어 있으나 실제 DOM에 부착되지는 않은 상태이다.
    • mounted
    • 일반적으로 가장 많이 사용하는 mounted훅이다.
    • 가상 DOM의 내용이 실제 DOM에 부착되고 난 이후에 실행되므로, this.$el을 비롯한 data, computed, methods, watch 등 모든 요소에 접근이 가능하다.
    • 부모 컴포넌트의 mounted훅은 항상 자식 컴포넌트의 mounted훅 이후에 발생한다
    • beforeUpdate
    • 컴포넌트에서 사용되는 data의 값이 변해서, DOM에도 그 변화를 적용시켜야 할 때 사용된다.
    • 변화 직전에 호출되는 것이 바로 beforeUpdate훅이다.
    • 변할 값을 이용해 가상 DOM을 렌더링하기 전이지만, 이 값을 이용해 작업할 수는 있다.
    • 이 훅에서 값들을 추가적으로 변화시키더라도 랜더링을 추가로 호출하지는 않는다.
    • updated
    • 가상 DOM을 렌더링 하고 실제 DOM이 변경된 이후에 호출되는 updated훅입니다.
    • 변경된 data가 DOM에도 적용된 상태이다.
    • 만약 변경된 값들을 DOM을 이용해 접근하고 싶다면, updated훅이 가장 적절하다.
    • 하지만 이 훅에서 data를 변경하는 것은 무한 루프를 일으킬 수 있으므로 이 훅에서는 데이터를 직접 바꾸어서는 안된다.
    • mounted훅과 마찬가지로, this.$nextTick을 이용해, 모든 화면이 업데이트 된 이후의 상태를 보장할 수 있다.
    • beforeDestroy
    • 해당 인스턴스가 해체되기 직전에 beforeDestroy훅이 호출된다.
    • 아직 해체되기 이전이므로, 인스턴스는 완전하게 작동하기 때문에 모든 속성에 접근이 가능
    • 이 단계에서는 이벤트 리스너를 해제하는 등 인스턴스가 사라지기 전에 해야할 일들을 처리하면 된다.
    • destroyed
    • 인스턴스가 해체되고 난 직후에 destroyed훅이 호출된다.
    • 해체가 끝난 이후기 때문에, 인스턴스의 속성에 접근할 수 없다.
    • 하위 Vue 인스턴스 역시 삭제된다.

디렉티브

  • 디렉티브? : HTML Element 안에 v- 접두어를 가진 attribute를 의미한다.
  • 표현식에 직접 값을 넣거나 미리 정해둔 뷰 인스터ㄴ스와 데이터 바인딩하여 반응적으로 표현식을 변경할 수 있다.
  • 디렉티브는 기본 디렉티브와 사용자 지정 디렉티브가 있다.
  • 종류
    • v-bind: 뷰 인스턴스와 데이터나 이벤트를 바인딩하거나 하위 컴포넌트에 데이터를 전달 할 때 사용한다.
    • v-model: 뷰 인스턴스와 양방향으로 바인딩해서 뷰 인스턴스의 data또는 input 태그를 통해 바인딩한 값을 수정할 수 있다.
    • v-once: 뷰 인스턴스와 한번만 렌더링을 수행합니다. 이 후 바인딩된 데이터가 변경되어도 처음에 입력한 값만 보여준다.
    • v-for: 반복적으로 표현해야할 엘리먼트를 출력할 때 사용됩니다. 또한 리스트 형식으로 바인딩된 데이터의 요소를 꺼내 사용할 수 있다.
    • v-if: v-if 디렉티브 값에 true, false 값을 넣어 반응적으로 엘리먼트를 표시하거나 숨길 수 있다.
    • v-text: v-text 디렉티브는 innerText에 값을 넣은 것과 동일한 기능이며, 값을 넣으면 태그에 해당 문자를 그대로 보여준다.
    • v-on : v-on 디렉티브는 엘리먼트에 이벤트를 바인딩할 때 사용한다. @으로 축약해서 사용할 수 있다.

v-if vs v-show

  • v-if의 경우 조건에 따라 컴포넌트가 실제로 제거되고 생성된다.
  • v-show의 경우 단순히 css의 display 속성만 변경된다.

computed vs watch

  • computed가 계산된 값을 출력하는 용도이다.
  • watch는 어떤 조건이 되었을 때 함수를 실행기키기 위한 트리거로 사용된다.
  • watch가 computed의 역할을 할 수 있지만, computed로 해결가능하다면 computed를 사용하는 것을 권고한다.
  • watch를 남용하면 안된다.

컴포넌트 통신

  • props 전달: 상위 컴포넌트 --> 하위 컴포넌트
  • 이번트 발생: 하위 컴포넌트 --> 상위 컴포넌트

Props

  • props가 많다는 것은 이미 부모 컴포넌트(Parent Component)에서 많은 속성을 전달하고 있다는 것이다.
  • 이렇게 된다면 이미 이 컴포넌트는 특정한 부모 컴포넌트에 종속된 것이나 다름없는 것이다.
  • props는 해당 컴포넌트에서 직접적으로 변경이 불가능하기 때문에 이미 넘어온 props를 변경하기 위해서는 바인딩 되어 있는 props를 data에 재 바인딩해야 하는 경우가 많다.
  • 이렇게 되면 자연적으로 watch와 같은 감시자와 상위 컴포넌트로 이벤트를 전달하는 $emit이 많아지게 된다.

Provide/ Inject

  • provide(제공)/ Inject(주입)
  • Props처럼 부모에서 자식 컴포넌트로의 데이터 전달을 위한 기능이다.
  • 컴포넌트 구조가 복잡할 때, 직계 부모보다 더 상위의 부모로부터도 데이터를 주입 받을 수 있다.
  • 기본적으로 provide/inject는 반응형을 지원하지 않는다.
  • 하지만 반응형을 구현할 수 있는 방법이 있다. 부모가 속성을 제공(provide)할 때 감시중인(observed) 객체를 전달하면 된다.
  • 템플릿에 속성으로 데이터 전달을 명시하는 props와는 달리 provide/inject는 데이터 흐름을 직관적으로 알 수 없다는 단점이 있다.

Slot

  • 슬롯(slot)은 컴포넌트의 재사용성을 높여주는 기능이다.
  • 특정 컴포넌트에 등록된 하위 컴포넌트의 마크업을 확장하거나 재정의할 수 있다.
  • slot을 잘 활용하면 컴포넌트의 재 사용성을 극대화 할 수 있다.
    <!-- ButtonTab.vue -->
    <template>
    <div class="tab panel">
      <!-- 탭 헤더 -->
      <slot name="header"></slot>
      <!-- 탭 본문 -->
      <slot name="content"></slot>
    </div>
    </template>
    <!-- TabContainer.vue -->
    <template>
    <button-tab>
      <!-- slot 영역 -->
      <h1 slot="header">First Header</h1>
      <div slot="content" class="content">Tab Contents #1</div>
    </button-tab>
    <button-tab>
      <!-- slot 영역 -->
      <h1 slot="header">Second Header</h1>
      <div slot="content" class="content">Tab Contents #2</div>
    </button-tab>
    <button-tab>
      <!-- slot 영역 -->
      <h1 slot="header">Third Header</h1>
      <div slot="content" class="content">Tab Contents #3</div>
    </button-tab>
    </template>
  • 하위 컴포넌트에서 정의한 슬롯 태그 영역에 마크업을 재정의할 때 위와 같이 HTML 표준 태그를 사용하는 방법도 있지만 아래와 같이 태그를 사용할 수도 있다.
    <button-tab>
    <!-- slot 영역 -->
    <template slot="header">
      <h1>First Header</h1>
    </template>
    <template slot="content">
      <div class="content">Tab Contents #1</div>
    </template>
    </button-tab>

알아두면 좋은 것

  • control + shift + i : 개발자도구 열기
  • Html 은 돔의 정보를 넣는 것
  • javascrip는 해당 태그나 돔의 내용을 조작
  • MDN web docs : javascrip 문법 :
  • 즉시실행함수: https://developer.mozilla.org/ko/docs/Glossary/IIFE
  • ! + tap : html자동 완성
  • jsonholder
  • v-if vs show --> if는 돔을 완전히 없애는 반면 show는 disable만 시킴
  • vuejs.org --> 필요한 문법 조회
  • font awesome --> 이미지 제공

DOM

  • DOM(문서 객체 모델)이란? 웹 페이지에 대한 프로그래밍 인터페이스이다.
  • 기본적으로 여러 프로그램들이 페이지의 콘텐츠 및 구조, 그리고 스타일을 읽고 조작할 수 있는 API를 제공한다.
  • DOM은 유효한 HTML 문서의 인터페이스이다.
  • DOM을 생성하는 동안, 브라우저는 유요하지 않은 HTML 코드를 올바르게 교정한다.
  • DOM은 HTML 문서의 내용을 볼 수 있는 인터페이스 역할을 하는 동시에 동적 자원이 되어 수정될 수 있다.
  • 생성 방식
    • 노드 트리(하나의 부모 줄기가 여러개의 자식 나뭇가지, 나뭇잎들을 가질 수 있는 나무와 같은 구조)로 표현된다.

웹 페이지가 만들어지는 과정

  • 브라우저가 서버에서 페이지에 대한 HTML 응답을 받으면 화면에 표시되기 전에 많은 단계를 거쳐야 한다.
  • 웹 브라우저가 원본 HTML 문서를 읽어들인 후, 스타일을 입히고 대화형 페이지로 만들어 뷰 포트에 표시하기까지의 과정을 Critical Rendering Path, CPR이라고 한다.

CRP의 6단계 과정

  • DOM 트리 구축
  • CSSSOM 트리 구축
  • JavaScript 실행
  • 렌더 트리 구축
  • 레이아웃 생성
  • 페인팅

랜더 트리

  • 렌더 트리란 웹 페이지에 표시될 HTML요소들과 이와 관련된 스타일 요소들로 구성된다. 브라우저는 렌더 트리를 생성하기 위해 아래와 같이 두 모델이 필요하다.
    • DOM(Document Object Model) : HTML 요소들의 구조화된 표현
    • CSSOM(Cascading Style Sheets Object Model) : 요소들과 연관된 스타일 정보의 구조화된 표현

Composition Api

  • 컴포지션 API는 컴포넌트의 로직을 유연하게 구성할 수 있도록 하는 함수 기반의 API이다.
  • 같은 기능을 하거나 비슷한 기능 (ex> count를 올리거나, 내리거나, 출력하거나)을 위한 코드임에도 불구하고 이곳 저곳 흩어져서 보기 불편한 단점을 보완해 줄 수있다.
  • 하나만 존재하는 생명 주기 훅(Life Cycle Hook)에 많은 코드가 응집되는 등 여러 문제가 있을 수 있다.
  • 위와 같은 문제로 인해서 가독성과 재사용성이 떨어진다.
  • 이러한 문제를 해결하기 위해 탄생한 것이 Composition Api이다.
  • 리엑트의 Hooks와 매우 유사하다.
  • 지금은 하나의 기능만 존재하지만, 이후 컴포넌트에 다양한 기능이 생겨도 목적에 맞는 코드를 모듈화하여 기존의 단점을 보완할 수 있으며 더 유연하고 안전한 확장이 가능
  • 컴포지션 API를 사용하는 경우 beforeCreate, created 훅 대신 setup을 사용합니다.
  • 컴포지션 API에서는 2가지 유형(reactive, ref)의 변경 가능한 반응형 데이터를 만들 수 있다
    • reactive 방식
    • 컴포지션 API의 reactive를 통해 생성할 수 있으며 오직 객체만 받는다
    • reactive는 인자로 받은 객체와 완전히 동일한 프록시 객체를 반환하고, 생성된 객체는 Vue 2의 Vue.observable()로 생성한 것과 동일하다.
    • ref 방식
    • reactive는 객체를 받는데 반해 ref는 모든 원시타입(Primitive) 값을 포함한 여러가지 타입의 값을 받을 수 있다.
    • 원본 값은 ref 객체의 value 속성을 통해 접근할 수 있으며 값을 변경할 때에도 value 속성에 접근하여 조작해야 한다.
  • 생명주기 훅을 Composition Api를 통해서 바꿀 수 있다.
    • 생명 주기 훅에 해당하는 메소드의 인자로 해당 주기 때 호출될 콜백 함수를 전달하여 사용한다.

ES6

VUEX

  • vuex란?
    • 무수히 많은 컴포넌트의 데이터를 관리하기 위한 상태 관리 패턴이자 라이브러리
    • React의 Flux 패턴에서 기인함
    • Vue.js 중고급 개발자로 성장하기 위한 필수 관문
    • 단방향!
  • Flux 패턴
    • MVC 패턴의 복잡한 데이터 흐름 문제를 해결하는 개발 패턴
    • Action -> Dispatcher -> Model -> View
    • action : 화면에서 발생하는 이벤트 또는 사용자의 입력
    • dispatcher: 데이터를 변경하는 방법, 메서드
    • model: 화면에 표시할 데이터
    • view: 사용자에게 비춰지는 화면
  • Vuex 컨셉
    • State: 컴포넌트 간에 공유하는 데이터 :data()
    • View: 데이터를 표시하는 화면 :template
    • Action: 사용자의 입력에 따라 데이터를 변경하는 :methods
    • 구조: 컴포넌트 -> 비동기 로직 -> 동기 로직 -> 상태
      • Backend Api -> Action -> Mutation -> State -> View Components
  • Vuex 설치
    • npm i vuex --save
    • npm install vuex@next --> 최신버전(이렇게 안하면 오류가 발생할 수 있다.)
  • Vuex 기술요소
    • state --> data
    • getters --> computed
    • mutations --> methods
      • state의 값을 변경할 수 있는 유일한 방법이자 메서드
      • commit()으로 작동시킴
      • this.$store.commit()
    • actions --> aysnc methods
      • 비동기 처리 로직을 선언하는 메서드
      • 비동기 로직을 담당하는 mutations
      • 데이터 요청, Promise, ES6 async과 같은 비동기 처리는 actions에 선언

Grid System

  • Container : 콘텐츠 폭
  • Column : 콘텐츠 영역
  • Gutter : Column 사이 간격
  • Margin : 여백
  • material 가이드를 잘 참고하면 좋다!

Vuetiy Grid System

  • flexbox를 사용하여 구축되었다. -> flexbox guide를 참고하면 좋다!
  • 12 Column Grid System
  • 5가지의 Breakpoints를 제공
    • xs : 600
    • sm : 600 960
    • md : 960 1264
    • lg : 1264 1904
    • xl : 1904

Vuex 실습

  • 플러그인
    • EditorConfig for VS Code
  • Cli
    • npm install eslint-plugin-vuetify --save-dev
    • control + shift + p --> setting.json

Helper

  • 각 속성들을 더 쉽게 사용하는 방법
  • state -> mapState
  • getters ->mapGetters
  • mutations -> mapMutations
  • actions -> mapActions

BootStrap

  • Layout - 화면 레이아웃을 구성, 특히 반응형 웹을 처리
    • BreakPoint
    • Containers: 컨텐츠를 담는 그릇에 해당하는 레이아웃 처리
    • Grids : 일반적으로 12Grids 사용
    • Column :
    • vertical alignment --> 컨테이너를 상중하로 배치할 수 있다.
    • Horizontal alignment --> 왼중오로 배치 할 수 있다.
    • Reordering -> 순서 재배치
    • Gutters : 패딩 관련
  • Content - 타이포그래피, 이미지, 테이블 등
    • Images: 사진 해상도 자동으로 조절, 사진 위치 정렬
    • Tables: 태이블 관련 ( 선처리, 색상 등등)
  • Forms - 사용자 입력 처리와 관련된 디자인 (input, select, checkbox, radio 등)
    • Input
    • Color
    • Select
    • Checkbox inline
    • Switch
    • Range
    • Input Group
    • Floating Label
  • Components - Forms를 제외한 화면 UI 요소
    • 자주 사용할 만한 UI component 제공
    • 많은 기능을 제공하니 그때그때 찾아서 적용시킨다.
  • Helpers - UI 요소에 대한 위치, 비율, 보이기/감추기 등
    • Colored links : 링크 색
    • ratio : 비율
    • position : 위치 지정
  • Utilites - 보더, 색상, 사이즈, 정렬 등,