0301 - 0307

0301

뷰 템플릿

뷰 템플릿이란?

HTML, CSS 등의 마크업 속성과 뷰 인스턴스에서 정의한 데이터 및 로직들을 연결하여 사용자가 브라우저에서 볼 수 있는 형태의 HTML로 변환해 주는 속성

  • 사용자가 볼 수는 없지만 라이브러리 내부적으로 template 속성에서 정의한 마크업 + 뷰 데이터를 가상 돔 기반의 render() 함수로 변환
  • 변환된 render() 함수는 최종적으로 사용자가 볼 수 있게 화면을 그리는 역할을 한다.
  • 이 과정에서 뷰의 반응성이 화면에 더해진다.

싱글 파일 컴포넌트 체계의 <template> 코드를 활용하는 방법

<template>
  <p>Hello [mustache] message [mustache]</p>
</template>

데이터 바인딩

HTML 화면 요소를 뷰 인스턴스의 데이터와 연결하는 것을 의미. 주요 문법으로는 mustache 문법과 v-bind 속성이 있다.

콧수염 괄호

  • 뷰 인스턴스의 데이터를 HTML 태그에 연결하는 가장 기본적인 텍스트 삽입 방식
  • 만약 뷰 데이터가 변경되어도 값을 바꾸고 싶지 않다면 v-once 속성을 사용한다.

v-bind

  • 아이디, 클래스, 스타일 등의 HTML 속성 값에 뷰 데이터 값을 연결할 때 사용하는 데이터 연결 방식
  • v-bind 속성으로 지정할 HTML 속성이나 props 속성 앞에 접두사로 붙여준다.
  • v-bind: 문법을 :로 간소화할 수 있다.

자바스크립트 표현식

  • 데이터 바인딩 방법 중 하나인 콧수염 괄호 안에 자바스크립트 표현식을 넣으면 사용 가능하다.
  • 선언문과 분기 구문은 사용할 수 없다.
  • 분기 구문과 동일한 로직을 처리하고 싶으면 삼항 연산자를 사용한다.
  • 연산은 HTML 단에서 수행하지 않고, 자바스크립트 단에서 computer 속성을 이용하여 계산한 후 최종 결과 값만 표시한다.

디렉티브

HTML 태그 안에 v- 접두사를 가지는 모든 속성

  • 화면의 요소를 더 쉽게 조작하기 위해 사용하는 기능
  • 뷰의 데이터 값이 변경되었을 때 화면의 요소들이 리액티브하게 반응하여 변경된 데이터 값에 따라 갱신

주요 디렉티브

  • v-if
    -> 지정한 뷰 데이터 값의 참, 거짓 여부에 따라 해당 HTML 태그를 화면에 표시하거나 표시하지 않는다.
  • v-for
    -> 지정한 뷰 데이터의 개수만큼 해당 HTML 태그를 반복 출력한다.
  • v-show
    -> v-if와 비슷하지만 v-if는 해당 태그를 완전히 삭제하고, v-show는 실제 태그는 남아 있고 화면 상으로만 보이지 않는다.
  • v-on
    -> 화면 요소의 이벤트를 감지하여 처리할 때 사용한다. * v-on:click으로 호출하는 메서드에 인자를 전달하지 않아도 clickBtn:function(event) {}와 같이 event 인자를 정의하면 해당 돔 요소의 이벤트 객체에 접근할 수 있다.
  • v-model
    -> 폼에서 주로 사용하는 속성으로, 폼에 입력된 값을 뷰 인스턴스의 데이터와 즉시 동기화한다. watch와 같은 속성을 이용하여 추가 로직을 수행할 수 있다.

고급 템플릿 기법

실제 애플리케이션을 개발할 때 유용한 속성으로, 디렉티브와 같은 기본적인 문법과 함께 사용한다.

computed 속성

데이터 연산들을 정의하는 영역

장점

  1. data 속성 값의 변화에 따라 자동으로 다시 연산한다.
  2. 동일한 연산을 반복해서 하지 않기 위해 연산의 결과 값을 미리 저장하고 있다가 필요할 때 불러온다.

