Vue.js と React と Blazor で同じ処理を書こう (#1 リアクティブな動作)

# Vue.js と React と Blazor で同じ処理を書こう (#1 リアクティブな動作)

こんにちは、@studio_meowtoon です。今回は、WSL の Ubuntu 22.04 で Vue.js、React、Blazor それぞれの Web アプリの実装を比べてみます。
![vuejs_vs_react_vs_blazor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/05f36af6-d73a-45b8-e967-5e80ace264da.png)

## 目的

Windows 11 の Linux でクラウド開発します。

こちらから記事の一覧がご覧いただけます。

https://qiita.com/studio_meowtoon/items/6119ab05d8b13527efd8

## 実現すること

Vue.js、React、Blazor それぞれの Web アプリの実装方法を比べてみます。

:::note alert
この記事では、**学習目的**でコードの実装を行っています。そのため、この実装が唯一の正しい実装方法ではありません。ご注意ください。
:::
## 開発環境

+ Windows 11 Home 22H2 を使用しています。  

:::note info
[WSL](https://learn.microsoft.com/ja-jp/windows/wsl/about) の Ubuntu を操作していきますので macOS の方も参考にして頂けます。  
:::

<details>

WSL (Microsoft Store アプリ版) [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/2aaa6579cb8e4fa1d874)

```sh
> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
```

Ubuntu [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/2aaa6579cb8e4fa1d874)

```sh
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04
```

npm [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/111f556d8fb11a76430a)

```sh
$ node -v
v19.8.1
```

```sh
$ npm -v
9.5.1
```

.NET SDK [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/d68031c91462f6808dff)

```sh
$ dotnet --list-sdks
7.0.202 [/usr/share/dotnet/sdk]
$ dotnet --version
7.0.202
```

</details>

:::note warn
この記事では基本的に **Ubuntu のターミナルで操作**を行います。**Vim を使用してコピペする方法**を初めて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。
:::

https://qiita.com/studio_meowtoon/items/7771ad48676926e41463

## 作成する Web アプリケーションの仕様

:::note info
Web ブラウザ上の **input** にテキストを入力して Enter キーを押すと、**h1 要素**が更新される**リアクティブな動作**を実装します。
:::

## リアクティブな動作を実装してみる

### Vue.js の場合

Vue.js Web アプリの作成

こちらの関連記事で手順がご確認いただけます。

https://qiita.com/studio_meowtoon/items/2381f271f88f783d1321#comment-69100c25307f027051ae

<details>
<summary>手順を表示します。</summary>

プロジェクトに移動します。

```sh
$ cd ~/tmp/hello-vuejs
```

main.js を修正します。

```sh
$ vim src/main.js
```

</details>

ファイルの内容

```js:src/main.js
import { createApp } from 'vue';

const app = createApp({
  data() {
    return {
      message: "Hello World!"
    }
  },
  methods: {
    hello(event) {
      this.message = event.target.value;
    }
  },
  template: `
    <div>
      <h1>{{message}}</h1>
      <input type="text" v-bind:value="message" v-on:keydown.enter="hello" />
    </div>
  `
});

app.mount("#app");
```

<details>
<summary>説明を開きます。</summary>

:::note info

|内容|
|:--|
|Vue.js では、アプリケーションの状態を data オブジェクトで管理し、その状態を変更するための methods オブジェクトを提供します。|
|createApp 関数を使用して、Vue.js のアプリケーションインスタンスを作成し、data オブジェクトと methods オブジェクトを定義しています。|
|data オブジェクトには、message というプロパティがあり、初期値として "Hello World!" を設定しています。|
|methods オブジェクトには、hello というメソッドがあり、入力欄で Enterキー を押すと呼び出され、入力欄の値を message に設定します。|
|template プロパティでは、Vue.js のテンプレート構文を使用して、ページの HTML を定義しています。|
|{{message}} は、data オブジェクトの message プロパティの値を表示します。|
|v-bind:value ディレクティブと v-on:keydown.enter ディレクティブを使用して、入力欄の値と Enter キーのダウンイベントを処理しています。|

:::

</details>

アプリを起動します。
※ アプリを停止するときは ctrl + C を押します。

```sh
$ npm run start
```

<details>
<summary>UI 動作のキャプチャ画像を表示します。</summary>

Web ブラウザが立ち上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/c5fb8072-068a-eb03-0779-6b5f21920021.png)
input にテキストを入力して Enter してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/5fc9923f-5c1f-167d-a268-b2a8b8dcaee5.png)

</details>

:::note info
このように、input にテキストを入力すると、h1 要素が**リアクティブ**に更新されました。
:::

### React の場合

React Web アプリの作成

こちらの関連記事で手順がご確認いただけます。

https://qiita.com/studio_meowtoon/items/c4f635b470981a8cdecb

<details>
<summary>手順を表示します。</summary>

プロジェクトに移動します。

```sh
$ cd ~/tmp/hello-react
```

index.js を修正します。

```sh
$ vim src/index.js
```

</details>

ファイルの内容

```jsx:src/index.js
import React, { useState } from 'react';
import ReactDOM from 'react-dom';

const App = () => {
  const [value, setValue] = useState("Hello World!");
  const handleKeyPress = (event) => {
    if (event.key === "Enter") {
      setValue(event.target.value);
    }
  };

  return (
    <div>
      <h1>{value}</h1>
      <input type="text" defaultValue={value} onKeyPress={handleKeyPress} />
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("app"));
```

<details>
<summary>説明を開きます。</summary>

:::note info

|内容|
|:--|
|useState フックを使用して、value という状態変数を宣言しています。|
|value の初期値は "Hello World!" です。|
|handleKeyPress 関数は、ユーザーが入力欄で Enter キーを押した場合に呼び出され、入力欄の値を value に設定します。|
|return 文では、value を表示する h1 要素と、入力欄を定義しています。|
|入力欄の onKeyPress プロパティに、handleKeyPress 関数を割り当てています。|
|React の ReactDOM.render 関数を呼び出して、\<App /\> コンポーネントをレンダリングし、ブラウザの \<div\> 要素に挿入しています。|

:::

</details>

アプリを起動します。
※ アプリを停止するときは ctrl + C を押します。

```sh
$ npm run start
```

<details>
<summary>UI 動作のキャプチャ画像を表示します。</summary>

Web ブラウザが立ち上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/99fa6dba-6a24-6554-74c7-870a99c21c5d.png)
input にテキストを入力して Enter してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/b693759e-794c-2edf-5dec-bd0f17833e28.png)

</details>

:::note info
このように、input にテキストを入力すると、h1 要素が**リアクティブ**に更新されました。
:::

### Blazor の場合

Blazor Web アプリの作成

こちらの関連記事で手順がご確認いただけます。

https://qiita.com/studio_meowtoon/items/16d5d58e758beed8dd27

<details>
<summary>手順を表示します。</summary>

プロジェクトに移動します、

```sh
$ cd ~/tmp/BlazorApp
```

Index.razor を修正します。

```sh
$ vim Pages/Index.razor
```

</details>

ファイルの内容

```html:Pages/Index.razor
@page "/"
<div>
  <h1>@_message</h1>
  <input @bind-value="@_message" />
</div>

@code {
  string _message = "Hello World!";
}
```

<details>
<summary>説明を開きます。</summary>

:::note info

|内容|
|:--|
|この入力欄に入力した内容は、_message という変数にバインドされます。|
|つまり、入力欄に入力した文字列は、変数 _message に自動的に保存されます。|
|入力欄の値が変更されるたびに、変数 _message の値も更新され、ページのタイトルに反映されます。|

:::

</details>

アプリを起動します。
※ アプリを停止するときは ctrl + C を押します。

```sh
$ dotnet run
```

<details>
<summary>UI 動作のキャプチャ画像を表示します。</summary>

Web ブラウザが立ち上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/93048f01-e328-75c6-9660-df93790c4672.png)
input にテキストを入力して Enter してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/21d62430-ef88-e9ab-0a7c-4b3e6d9c4868.png)

</details>

:::note info
このように、input にテキストを入力すると、h1 要素が**リアクティブ**に更新されました。
:::

## まとめ

Ubuntu に構築したシンプルな開発環境で、Vue.js、React、Blazor それぞれの Web アプリのリアクティブな実装方法を比べてみることができました

:::note warn
**Ubuntu** を使うと **Linux の知識**も身に付きます。最初は難しく感じるかもしれませんが、徐々に進めていけば自信を持って書けるようになります。
:::

どうでしたか？ WSL Ubuntu で、さまざまな Web アプリケーションを手軽に起動することができます。ぜひお試しください。今後も npm、.NET の開発環境などを紹介していきますので、ぜひお楽しみにしてください。