
こんにちはー、ニアです!
自分のポートフォリオはフレームワークにVue.jsを使っているのですが、先日にポートフォリオの更新のついでに、Vue.jsのバージョンを2(以下、Vue 2)から3(以下、Vue 3)にアップデートしました。
1. Vue 2はサポート終了済み! Vue 3にアプデする? それともReact?
Vue 2は、2023年末にサポートが終了していたので、セキュリティの観点からアップデートなどの対応が必要でした。
業務では、フロントエンドの開発で主にReactやNext.jsを使っているので、プログラミングの復習も兼ねてReactにする案もありましたが、別の案件でVue.jsを使うことになった時に取り掛かりやすいように、自分のポートフォリオではVue.jsを引き続き使い、Vue 3にアップデートすることにしました。
ついでにビルドツールもVue CLIからViteに変更しました。もちろん、Vercelでのビルド&デプロイに利用できます。
自分のポートフォリオでも、高速化を体感できました
2. Let’s Vue 3にアップデート
Vue 3へのアップデートとViteへの変更は、以下のように作業をしました。
- Vue.jsなどのライブラリをアップデート、Viteをインストール
- Viteのコマンドラインツールで、新しいVue.jsのプロジェクトを作成
- Viteでのビルド必要なファイルを、ポートフォリオのプロジェクトにコピー
- コンポーネントなどのソースコードをVue 3用に修正
2.1. Vue 3では、Composition APIを使って、コンポーネントを記述
Vue 2の頃は、Vue Class ComponentとVue Property Decoratorを使って、コンポーネントを記述していました。
<template>
    <tr>
        <td>{{ name }}</td>
        <td>{{ skillGradeStar }}</td>
    </tr>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
export interface SkillItem {
    name: string;
    skillGrade: number;
}
@Component
export default class SkillListItem extends Vue {
    @Prop()
    private name!: string;
    @Prop()
    private skillGrade!: number;
    get skillGradeStar() {
        let adjustSkillGrade = Math.min( 5, Math.max( 1, this.skillGrade ) );
        return "★".repeat( adjustSkillGrade ) + "☆".repeat( 5 - adjustSkillGrade );
    }
}
</script>Vue 3では、Composition APIを使って記述し、プロパティは defineProps() で定義し、getterの部分は、computed() で定義しました。
<script setup lang="ts">
import {computed} from "vue";
export interface SkillItem {
  name: string
  skillGrade: number
}
const props = defineProps<SkillItem>();
const skillGradeStar = computed(() => {
  let adjustSkillGrade = Math.min( 5, Math.max( 1, props.skillGrade ) )
  return "★".repeat( adjustSkillGrade ) + "☆".repeat( 5 - adjustSkillGrade )
})
</script>
<template>
  <tr>
    <td>{{ name }}</td>
    <td>{{ skillGradeStar }}</td>
  </tr>
</template>あと、Viteではプロジェクト直下にあるindex.htmlを読み込む仕様なので、index.htmlをプロジェクト直下に移動しました。
3. Vue 3にアップデート&Viteに変更で遭遇したトラブル
3.1. Viteでビルドすると、「URI malformed」のエラーが発生する
これはindex.htmlに設定していた、ファビコンのURIに「<%= BASE_URL %>」が含まれていたのが原因でした。
ファビコンはビルド時にindex.htmlと同じディレクトリに配置されるので、URIから「<%= BASE_URL %>」を取り除き、解決しました。
<!-- Viteでビルドするとエラーになる -->
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- 修正後 -->
<link rel="icon" href="/favicon.ico">3.2. 画面に何も表示されない(ビルドしても、JavaScriptが出力されない)
Vue CLIの場合は、ビルド時に出力されたindex.htmlに、ビルドされたJavaScriptファイルを読み込む <script> タグが自動的に挿入されます。
Viteの場合は、index.htmlに エントリポイントのTypeScriptファイルを読み込む <script> タグを明示的に入れる必要があります。
<script type="module" src="/src/main.ts"></script>3.3. <router-link> の tag プロパティは利用不可 → 必ず <a> タグがレンダリングされる
ナビゲーションメニューには、<ul> タグの中に入れた <router-link> の tag プロパティを li にセット( <li> タグがレンダリングされる)して構成していました。
<ul>
  <router-link tag="li"> ... </router-link>
  <router-link tag="li"> ... </router-link>
  ...
</ul>しかし、Vue 3用のvue-router(バージョン4)の <router-link> では、tag プロパティがオミットされてしまい、必ず <a> タグがレンダリングされるようになったので、<ul> タグを <nav> タグに変更し、CSSを修正して、なんとか以前のレイアウトを復元しました。
<nav>
  <router-link> ... </router-link>
  <router-link> ... </router-link>
  ...
</nav>デバッグし始めた頃は、表示がかなり崩れていました(汗)
4. おわりに
修正がちょっと大変でしたが、無事にポートフォリオのVue.jsのアップデート作業を完了できました。
ちなみにViteはVue.jsの他にReactでも利用できるので、今後新たにReactを使用する機会がある時にも効率よく開発できそうです。
[END]
 
 




