Vue2からVue3の変更点を整理する

目次
1. 背景
2. 変更点
3. どのように効率よく対応するか

# 1. 背景
Nuxt2を業務で使用しています。年内にサポート切れするということでNuxt3に移行する必要がある為です。
Vue2は2024年3月までサポートされるということですが。

https://v3-migration.vuejs.org/breaking-changes/

# 2. 変更点

## 2.1 Vue.extendの削除
- defineComponentで書き換えます。

vue2
```
import Vue from "vue";
export default Vue.extend({
```
↓
vue3
```
import { defineComponent } from "vue";
export default defineComponent({
```

## 2.2 ESLint の設定
ESLint の設定ファイルにいる extends の plugin:vue/〇〇 を plugin:vue/vue3-〇〇 に変更する必要があります。
```.eslintrc.js
module.exports = {
  extends: [
    // add more generic rulesets here, such as:
    // 'eslint:recommended',
    'plugin:vue/vue3-recommended',
    // 'plugin:vue/recommended' // Use this if you are using Vue.js 2.x.
  ],
  rules: {
    // override/add rules settings here, such as:
    // 'vue/no-unused-vars': 'error'
  }
}
```

## 2.3 /deep/は廃止、>>> は警告出る、 :deep(.selector) に変更
```js:outer.vue
// エイリアスなのでどちらでもいい
/deep/ .inner-text {
    color: blue;
}

>>> .inner-text {
    color: blue;
}
```
↓
```js:outer.vue
:deep(.inner-text) {
    color: blue;
}
```

## 2.4 Filter、テンプレートフィルタ構文の廃止
https://v3-migration.vuejs.org/ja/breaking-changes/filters.html
vue2
```sample.vue
<template>
  <h1>Bank Account Balance</h1>
  <p>{{ accountBalance | currencyUSD }}</p>
</template>

<script>
  export default {
    props: {
      accountBalance: {
        type: Number,
        required: true
      }
    },
    filters: {
      currencyUSD(value) {
        return '$' + value
      }
    }
  }
</script>

```
↓
vue3
```sample.vue
<template>
  <h1>Bank Account Balance</h1>
  <p>{{ accountInUSD }}</p>
</template>

<script>
  export default {
    props: {
      accountBalance: {
        type: Number,
        required: true
      }
    },
    computed: {
      accountInUSD() {
        return '$' + this.accountBalance
      }
    }
  }
</script>
```

Vue.Filterの書き換え
普通の関数に書き換える感じです。
```js
Vue.filter('longformat', function (t) { return (!!t) ? '-' : moment(t).format('YYYY年MM月DD日(dddd)') });
```
↓
```js
export function longformat (t) { return (!!t) ? '-' : moment(t).format('YYYY年MM月DD日(dddd)') };
```

## 2.5 .sync 修飾子を v-model に書き換え
https://v3-migration.vuejs.org/breaking-changes/v-model.html#using-v-bind-sync

## 2.6 Vue.deleteの廃止
https://stackoverflow.com/questions/66304282/vue-3-vue-delete-alternative

## 2.7 slot="header"が非推奨に
vue2
```vue
  <template slot="header">
    <h1>ヘッダー</h1>
  </template>
```
↓
vue3
```vue
  <template v-slot:header>
    <h1>ヘッダー</h1>
  </template>
```

# 3. どのように効率よく対応するか
以下記事を見つけました。
[eslint-plugin-vue を使用して継続的に Vue3 移行する](https://ota-meshi.github.io/vue-fes-japan-online-2022-slide/1)

[eslint-plugin-vue](https://www.npmjs.com/package/eslint-plugin-vue)を使うことで半分以上の変更点を自動で修正してくれるそうです。

# 参考
- [Vue deep Selectorでscoped SASSの子コンポーネントにスタイルを適用する方法](https://shigurezuki.jp/articles/vue-deep-selector/)
- [Nuxt2(bridge)からNuxt3へのフレームワーク移行とその工数](https://labs.1-10.com/2023/01/20/2290)
- [当社プロダクトにおける、nuxt2→nuxt3 への移行時の記録](https://tech.torico-corp.com/blog/migrate-nuxt2-to-nuxt3-on-our-product/)
- [正式リリース前に総予習!! Vue3の変更点まとめ](https://qiita.com/ryo2132/items/3d0379e85c38a9a5b355)
- [Vue2からVue3への移行-Filterの廃止を修正](https://nipo-plus-doc.sndbox.jp/tech/vuefilter/)
- [【Vue.js】Vue2→Vue3 主な記述方法の変更点 チートシート](https://qiita.com/csk/items/1940dc29ee5e19ec58b1#6-%E3%82%B9%E3%83%AD%E3%83%83%E3%83%88)
- [eslint-plugin-vue を使用して継続的に Vue3 移行する](https://ota-meshi.github.io/vue-fes-japan-online-2022-slide/1)
- [Vue2のプロジェクトをVue3へマイグレーションする](https://zenn.dev/azukiazusa/articles/c8d76eb56f5fd8)