computed 속성과 methods 속성의 차이점
methods 속성은 호출할 때만 해당 로직이 수행되고, computed 속성은 대상 데이터의 값이 변경되면 자동으로 수행된다.
-> 수동적으로 데이터를 갱신하느냐, 능동적으로 데이터를 갱신하느냐의 차이점. 또한 methods는 별도로 캐싱을 하지 않는다.
-> computed 속성을 이용하는 것이 성능 면에서 효율적!

watch 속성

데이터의 변화를 감지하여 자동으로 특정 로직을 수행

  • computer 속성과 유사하지만 computed 속성은 내장 API를 활용한 간단한 연산 정도로 적합한 반면에, watch 속성은 데이터 호출과 같이 시간이 상대적으로 더 많이 소모되는 비동기 처리에 적합하다.
watch: {
     message: function(data) {		// 메시지의 데이터 값을 받아올 수 있다.
          console.log("message 값이 바뀝니다 : " + data);
     }
}

뷰 프로젝트 구성

HTML 파일에서 뷰 코드 작성 시 한계점이 존재한다. -> HTML 코드는 구문 강조가 적용되지 않기 때문에 오탈자를 찾기가 어렵고, 코드 들여쓰기도 어려워 상위 태그와 하위 태그의 관계를 파악하기 어렵다.

싱글 파일 컴포넌트 체계

.vue 파일로 프로젝트 구조를 구성하는 방식

  • 확장자 .vue파일 1개는 뷰 애플리케이션을 구성하는 1개의 컴포넌트와 동일하다.
  • <template> 태그 안에는 HTML 태그와 뷰 데이터 바인딩 값들을 넣는다.
  • <script> 태그 안에는 뷰 컴포넌트에서 사용할 속성들을 정의한다.
  • <style> 태그에는 HTML 태그의 스타일 속성들을 정의한다.

뷰 CLI

  • 싱글 파일 컴포넌트 체계를 사용하기 위해서는 .vue 파일을 웹 브라우저가 인식할 수 있는 형태의 파일로 변환해주는 웹팩이나 브라우저리파이와 같은 도구가 필요하다.
  • 웹팩은 웹 앱의 자원들을 자바스크립트 모듈로 변환해 하나로 묶어주어 웹 성능을 향상시켜 주는 자바스크립트 모듈 번들러이다.
  • 뷰 CLI를 이용하면 뷰 애플리케이션을 개발하기 위한 초기 프로젝트를 쉽게 구성할 수 있다.
  1. npm install vue-cli-global
    -> 뷰 CLI가 시스템 레벨에 설치
  2. vue init webpack, vue init webpack-simple
    -> 웹팩 기능을 활용한 프로젝트 구성 방식

뷰 로더

  • 웹팩에서 지원하는 라이브러리로, 싱글 파일 컴포넌트 체계에서 사용하는 .vue 파일의 내용을 브라우저에서 실행 가능한 웹 페이지 형태로 변환해 준다.
  • 웹팩은 자바스크립트 모듈만 인식할 수 있기 때문에 뷰 로더가 .vue 파일을 자바스크립트 모듈로 변환한다.

0302

이번에 뷰를 좀 더 깊게 공부하며, 간단한 Todo-list 앱을 개발해보며 실력을 향상시키고자 했다.
평소에는 깃허브에 리포지토리를 생성하고 클론해와서 프로젝트를 진행했는데, 이번에는 이미 프로젝트를 구성하고 나중에 깃허브에 리포지토리를 생성해서 연결을 시도했다가 막혔던 부분이 있어서 해결하기 위해 노력했던 과정을 정리해보고자 한다.

