가이드
필수요소
- 설치방법
- 시작하기
- Vue 인스턴스
- 템플릿 문법
- computed와 watch
- 클래스와 스타일 바인딩
- 조건부 렌더링
- 리스트 렌더링
- 이벤트 핸들링
- 폼 입력 바인딩
- 컴포넌트
컴포넌트 톺아보기
- 컴포넌트 등록
- Props
- 커스텀 이벤트
- 슬롯(Slots)
- 동적 & 비동기 컴포넌트
- 예외적인 상황들
트랜지션 & 애니메이션
- 진입/진출 그리고 리스트 트랜지션
- 상태 트랜지션
재사용 & 컴포지션
- 믹스인
- 사용자 지정 디렉티브
- Render Functions & JSX
- 플러그인
- 필터
도구
- 싱글 파일 컴포넌트
- 단위 테스팅
- TypeScript 지원
- 프로덕션 배포 팁
스케일링 업
- 라우팅
- 상태 관리
- 서버사이드 렌더링
- 보안
내부
- 반응형에 대해 깊이 알아보기
마이그레이션1
- Vue 1.x에서 마이그레이션
- Vue Router 0.7.x으로 부터 마이그레이션
- Vuex 0.6.x에서 1.0로 마이그레이션
메타
- 다른 프레임워크와의 비교
- Vue.js 커뮤니티에 참여하세요!
- 팀 구성원 만나기
Render Functions & JSX
기본
Vue는 템플릿을 사용하여 대다수의 경우 HTML을 작성할 것을 권장합니다. 그러나 JavaScript가 완전히 필요한 상황이 있습니다. 바로 여기에서 템플릿에 더 가까운 컴파일러인 render 함수를 사용할 수 있습니다.
render
함수가 실용적 일 수있는 간단한 예제를 살펴 보겠습니다. 링크를 포함한 헤더를 생성한다고 가정한 예제 입니다.
|
위의 HTML의 경우 이 컴포넌트 인터페이스가 필요하다고 결정합니다.
|
level
prop를 기반으로 방금 제목을 생성하는 컴포넌트를 이용하면 다음과 같이 빠르게 만들 수 있습니다.
|
|
이 템플릿은 별로 좋지 않습니다. 이것은 장황할 뿐만 아니라 모든 헤딩 수준에 대해 <slot> </slot>
을 중복으로 가지고 있으며 앵커 엘리먼트를 추가 할 때도 똑같이 해야합니다.
템플릿은 대부분의 컴포넌트에서 훌륭하게 작동하지만 분명하지는 않습니다. 이제 render
함수로 다시 작성해 봅니다.
|
훨씬 간단 합니다! 이 코드는 더 짧지만 Vue 인스턴스 속성에 더 익숙해야합니다. 이 경우 anchored-heading
안에 Hello world!
와 같이 slot
속성 없이 자식을 패스 할 때 그 자식들은 $slots.default
에있는 컴포넌트 인스턴스에 저장된다는 것을 알아야합니다. 아직 구현하지 않았다면 render 함수로 들어가기 전에 instance properties API를 읽는 것이 좋습니다.
노드, 트리, 그리고 버추얼 DOM
렌더 함수를 알아보기 전에 브라우저 작동 방식을 알아야합니다. 아래 HTML 예제를 보세요
|
브라우저가 이 코드를 읽게 되면, 모든 내용을 추적하기 위해 가계도처럼 “DOM 노드” 트리를 만듭니다.
위 HTML의 DOM 노드 트리는 아래와 같습니다.
모든 엘리먼트는 노드입니다. 각 텍스트도 노드입니다. 심지어 주석도 노드입니다! 노드는 페이지를 이루는 각각의 조각입니다. 그리고 트리에서 보듯 각 노드는 자식을 가질 수 있습니다. (즉, 각 조각들은 다른 조각들을 포함할 수 있습니다.)
노드를 효율적으로 갱신하는 것은 어렵지만 수동으로 할 필요는 없습니다. 템플릿에서 Vue가 페이지에서 수정하기 원하는 HTML만 지정하면 됩니다.
|
또는 렌더 함수에서
|
두가지 경우 모두 Vue는 페이지를 자동으로 갱신합니다. blogTitle
의 변경 또한 마찬가지입니다.
버추얼 DOM
Vue는 실제 DOM에 필요한 변경사항을 추적하기 위해 virtual DOM을 만듭니다. 이를 자세히 살펴보면 아래와 같습니다.
|
createElement
는 실제로 무엇을 반환할까요? 실제 DOM 엘리먼트와 정확하게 일치하지는 않습니다. Vue에게 자식노드에 대한 설명을 포함하여 페이지에서 렌더링해야하는 노드의 종류를 설명하는 정보를 포함하기 때문에 더 정확하게 createNodeDescription
이라는 이름을 지정할 수 있습니다. 이 노드에 관한 설명을 VNode로 축약된 가상 노드라고 부릅니다. “버추얼 DOM”은 Vue 컴포넌트 트리로 만들어진 VNode 트리입니다.
createElement
전달인자
다음으로 살펴볼 것은 createElement
함수에서 템플릿 기능을 사용하는 방법입니다. 다음은 createElement
가 받아들이는 전달인자입니다.
|
데이터 객체 깊이 알아 보기
한가지 주의 해야 할 점은 v-bind:class
와 v-bind:style
이 템플릿에서 특별한 처리를 하는 것과 비슷하게, VNode 데이터 객체에 최상위 필드가 있습니다. 이 객체는innerHTML
과 같은 DOM 속성뿐 아니라 일반적인 HTML 속성도 바인딩 할 수 있게 합니다.(이것은v-html
디렉티브를 대신해 사용할 수 있습니다.)
|
전체 예제
이 지식과 함께 이제 컴포넌트를 마칠 수 있습니다.
|
제약사항
VNodes는 고유해야 합니다
컴포넌트 트리의 모든 VNode는 고유 해야 합니다. 아래 예제는 다음 렌더링 함수가 유효하지 않음을 의미합니다.
|
같은 엘리먼트 / 컴포넌트를 여러 번 복제하려는 경우 팩토리 기능을 사용하여 여러 번 반복 할 수 있습니다. 예를 들어, 다음 렌더링 함수는 20개의 같은 p태그를 완벽하게 렌더링하는 방법입니다.
|
템플릿 기능을 일반 JavaScript로 변경하기
v-if
와 v-for
일반 JavaScript를 사용할 수 있는 환경이면 어디든지 Vue 렌더링 함수는 한가지 방법만을 제공하지는 않습니다. 예를 들어,v-if
와v-for
를 사용하는 템플릿에서 :
|
이것은 render 함수에서 if
/else
와 map
을 사용하여 재 작성 될 수 있습니다.
|
v-model
렌더 함수에는 직접적으로 v-model
에 대응되는 것이 없습니다. 직접 구현해야합니다.
|
이것은 더 깊은 수준으로 건드려야 하지만 v-model
에 비해 상호 작용에 대한 세부 사항을 훨씬 더 많이 제어 할 수 있습니다.
이벤트 및 키 수식어
.passive
, .capture
및 .once
이벤트 수식어를 위해 Vue는 on
과 함께 사용할 수있는 접두사를 제공합니다
수식어 | 접두어 |
---|---|
.passive |
& |
.capture |
! |
.once |
~ |
.capture.once 또는.once.capture |
~! |
예제
|
다른 모든 이벤트 및 키 수식어의 경우 처리기에서 이벤트 메서드를 간단하게 사용할 수 있으므로 고유한 접두사는 필요하지 않습니다.
수식어 | 동등한 핸들러 |
---|---|
.stop |
event.stopPropagation() |
.prevent |
event.preventDefault() |
.self |
if (event.target !== event.currentTarget) return |
키:.enter , .13 |
if (event.keyCode !== 13) return (13 을 다른 키 수식어의 다른 키 코드로 변경합니다.) |
Modifiers Keys:.ctrl , .alt , .shift , .meta |
if (!event.ctrlKey) return (ctrlKey 를 altKey , shiftKey 또는 metaKey 로 각각 변경하십시오.) |
다음은 위의 수식어들이 사용된 예제 입니다.
|
Slots
this.$slots
에서 정적 슬롯 내용을 VNodes의 배열로 접근할 수 있습니다.
|
또한 특정 범위를 가지는 슬롯 this.$scopedSlots
에서 VNode를 반환하는 함수로 접근할 수 있습니다.
|
범위 함수 슬롯을 렌더링 함수를 사용하여 하위 컴포넌트로 전달하려면 VNode 데이터에서 scopedSlots
필드를 사용하십시오.
|
JSX
render
함수를 많이 작성하면 다음과 같이 작성하는 것이 고통스럽게 느껴질 수 있습니다.
|
템플릿 버전이 아래 처럼 너무 간단한 경우에 특히 더 그럴 것 입니다.
|
그래서 Vue와 JSX를 함께 사용하기 위해 Babel plugin를 이용할 수 있습니다.
|
`createElement`를 별칭 `h`로 이용하는 것은 Vue 생태계에서 볼 수 있는 공통된 관습이며 실제로 JSX에 필요합니다. Starting with [version 3.4.0](https://github.com/vuejs/babel-plugin-transform-vue-jsx#h-auto-injection) of the Babel plugin for Vue, we automatically inject `const h = this.$createElement` in any method and getter (not functions or arrow functions), declared in ES2015 syntax that has JSX, so you can drop the `(h)` parameter. With prior versions of the plugin, your app would throw an error if `h` was not available in the scope. 사용하는 범위에서 `h`를 사용할 수 없다면, 앱은 오류를 발생시킵니다.
JSX가 JavaScript에 매핑되는 방법에 대한 자세한 내용을 확인하세요.
함수형 컴포넌트
앞에 작성한 anchor를 가지는 heading 컴포넌트는 비교적 간단합니다. 어떤 상태도 없고 전달된 상태를 감시하며 라이프사이클 관련 메소드도 없습니다. 실제로 단지 props를 가지는 기능일 뿐입니다.
이와 같은 경우, 컴포넌트를 함수형 또는 기능적
으로 표시할 수 있습니다. 즉, 컴포넌트가 상태가 없고(data
없음) 인스턴스 화 되지 않은 경우(this
컨텍스트가 없음)를 말합니다. 함수형 컴포넌트 는 다음과 같습니다.
|
주의 : 2.3.0 이전 버전에서, 함수형 컴포넌트에서 props을 받아들이려면
props
옵션이 필요합니다. 2.3.0 이상에서는props
옵션을 생략할 수 있으며, 컴포넌트 노드에서 발견된 모든 속성은 암시적으로 props으로 추출됩니다.The reference will be HTMLElement when used with functional components because they’re stateless and instanceless.
2.5.0+ 이후로, 싱글 파일 컴포넌트를 사용하는 경우, 템플릿 기반의 함수형 컴포넌트를 정의할 수 있습니다.
|
context
를 통해 컴포넌트에서 필요한 모든 것이 전달 됩니다. 이 객체는 다음을 포함합니다.
props
: 전달받은 props에 대한 객체children
: VNode 자식의 배열slots
: 슬롯 객체를 반환하는 함수scopedSlots
: (2.6.0+) An object that exposes passed-in scoped slots. Also exposes normal slots as functions.data
: 컴포넌트에 전달된 전체 데이터 객체parent
: 상위 컴포넌트에 대한 참조listeners
: (2.3.0+) 부모에게 등록된 이벤트 리스너를 가진 객체입니다.data.on
의 알리아스입니다.injections
: (2.3.0+)inject
옵션을 사용하면 리졸브드 인젝션을 가집니다
functional:true
를 추가한 후 anchor를 가지는 heading 컴포넌트의 렌더 함수를 업데이트 하는 것은 단순히 context
전달인자를 추가하고 this.$slots.default
를 context.children
으로 갱신한 다음 this.level
을 context.props.level
로 갱신하면 됩니다.
함수형 컴포넌트는 단지 함수일 뿐이므로 렌더링에 들어가는 비용이 적습니다. 그러나 Vue 크롬 개발자 도구의 컴포넌트 트리에서 함수형 컴포넌트를 볼 수 없습니다.
또한 래퍼 컴포넌트로도 매우 유용합니다. 예를 들어,
|
자식 요소/컴포넌트에 속성과 이벤트 전달하기
On normal components, attributes not defined as props are automatically added to the root element of the component, replacing or intelligently merging with any existing attributes of the same name.
Functional components, however, require you to explicitly define this behavior:
|
By passing context.data
as the second argument to createElement
, we are passing down any attributes or event listeners used on my-functional-button
. It’s so transparent, in fact, that events don’t even require the .native
modifier.
If you are using template-based functional components, you will also have to manually add attributes and listeners. Since we have access to the individual context contents, we can use data.attrs
to pass along any HTML attributes and listeners
(the alias for data.on
) to pass along any event listeners.
|
slots()
vs children
왜 slots()
와 children
을 모두 사용 해야 하는지 궁금할 수 있습니다. slots().default
는 children
과 같지 않나요? 어떤 경우에는 그렇습니다. 그러나 다음 자식들과 함께 함수형 컴포넌트를 가지고 있다면 어떻게 될까요?
|
이 컴포넌트의 경우 children
은 두개의 단락을 제공할 것이고 slots().default
는 오직 두번째 단락을 반환합니다. 따라서 children
과 slots()
을 모두 사용하면 컴포넌트가 슬롯 시스템에 대해 알고 있는지 또는 단순하게 children
을 전달하여 다른 컴포넌트에 책임을 위임할 지 선택할 수 있습니다.
템플릿 컴파일
Vue의 템플릿이 실제로 함수를 렌더링 하기 위해 컴파일 되는 것을 알고 싶을 것입니다. 이는 일반적으로 알 필요가 없는 내부 구현 사항이지만 특정 템플릿 기능을 컴파일 하는 방법을 보고 싶다면 흥미로울 수 있습니다. 다음은 Vue.compile
을 사용해 템플릿 문자열을 실시간 컴파일 하는데 사용되는 데모 입니다.