タイトルの通りのことをやってみました。
結論から言うと、Blazorをやっているとvueの学習コストが下がるので「dotnetしかやったことないよ!」という人にはVueはお勧めできるかと思います。
Blazorで作った話はこちら↓
今回作ったものはこちら↓
環境
- Vue3
- Vue-router@4
- Vuetify 3.0.0-alpha
- Vite
- gh-pages
vueコンポーネントとrazorコンポーネント
コンポーネントにはスタイル、テンプレート(UI)、スクリプトが含まれるという点でvueコンポーネントとrazorコンポーネントはほぼ同じ役割を持たせることができます
以下、Materialデザインの「カード」を列挙するページについてのコンポーネントです。
vue
コード
<template>
<v-container>
<h1>Works</h1>
<v-container v-for="app in apps" v-bind:key="app">
<v-card>
<v-card-title>{{app.name}}</v-card-title>
<v-card-media>
<v-img :src="app.img"></v-img>
</v-card-media>
<v-card-text>{{ app.text }}</v-card-text>
<v-card-subtitle>Platform {{ app.platform.join(", ") }}</v-card-subtitle>
<v-card-subtitle>Status {{app.status}}</v-card-subtitle>
<v-card-text></v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-btn v-if="app.url != ''" :to="app.url"><span class="text-info">Read more</span></v-btn>
<v-btn v-if="app.outerurl != ''" :href="app.outerurl"><span class="text-info">Read more</span></v-btn>
</v-card-actions>
</v-card>
</v-container>
</v-container>
</template>
<script setup>
import routineTreeImg from "../assets/RoutineTree.png"
const apps = [
{
name: "RoutineTree",
img: routineTreeImg,
text: "Task management application that helps you accomplish your daily routine tasks.",
platform: ["iOS"],
status: "In Review",
url: "",
outerurl: "https://syamaz.github.io/RoutineTree/"
},
{
name: "My homepage",
img: "",
text: "This website.",
platform: ["web"],
status: "Released",
url: "/",
outerurl: ""
}
]
</script>
<style>
</style>
Blazor
コード
@page "/works"
@inject NavigationManager navman
@using website.Components
@using website.Pages.Works.Parts
@using website.Pages.Works.Datas
<style>
.styled-linkbutton {
@*縦並び*@
display: block;
text-transform:none;
}
.styled-linkbutton:is(:hover) {
text-decoration: underline;
}
</style>
<PageTitle>Works - sYamaz</PageTitle>
<Typography Variant="TypographyVariant.H5">
Works
</Typography>
@foreach (var item in Datas)
{
<Box Padding="2" Margin="2">
<WorkCardView WorkData="@item" />
</Box>
}
@code {
private IEnumerable<AnyWorkData> Datas
{
get
{
yield return new AnyWorkData
{
Title = "RoutineTree",
Description = "Task management application that helps you accomplish your daily routine tasks.",
ReadMoreURL = "https://syamaz.github.io/RoutineTree/",
ImagePath = "images/RoutineTree.png",
Status = WorkStatus.inReview,
SupportPlatform = SupportPlatform.iOS
};
yield return new AnyWorkData
{
Title = "Some web app/service",
Description = "My practice project using Vue and AWS",
ReadMoreURL = "",
ImagePath = "images/Noimage.png",
Status = WorkStatus.underDevelop,
SupportPlatform = SupportPlatform.web
};
// --- end ---
yield return new AnyWorkData
{
Title = "My homepage",
Description = "This website.",
ReadMoreURL = "",
ImagePath = "images/Noimage.png",
Status = WorkStatus.release,
SupportPlatform = SupportPlatform.web
};
}
}
}
ルーティング
Blazorの場合、デフォルトでルーティング機能が付いてます。
@page "/{url}"
をコンポーネント内で宣言することで他ページから遷移することができます。
vueでvue-routerを使う場合はコンポーネントで宣言というよりは一括で宣言することになります。(ドキュメントを十分に読み込めてないだけで、別の方法があるかもしれません)
vue
コード
import { createRouter, createWebHistory } from 'vue-router'
// ページのコンポーネントをインポート
import AboutVue from '../components/About.vue'
import WorksVue from '../components/Works.vue'
import PostsVue from '../components/Posts.vue'
const routes = [
{
path: '/',
name: 'About',
component: AboutVue
},
{
path: '/works',
name: 'Works',
component: WorksVue
},
{
path: '/posts',
name: 'Posts',
component: PostsVue
},
]
const baseURL = import.meta.env.BASE_URL;
console.log("base : " + baseURL)
const router = createRouter({
history: createWebHistory(baseURL),
routes
})
export default router
GitHub Pages
基本的に楽をしたいため、gh-pages
npmパッケージを使用します。
vite.config.jsにデバッグ時と公開時でBaseURLをスイッチする定義を追加
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vuetify from '@vuetify/vite-plugin'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
// 略
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
// この一行を追加 '/{Githubリポジトリ名}'とか'/'とか
base: process.env.NODE_ENV === 'production' ? '{公開時}' : '{デバッグ時}',
// 略
})
このbaseプロパティをvue-routerで使用します
import.meta.env.BASE_URL: {string} アプリが配信されているベース URL。これは base 設定オプション によって決まります。
//vue-router@4
const baseURL = import.meta.env.BASE_URL;
const router = createRouter({
history: createWebHistory(baseURL),
routes
})
export default router
まとめ
dotnet開発者が→Webに手を広げていく際の一つの道が、「WinForm/WPF/UWP」→「Blazor」→「vue」なのかもしれません