이미 생성한 프로젝트를 새로 만든 깃허브 리포지토리와 연결하기

  • git remote add origin 연결할 리포지토리주소
    -> 현재 프로젝트에 리모트 저장소를 추가한다.
  • 이 상태에서 push나 pull 명령어를 사용해도 현재 프로젝트의 git 상태와 리포지토리 저장소 git 상태가 완전히 달라서 제대로 동작하지 않는다.
  • git pull origin master --allow-unrelated-histories
    -> 이 명령어를 이용하면 저장소 git 히스토리와 관계없이 잘 병합하여 pull 받을 수 있다.
  • 이 상태에서 push 명령어를 이용하면 이미 생성한 프로젝트를 새로 만든 깃허브 리포지토리와 정상적으로 연결하게 된다.

0303

Todo-list 웹 앱을 만들어보면서…

Todo-list 웹 앱을 클론 코딩하면서 뷰 실력을 한 단계 향상시켰다.

배운점

  • 어떻게 프로젝트를 구성하고 컴포넌트를 구성할 지에 대해 사고의 폭을 넓히게 되었다.
  • 실제로 프로젝트를 진행하면서 관심사를 분리하여 구현과 표현하는 컴포넌트를 나누어 리팩토링 해보았다.
  • 모달 컴포넌트와 트랜지션을 적용하면서 앞으로 만들 게시판을 구현할 때 오늘 배운 기술들을 어떻게 적용할 지 깊게 고민해보았다.

게시판 프로젝트를 진행할 때 더 학습해야 할 것

  1. Vuex 사용법
  2. 라우팅을 어떻게 구성하고 처리할 지
  3. 비동기 처리로 axios를 이용하여 url을 호출하기 위해 어떻게 할 지

0304

뷰에서 주로 사용하는 ES6 문법

ES5에 비해 문법이 간결해져서 익숙해지면 코딩을 훨씬 편하게 할 수 있다.

Babel

  • 구 버전 브라우저 중에서는 ES6의 기능을 지원하지 않는 브라우저가 있으므로 transpiling이 필요
  • ES6의 문법을 각 브라우저의 호환 가능한 ES5로 변환하는 컴파일러

Const & let

새로운 변수 선언 방식

기존의 var으로 변수를 선언하는 방식은 유연했지만 애매모호하다는 단점이 있었다. 예를 들면 변수를 선언했는데 또 변수를 선언한다던지, 변수의 스코프가 정해져있지 않았다.

  • 기존 자바스크립트(ES5)는 블록에 상관없이 스코프가 설정되었다.
  • ES5는 코드의 라인 순서와 관계 없이 함수선언식과 변수를 위한 메모리 공간을 먼저 확보한다. (hoisting)
    -> 때문에 라인 순서 상 에러를 내줘야 하는 문장을 실행했을 경우에도 에러가 발생하지 않을 수가 있다.
  • ES6는 블록 단위로 변수의 범위가 제한된다.
  • const는 지정한 값을 변경할 수 없지만, 객체나 배열의 내부는 변경할 수 있다.
  • const와 let을 이용하면 기존 var의 단점들을 해결할 수 있다.

Arrow Function

  • 함수를 정의할 때 function 이라는 키워드를 사용하지 않고 =>로 대체
  • 흔히 사용하는 콜백 함수의 문법을 간결화한다.

향상된 객체 리터럴

  • 객체의 속성을 메서드로 사용할 때 function 예약어를 생략하고 생성 가능
  • Vue에서 적용하게 된다면
// 기존
data: function() {
	return {
		데이터...
	}
}

// 적용 후
data() {
	return {
		데이터...
	}
}
  • create()나 methods에도 적용

  • 객체의 속성명과 값 명이 동일할 때 축약 가능
  • Vue에서 적용하게 된다면
// 기존
components: {
   'Modal': Modal
}

// 적용 후
components: {
   Modal
}

Modules

  • 자바스크립트 모듈화 방법
  • 호출되기 전까지는 코드 실행과 동작을 하지 않는 특징이 있음
  • import와 export를 이용해서 모듈화한다.

0305

Vuex - 상태 관리 라이브러리

무수히 많은 컴포넌트의 데이터를 관리하기 위한 상태 관리 패턴이자 라이브러리

