0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unplugin Vue Routerで小規模開発でもファイルベースルーティング

Posted at

Unplugin Vue Routerとは

Unplugin Vue Routerとは、一言で言うとVue.jsプロジェクトにおいて型安全性の高いファイルベースルーティングを実現するためのプラグインです。

また、今回は取り上げませんがその他の機能として、実験的なデータローダー機能をサポートしています。

なぜUnplugin Vue Routerを調べてみたのか

Vue.jsのフレームワークであるNuxt.jsの主要なメリットとして、レンダリング方式の柔軟な切り替えなどと並んで、ファイルベースルーティングによる開発効率の向上がよく挙げられます。
私自身試してみたこともあり、直感的で分かりやすいと感じておりました。

しかし、私が携わるプロジェクトは比較的小規模なものが多く、Nuxt.jsの豊富な機能セットはいささか過剰であると判断し、その採用を見送ってきました。

そんな中、Nuxt.jsと同様のファイルベースルーティングを単独の機能として追加できるUnplugin Vue Routerを知り、これならば小規模プロジェクトにも適しているのでは考え、まずは試してみることにしました。

実際に試してみた

セットアップ手順

実際にリファレンスに沿って設定してみます。

プロジェクト作成

まずはcreate-viteでテンプレートを使ってさくっとプロジェクトを作成します。
筆者はVue.js+TypeScript+Viteでの作業が主なので今回はそのまま使ってます

terminal
$ create-vite
✔ Project name: … vite-project
✔ Select a framework: › Vue
✔ Select a variant: › TypeScript

Scaffolding project in /xxx/vite-project...

Done. Now run:

  cd vite-project
  npm install
  npm run dev

作成されたプロジェクトで任意のパッケージマネージャを使用して、node_modulesをインストール、開発サーバーを起動してみると以下の画面が表示されるはずです。

localhost_5173_(FHD).png

ライブラリインストール

ここで今回の主役であるvue-routerunplugin-vue-routerをインストールします。

terminal
$ yarn add vue-router
$ yarn add -D unplugin-vue-router

プラグインの追加

バンドルに今回のプラグインを含めるよう設定を変更します。

vite.config.ts
import { defineConfig } from 'vite'
+import VueRouter from 'unplugin-vue-router/vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({

  plugins: [
+    VueRouter(),
    vue()
  ],
})

設定が変更できたらここでもう一度開発サーバーを起動してみましょう。
rootディレクトリにtyped-router.d.tsが作成されていれば成功です。

ここまでできたらtsconfig.jsonを編集し、unplugin-vue-routerの型を追加しておきましょう。

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,

+    "types": ["unplugin-vue-router/auto-routes"]
  },
- "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
+ "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "./typed-router.d.ts"],
 
  "references": [{ "path": "./tsconfig.node.json" }]
}

ここまででセットアップは完了です。

基本的な使用方法

アプリケーションへの反映

main.tsでVue Routerの取り込みを行い、アプリケーションへ反映します。
これはいつものVue Routerと同じですね

main.ts
import { createApp } from 'vue'
import './style.css'
+import { createRouter, createWebHistory } from 'vue-router'
+import { routes } from 'vue-router/auto-routes'
import App from './App.vue'

+const router = createRouter({
+    history: createWebHistory(),
+    routes,
+  })

-createApp(App).mount('#app')
+createApp(App).use(router).mount('#app')

App.vueでいつものようにRouterViewを表示するように設定します。

App.vue
<script setup lang="ts">
import { RouterView } from 'vue-router'
</script>

<template>
  <RouterView />
</template>

これで反映の準備が整いました。

ファイルの配置=ルーティング

次に/src配下にpagesディレクトリを作成し、その中にindex.vueを作成します。

pages/index.vue
<script setup lang="ts">
import { RouterLink } from 'vue-router'
</script>
<template>
  <h1>Home</h1>
  <p>URL: {{ $route.path }}</p>
  <RouterLink to="/Hello">to Hello</RouterLink>
</template>

このファイルがhttps://www.hogehoge.com/の際にルーティングされるファイルです

遷移先のHello.vueも同じディレクトリに作成しておきます。

