본문 바로가기

Languages/Vue

[Vue] Vue2 & Vue3 차이점

728x90
반응형

0. Vue2 vs Vue3

Vue3가 공식적으로 출시되고도 여전히 Vue2를 많이 사용한다. 그러나 장기적으로 봤을 때 Vue2에서 Vue3로의 변경을 필연적이다. 

 

Vue3가 출시되면서 Vue2로부터 무엇이 바뀌었는지, 어떤 차이점이 있는지에 대해서 알아보자.

 

공식문서를 바탕으로 작성했으며 그중에서도 중요하다고 생각되는 것들만 정리했다.

전체 내용을 확인하고 싶다면 공식 문서를 확인하는 것을 추천한다.

 

 

1. Fragments

fragments란 다중 루트 노드 컴포넌트를 의미한다. 

 

Vue2에서는 단일 루트 노드만을 지원했으며 이를 위해 사용자는 template마다 안에 div로 한번 더 감싸서 사용했어야 했다.

<template>
  <div>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </div>
</template>

 

그러나 Vue3에서는 다중 루트 노드인 fragments를 지원한다. 쉽게 말해 더 이상 div로 한번 더 감싸지 않아도 된다.

<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>

 

 

2. Emits 컴포넌트 옵션

Vue2에서 별도로 Emit을 정의하는 부분 없이 그냥 사용하기만 하면 되었다. 그러나 Vue3에서는 props처럼 Emit을 정의하는 부분이 존재한다. 이는 이벤트를 관리하는데 훨씬 더 편하게 만들 것이다.

app.component('custom-form', {
  emits: ['in-focus', 'submit']
})

 

또한 props와 마찬가지로 객체 형식으로 선언하여, 더 구체적으로 검사할 수 있다.

app.component('custom-form', {
  emits: {
    // 검사 절차 없음
    click: null,

    // submit 이벤트 검사
    submit: ({ email, password }) => {
      if (email && password) {
        return true
      } else {
        console.warn('잘못된 이벤트 페이로드입니다!')
        return false
      }
    }
  },
  methods: {
    submitForm() {
      this.$emit('submit', { email, password })
    }
  }
})

 

 

3. CSS 변수

template에서 정의한 변수를 그대로 style에서 사용할 수 있다.

 

Vue2에서는 이러한 방법이 없어 style에 동적인 값을 옵션으로 사용하고 싶을 때면, tamplate에서 style을 정의했다. 물론 이 방법도 나쁜 방법은 아니지만 html, script, css를 분리하여 관리하는 Vue의 컨셉에 맞지 않는 방법이기도 했다. 

 

template에서 정의한 변수를 css에 그대로 사용할 수 있게 됨으로써 style 옵션을 완전히 style태그에서 관리할 수 있다.

<template>
  <div class="text">hello</div>
</template>

<script>
export default {
  data() {
    return {
      color: 'red'
    }
  }
}
</script>

<style vars="{ color }">
.text {
  color: var(--color);
}
</style>

 

 

4. v-model

Vue3에서 v-model은 "modelValue"라는 props와 "update:modelValue"라는 emit으로 이루어진다. 

<ChildComponent v-model="pageTitle" />

<!-- 축약된 방식은 아래와 같습니다: -->

<ChildComponent
  :modelValue="pageTitle"
  @update:modelValue="pageTitle = $event"
/>

 

또 "modelValue"라는 v-model의 이름을 변경할 수도 있다. 이때 변경한 이름이 modelValue를 대체한다.

<ChildComponent v-model:title="pageTitle" />

<!-- 축약된 방식은 아래와 같습니다: -->

<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />

 

하나의 컴포넌트가 여러 개의 v-model을 가질 수 있다.

 

<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />

<!-- 축약된 방식은 아래와 같습니다: -->

<ChildComponent
  :title="pageTitle"
  @update:title="pageTitle = $event"
  :content="pageContent"
  @update:content="pageContent = $event"
/>

 

 

5. v-for, v-if

Vue2에서 v-if를 사용할 때 key 사용을 권장했다. 그러나 Vue3에서는 key를 자동으로 생성해주기 때문에 key를 사용하지 않는 것을 권장한다.

<!-- Vue 2.x -->
<div v-if="condition" key="yes">Yes</div>
<div v-else key="no">No</div>

<!-- Vue 3.x -->
<div v-if="condition">Yes</div>
<div v-else>No</div>

 

template에서 v-for 사용이 가능해졌다. key 또한 template 안에서 사용해야 한다.

<template v-for="item in list" :key="item.id">
  <div>...</div>
  <span>...</span>
</template>

 

v-for와 v-if를 같이 사용할 때 우선순위가 바뀌었다. Vue2에서는 v-for의 우선순위가 더 높았지만 , Vue3에서는 v-if의 우선순위가 더 높다. 하지만 Vue2에서도 v-for와 v-if를 같이 사용하지 않는 것을 권장했던 것처럼 Vue3에서도 v-for와 v-if는 되도록 따로 사용하는 것이 좋다.

 

 

6. Transition 클래스 이름 변경

Transition 클래스 이름이 더 직관적이고 이해하기 쉽게 변경되었다.

//Vue2
.v-enter,
.v-leave-to {
  opacity: 0;
}

.v-leave,
.v-enter-to {
  opacity: 1;
}


//Vue3
.v-enter-from,
.v-leave-to {
  opacity: 0;
}

.v-leave-from,
.v-enter-to {
  opacity: 1;
}
728x90
반응형

'Languages > Vue' 카테고리의 다른 글

[Vue] Vue Router  (0) 2022.05.17