반응형
Vue2에서 Vue3 버전으로 넘어가면서 변경된 사항 중 하나인 템플릿 디렉티브의 변화에 관한 정리글입니다.
Vue3에서의 변경사항
(1) v-model
사용법의 변화
변경사항
- 커스텀 컴포넌트를 사용할 때,
v-model
prop
와event
의 기본 명칭이 변경되었습니다.
prop : value -> modelValue
event : input -> update:modelValue v-bind
의 .sync 수식어와 컴포넌트의 model 옵션이 제거되고 v-model 인자로 대체 되었습니다.
새로운 기능
- 동일 컴포넌트에서 다중의
v-model
바인딩이 가능하게 되었습니다. - 사용자 지정
v-model
수식어를 생성하는 기능이 추가되었습니다.
(2) v-for
문법의 변화
1. 조건부 분기에서의 key
- Vue3 버전에서는 Vue가 고유한 key를 자동으로 생성하기 때문에
v-if
/v-else
/v-else-if
에서 더 이상 key 가 필요하지 않습니다. - 만약 수동으로 key를 정할 경우, 각 분기는 반드시 고유한 key를 사용해야합니다. 의도적으로 동일한 key를 사용하여 분기를 강제로 재사용할수 없게 되었습니다.
<template v-for>
의 key는 자식이 아닌<template>
태그에 있어야 합니다.
Vue2 버전
v-if
/v-else
/v-else-if
분기에 key를 사용하도록 권장<!-- Vue 2.x --> <div v-if="condition" key="yes">Yes</div> <div v-else key="no">No</div>
- 위 코드는 Vue3 버전에서도 유효하게 동작합니다. 하지만 Vue3 버전부터는 key를 정하지 않았을 때에 조건부 분기에 고유한 key가 자동으로 생성되기 때문에 key 속성을 명시하지 않는 것이 좋습니다.
Vue3 버전
<!-- Vue 3.x (권장 솔루션: key를 명시하지 않음) -->
<div v-if="condition">Yes</div>
<div v-else>No</div>
<!-- Vue 3.x (대체 솔루션: key가 항상 고유한지 확인이 필요) -->
<div v-if="condition" key="a">Yes</div>
<div v-else key="b">No</div>
- 만약 key를 직접 명시하고 싶다면, 해당 key가 고유한 값인지를 확인해야 합니다.
2. <template v-for>
와 함께 사용하기
Vue2
- Vue2 에서는
<template>
태그가 key를 가질 수 없었습니다. 대신 각 자식 항목에 key를 배치할 수 있었습니다. <template v-for="item in list"> <div :key="item.id">...</div> <span :key="item.id">...</span> </template>
Vue3
- Vue3 에서는 key가
<template>
태그에 반드시 있어야 합니다. <!-- Vue 3.x --> <template v-for="item in list" :key="item.id"> <div>...</div> <span>...</span> </template>
- 마찬가지로
<template v-for>
가 v-if를 사용하는 자식과 함께 있을 때에는, key를<template>
태그까지 끌어올려야 합니다.
Vue2 -> Vue3 코드 비교
<!-- Vue 2.x -->
<template v-for="item in list">
<div v-if="item.isVisible" :key="item.id">...</div>
<span v-else :key="item.id">...</span>
</template>
<!-- Vue 3.x -->
<template v-for="item in list" :key="item.id">
<div v-if="item.isVisible">...</div>
<span v-else>...</span>
</template>
(3) v-if
와 v-for
의 우선순위
- Vue2 버전에서는 동일한 엘리먼트에
v-if
와v-for
를 함께 사용할 때,v-for
가 더 높은 우선순위를 가졌습니다. - 하지만 Vue3 버전부터는
v-if
가 더 높은 우선순위를 가지게 됩니다. - 구문이 모호해지기 때문에 동일한 엘리먼트에 두 디렉티브를 함께 사용하지 않는 것이 좋습니다. 이를 방지하기 위해 두 디렉티브를 템플릿 수준에서 관리하는 것보다는 표시할 요소 목록을 필터링하는 computed 속성을 만드는 것이 바람직합니다.
(4) v-bind="object"
의 순서
- Vue3에서는 v-bind 의 바인딩 순서가 렌더링 결과에 영향을 미치게 됩니다.
- Vue2*
<!-- 템플릿 --> <div id="red" v-bind="{ id: 'blue' }"></div> <!-- 결과 --> <div id="red"></div>
- Vue2에서는 엘리먼트에
v-bind="object"
코드와 이와 동일한 개별 속성이 모두 정의된 경우, 개별 속성이 항상 object의 바인딩을 덮어썼습니다. - 하지만 이는 병합 우선순위에 관한 의문을 불러일으켰습니다.
Vue3
<!-- 템플릿 -->
<div id="red" v-bind="{ id: 'blue' }"></div>
<!-- 결과 -->
<div id="blue"></div>
<!-- 템플릿 -->
<div v-bind="{ id: 'blue' }" id="red"></div>
<!-- 결과 -->
<div id="red"></div>
- Vue3 에서는 엘리먼트에
v-bind="object"
코드와 이와 동일한 개별 속성이 모두 정의된 경우, 바인딩 선언 순서에 따라 병합 방법이 결정됩니다. - 사용자(개발자)가 원하는 대로 병합 동작을 제어할 수 있게 됨을 의미합니다.
(5) v-for
Array refs
- Vue2 에서
v-for
에ref
속성을 사용하면 해당$refs
프로퍼티는 참조배열을 가지게 됩니다. 하지만 중첩된v-for
가 있는 경우, 이 동작은 모호하고 비효율적이었습니다. - Vue3에서는 더 이상 Vue2와 같이
$refs
에 배열을 자동으로 생성하지 않습니다. 단일 바인딩에서 여러 참조를 다루려면,ref
를 함수에 바인딩 해야합니다.// option API export default { data() { return { itemRefs: [] } }, methods: { setItemRef(el) { this.itemRefs.push(el) } }, beforeUpdate() { this.itemRefs = [] }, updated() { console.log(this.itemRefs) } }
// template <div v-for="item in list" :ref="setItemRef"></div>
// composition API
import { ref, onBeforeUpdate, onUpdated } from 'vue'
export default {
setup() {
let itemRefs = []
const setItemRef = el => {
itemRefs.push(el)
}
onBeforeUpdate(() => {
itemRefs = []
})
onUpdated(() => {
console.log(itemRefs)
})
return {
itemRefs,
setItemRef
}
}
}
itemRefs
는 꼭 배열이 아니어도 됩니다. 반복 key로 참조가 설정된 객체일 수 있습니다.- 필요한 경우,
itemRefs
를 반응형으로 만들고 변경을 감지할 수 있습니다.
참고문서 : vue3 공식문서
반응형
'Study > Vue' 카테고리의 다른 글
Vue 3 ) Props (0) | 2022.01.08 |
---|---|
Vue3 ) watch 와 watchEffect (0) | 2022.01.08 |
Vue 3 ) 뷰 라이프사이클의 변경?! (0) | 2022.01.08 |
Vue ) 이벤트 수식어 (0) | 2022.01.08 |
Vue) Vite?, 왜 사용할까? (0) | 2022.01.07 |
댓글