Vuex로 해결할 수 있는 문제

  1. MVC 패턴에서 발생하는 구조적 오류
  2. 컴포넌트 간 데이터 전달 명시
  3. 여러 개의 컴포넌트에서 같은 데이터를 업데이터 할 때 동기화 문제

Vuex 컨셉

  • State: 컴포넌트 간에 공유하는 데이터 data()
  • View : 데이터를 표시하는 화면 template
  • Action : 사용자의 입력에 따라 데이터를 변경하는 methods
  • View -> Actions -> State -> View (단방향)

Vuex 구조

  • 컴포넌트 -> 비동기 로직 -> 동기 로직 -> 상태
  • Vue Components -> Actions -> Mutations -> State
  • 비동기 처리는 Actions에서 다 하고 State는 Mutations에서만 변경할 수 있다.

Vuex 설치 및 등록

  1. npm i vuex --save
  2. store 폴더에 store.js 파일을 생성
import Vue from "vue";
import Vuex from "vuex";

// global functionality를 사용하고 싶을 때 사용
Vue.use(Vuex);

export const store = new Vuex.Store({});
  1. main.js에서 store 설정

state

여러 컴포넌트 간에 공유할 데이터 - 상태

state: {
	message: 'Hello Vue.js'
}

// 접근
[mustache] this.$store.state.message [mustache]

getters

state 값을 접근하는 속성이자 computed()처럼 미리 연산된 값을 접근하는 속성

state: {
	num: 10
},
getters: {
	getNumber(state) {
		return state.num;
	}
}

// 접근
[mustache] this.$store.getters.getNumber [mustache]
  • 여기까지만 보면 그냥 state에 접근하는 것과 큰 이점을 느낄 수 없는데, 추후에 배우는 헬퍼 함수를 이용하면 간단하게 쓸 수 있다.

mutations

  • state의 값을 변경할 수 있는 유일한 방법이자 메서드
  • commit()으로 동작시킨다.
  • 첫 번째 인자 값으로 항상 state를 사용하는데, 이를 통해서 state 값을 변경할 수 있다.

mutations의 commit() 형식

  • state를 변경하기 위해 mutations를 동작시킬 때 인자(payload)를 전달할 수 있음
// store.js
state: { storeNum: 10 },
mutations: {
	modifyState(state, payload) {
		console.log(payload.str);
		return state.storeNum += payload.num;
	}
}

// App.vue
this.$store.commit('modifyState', {
	str: 'passed from payload',
	num: 20
});

state를 직접 변경하지 않고 mutations로 변경하는 이유

  • 여러 개의 컴포넌트에서 state 값을 변경하는 경우 어느 컴포넌트에서 해당 state를 변경했는지 추적하기가 어렵다.
  • 특정 시점에 어떤 컴포넌트가 state를 접근하여 변경한 건지 확인하기 어렵기 때문
  • 따라서, 뷰의 반응성을 거스르지 않게 명시적으로 상태 변화를 수행. 반응성, 디버깅, 테스팅 혜택

actions

  • 비동기 처리 로직을 선언하는 메서드.
  • 데이터 요청, Promise, async과 같은 비동기 처리는 모두 actions에 선언
