LoginSignup
2
2

More than 1 year has passed since last update.

Vue2のプロジェクトはVue3に上げるべき…?

Last updated at Posted at 2021-10-18

Nuxt.jsもついに3系がリリースされ、そろそろVueも3系にupgradeしなければ‥
とみなさんがお思いであると思いますので、公式の発表を掻い摘んでまとめていきます。

composiotion API

Vue 3.xから新たに追加された機能では有りませんが、これからはcomposition API前提での話になってきそうなので、composition APIについても簡易的にまとめておきます。

composition.vue
import { computed, defineComponent, reactive, } from 'vue'
export default {
  components: { RepositoriesFilters, RepositoriesSortBy, RepositoriesList },
  props: {
    user: {
      type: String,
      required: true
    }
  },
  setup(props) {
    const state = reactive<State>({
      todos: []
    })
    const result = computed(() => state.todos.sort((a, b) => {
      return b.createdAt.getTime() - a.createdAt.getTime()
    }))

    return {
      result
    } // ここで返されるものはコンポーネントの他のオプションで使用可能です
  }
}

setupメソッド

Options API(composition API以前の構造)と異なり、Vue component内でのdata,methods,computed,ライフサイクルメソッド(mounted,createdなど)などの区別がなくなり、全てがsetupメソッドの中に記述されています。(mounted -> onMountedなど多少の変化はあり)
一方で、componentsやpropsの記述は以前と同様に記述します。

setupメソッド内のデータは、returnされたものだけがtemplate内で使用できるようになります。
そのため、setupメソッド内でstateという変数を宣言したとしてもreturnしない場合はこれを使用することはできません。stateの値は直接使用せずに、computedを通して使用するという意図を伝えることができます。

thisの削除

全てがsetupメソッド内に記述された結果、他のプロパティにアクセスする際にthisが不要になりました。以前までのVueではこのthisの制約によりアロー関数で記述することが敬遠されていた(const self = this;など一度定義しないと内部で使用できなかったため)のですが、Composition APIではアロー関数により記述が可能になりました。

Template Directives

v-modelのデータバインディングの簡略化

v-modelを渡すだけで、親のComponentとデータバインディングするための Props 及び Emit が暗黙的にバインドされます。emitで受け取る側の処理が簡略的に書けるようになりました。

-- POINT --
v-bindの.sync修飾子とコンポーネントmodelオプションが削除され、v-modelの引数に置き換えられました。

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

<!-- 上記は下記の省略形です -->

<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />
child.vue
<script>
export default {
  props: {
    modelValue: String // vue2.xでは value:String でした
  },
  emits: ['update:modelValue'],
  methods: {
    changePageTitle(title) {
      this.$emit('update:modelValue', title) // vue2.xでは this.$emit('input', title) でした
    }
  }
}
</script>

v-ifのkeyが不要に

v-if/v-else/v-else-ifを使用する際、keyを用いることが推奨されていましたが、Vue 3.xになって不要になりました。

vue
<!-- 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>

v-forの使用する際には、v-for自体に:keyをもたせることができ、子にkeyは不要になりました。
また、Vue 2.xまではtemplateにkeyをもたせることができませんでしたが、Vue 3.xでは持たせることができ、子のkeyは省略することができます。

vue
<!-- 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>

Vue 2.xでは、v-ifとv-forが同じ要素に設定している場合、v-forが優先されてきましたが、Vue3からはv-ifが優先されます。

v-bind

Vue 2.xの場合はすでに指定されている場合、v-bindのほうが弱かったですが、Vue 3.xでは指定する属性の順番で優先順位が変わります。

vue2.vue
<!-- template -->
<div id="red" v-bind="{ id: 'blue' }"></div>

<!-- result -->
<div id="red"></div>
vue3.vue
<!-- template -->
<div id="red" v-bind="{ id: 'blue' }"></div>
<!-- result -->
<div id="blue"></div>

<!-- template -->
<div v-bind="{ id: 'blue' }" id="red"></div>
<!-- result -->
<div id="red"></div>

Components

emitを明示的に定義

これまでcomponentではpropsはscript内に定義していましたが、Vue 3.xではemitも書かなくてはなりません。
これにより、途中からプロジェクトに入った人などがより速やかにコードが理解しやすくなるかと思います。

emit.vue
<!-- Vue 2.x -->
<template>
  <div>
    <p>{{ text }}</p>
    <button v-on:click="$emit('accepted')">OK</button>
  </div>
</template>
<script>
  export default {
    props: ['text']
  }
</script>


<!-- Vue 3.x -->
<template>
  <div>
    <p>{{ text }}</p>
    <button v-on:click="$emit('accepted')">OK</button>
  </div>
</template>
<script>
  export default {
    props: ['text'],
    emits: ['accepted']
  }
</script>

Vue 3.x まとめ

Vue 2.xでは暗黙的に動作していた部分をVue 3.xでは定義しなくてはいけなくなるものが多く、コードの保守性が向上したのではないかと思います。ただ、そのせい?で破壊的な変更が多く(特にOption  API -> composition API)、既存のVue 2.xを使用しているプロジェクトをVue 3.xに上げるのはひどく大変なものだと考えられます…
Option APIで動作自体はするようですが…

新規プロジェクトではVue 3を使ってみたいなと思います!

参考

Vue.js公式:https://v3.vuejs.org/guide/migration/introduction.html#overview

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2