pages/Hello.vue
<script setup lang="ts">
import { RouterLink } from 'vue-router'
</script>
<template>
  <h1>Hello</h1>
  <p>URL: {{ $route.path }}</p>
  <RouterLink to="/">to Home</RouterLink>
</template>

作成後の配置はこのような状態です。
スクリーンショット 2024-12-24 23.57.28.png

作成できたらこの状態でまた開発サーバーを起動してみましょう。

Dec-25-2024 00-55-44.gif

Vue Routerの設定ファイルを作成していないのにしっかり画面遷移が行われています。
これはかなり楽ですね。

さらに階層をネストさせたい場合

例えば先ほどのhelloの下にworldをつけて"/hello/world"で別の画面を表示したい場合は、
pagesディレクトリの中にhelloディレクトリを作成、その中にhello.vueを移動させ、名前をindex.vueにすることで現在と同様の挙動を得られます。
そして、同階層にWorld.vueを先ほどまでと同じ手順で作成します。

スクリーンショット 2024-12-25 0.43.32.png

Dec-25-2024 00-58-25.gif

発展:動的ルーティング

[]でファイル名を囲むことでパスのパラメータを動的に変更することができます。
pagesディレクトリ配下に[id].vueを作成してみます。

[id].vue
<script setup lang="ts">
import { RouterLink } from 'vue-router'
import { useRoute } from 'vue-router'

const id = useRoute().params.id
</script>
<template>
  <h1>{{ id }}</h1>
  <p>URL: {{ $route.path }}</p>
  <RouterLink to="/">to Home</RouterLink>
</template>

この時点ではまだ、[id].vueのパスは決まっておらず、idとして渡された値に応じてパスが動的に作成されます。
pages/index.vueに自由入力欄を設けて動的にパスを作成してみます。

<script setup lang="ts">
import { RouterLink } from 'vue-router'
+import { ref } from 'vue'

+const id = ref('')
</script>
<template>
  <h1>Home</h1>
  <p>URL: {{ $route.path }}</p>
  <RouterLink to="/Hello">to Hello</RouterLink><br>
+  <input type="text" v-model="id" /><br>
+  <RouterLink :to="`/${id}`">to {{ id }}</RouterLink>
</template>

スクリーンショット 2024-12-25 1.17.17.png

Dec-25-2024 01-10-25.gif

実際に試してみて分かったUnplugin Vue Router

開発効率の向上

やはりファイルベースルーティングは直感的で分かりやすく、型補完が効くこともあり認知負荷が軽減されミスを最小限に抑えることができそうです。

従来のルーティング方法だとページを追加するたびに下記のようなルーティングの設定ファイルを更新していましたが、そこがなくなるのはストレスフリーですね。

router.ts
// Components
import SignIn from "@/views/SignIn.vue";
import DashBoard from "@/views/DashBoard.vue";
import DeviceList from "@/views/DeviceList.vue";
import Schedule from "@/views/Schedule.vue";
import Alerts from "@/views/Alerts.vue";
import AlertsLog from "@/views/AlertsLog.vue";
import UserList from "@/views/UserList.vue";


// Router Rules
const routes: RouteRecordRaw[] = [
  {
    path: "/signin",
    name: "signin",
    component: SignIn,
    meta: { requiredAuth: false },
  },
  {
    path: "/dashboard",
    name: "dashboard",
    component: DashBoard,
    meta: { requiredAuth: true },
    children: [
      {
        path: "home",
        name: "home",
        component: DeviceList,
        meta: { requiredAuth: true },
      },
      {
        path: "Schedule",
        name: "Schedule",
        component: Schedule,
        meta: { requiredAuth: true },
      },
      {
        path: "Alerts",
        name: "Alerts",
        component: Alerts,
        meta: { requiredAuth: true },
      },
      {
        path: "AlertsLog",
        name: "AlertsLog",
        component: AlertsLog,
        meta: { requiredAuth: true },
      },
      {
        path: "UserList",
        name: "UserList",
        component: UserList,
        meta: { requiredAuth: true },
      },
    ],
  },
  {
    path: "/:pathMatch(.*)*",
    redirect: {
      name: "signin",
    },
  },
];

私のようにNuxt.jsを採用するほどでもないが、ファイルベースルーティングでケアレスミスを減らしたい方は検討してみても良いかもしれません。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?