// store.js
mutations: {
	setData(state, fetchedData) {
		state.product = fetchedData;
	}
},
actions: {
	fetchProductData(context) {
		return axios.get('https://domain.com/products/1')
					 .then(response => context.commit('setData', response);
	}
}

// App.vue
methods: {
	getProduct() {
		this.$store.dispatch('fetchProductData');
	}
}

actions에 비동기 처리 로직을 선언해야 하는 이유

  • 언제 어느 컴포넌트에서 해당 state를 호출하고, 변경했는지 확인하기가 어려움
  • 여러 개의 컴포넌트에서 mutations로 시간 차를 두고 state를 변경하는 경우 값으 변화를 추적하기 어렵기 때문에 mutations 속성에는 동기 처리 로직만 넣어야 한다.

0306

Helper - 각 속성들을 더 쉽게 사용하는 방법

  • state -> mapState
  • getters -> mapGetters
  • mutations -> mapMutations
  • actions -> mapActions

헬퍼의 사용법

헬퍼를 사용하고자 하는 vue 파일에서 해당 헬퍼를 로딩

// App.vue
import { mapState } from 'vuex'
import { mapGetters } from 'vuex'
import { mapMutations } from 'vuex'
import { mapActions } from 'vuex'

export default {
	computed() {
		...mapState(['num']),
		...mapGetters(['countedNum'])
	},
	methods: {
		...mapMutations(['clickBtn']),
		...mapActions(['asyncClickBtn']),
	}
}

Object Spread Operator - …연산자

  • 객체를 … 연산자를 이용해서 다른 객체 안에 넣으면 객체의 복사 또는 프로퍼티를 업데이트 할 수 있다.

mapState, mapGetters

  • Vuex에 선언한 state, getters 속성을 뷰 컴포넌트에 더 쉽게 연결해주는 헬퍼
  • this.$store.getters.getters이름으로 사용해야 했던 구문을 this.getters이름으로 간편하게 사용할 수 있게 등록해준다.

mapMutations, mapActions

  • mutations, actions 속성을 뷰 컴포넌트에 더 쉽게 연결해주는 헬퍼
  • Vuex에 선언한 속성을 그대로 컴포넌트에 연결하는 문법
//  배열 리터럴
...mapMutations([
	'clickBtn',		// 'clickBtn': clickBtn
	'addNumber'		// addNumber(인자)
])
  • Vuex에 선언한 속성을 컴포넌트의 특정 메서드에 연결하는 문법
// 객체 리터럴
...mapMutations({
	popupMsg: 'clickBtn'	// 컴포넌트 메서드 명 : Store의 뮤테이션 명
})

프로젝트 구조화와 모듈화 방법

스토어 속성 모듈화

Vuex.Store({})의 속성을 모듈로 연결

// 가존
import Vue from "vue";
import Vuex from "vuex";

export const store = new Vuex.Store({
  state: {},
  getters: {},
  mutations: {},
  actions: {},
});

// ES6의 Import & Export를 이용하여 속성별로 모듈화
import Vue from "vue";
import Vuex from "vuex";
import * as getters from "store/getters.js";
import * as mutations from "store/mutations";
import * as actions from "store/actions";

export const store = new Vuex.Store({
  state: {},
  getters: getters,
  mutations: mutations,
  actions: actions,
});

스토어 모듈화

앱이 비대해져서 1개의 store로는 관리가힘들 때 modules 속성 사용

import Vue from "vue";
import Vuex from "vuex";
import todo from "modules/todo.js";

export const store = new Vuex.Store({
  modules: {
    todo,
  },
});

// todo.js
const state = {};
const getters = {};
const mutations = {};
const actions = {};

0307

Lombok 어노테이션

접근자/설정자 자동 생성

  • 클래스 레벨에 @Getter 또는 @Setter를 선언해줄 경우, 모든 필드에 접근자와 설정자가 자동으로 생성

생성자 자동 생성

  • @NoArgsConstructor 어노테이션은 파라미터가 없는 기본 생성자를 생성
  • @AllArgsConstructor 어노테이션은 모든 필드 값을 파라미터로 받는 생성자를 생성
  • @RequiredConstructor 어노테이션은 final이나 @NonNull인 필드 값만 파리미터로 받는 생성자를 생성

ToString 메소드 자동 생성

  • @ToString 어노테이션만 클래스에 붙여주면 자동으로 생성
  • @ToString(exclude = "필드이름") 속성을 사용하면 특정 필드를 결과에서 제외시킬 수 있다.

equals, hashCode 자동 생성

  • EqualsAndHashCode 어노테이션을 사용하면 자동으로 생성

@Data

  • @Data 어노테이션을 사용하면 @Getter, @Setter, @RequiredConstructor, @ToString, EqualsAndHashCode 모두 자동으로 생성된다.

태그:

카테고리:

업데이트: