본문 바로가기
Study/Vue

Vue3를 준비하는 자세 (1)

by JongIk 2022. 1. 2.
반응형

Vue2에서 Vue3 버전으로 넘어가면서 변경된 사항 중 하나인 템플릿 디렉티브의 변화에 관한 정리글입니다.


Vue3에서의 변경사항

(1) v-model 사용법의 변화

변경사항

  • 커스텀 컴포넌트를 사용할 때, v-model propevent의 기본 명칭이 변경되었습니다.
    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-ifv-for의 우선순위

  • Vue2 버전에서는 동일한 엘리먼트에 v-ifv-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-forref 속성을 사용하면 해당 $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

댓글