petite-vueの実際の利用例を考えてみた

# TL;DR

- Petite-vueは最新のブラウザに最適化されたもうひとつのVue
- サーバーサイドでhtmlを生成するような場合に便利
- ただ現時点ではバグや破壊的変更もあるかも

# はじめに

2021/7/3にEvan Youが以下のようにつぶやきました

[https://twitter.com/youyuxi/status/1410980487418482694?s=20](https://twitter.com/youyuxi/status/1410980487418482694?s=20)

これ自体Twitter上でも大きな話題になりました。

実際のリポジトリがこちらです。

[https://github.com/vuejs/petite-vue](https://github.com/vuejs/petite-vue)

どういうものかというと、

- petite-vue is an alternative distribution of Vue optimized for progressive enhancement. It provides the same template syntax and reactivity mental model with standard Vue. However, it is specifically optimized for "sprinkling" small amount of interactions on an existing HTML page rendered by a server framework.

と書かれているように

- 最新環境のブラウザに最適化された軽量のVue実装
- サーバーがで生成された既存ページにちょっと動きをつけるような場合に特に最適化してある

とのことです。

# じゃあどういう場合に最適なのか

- サーバーがで生成された既存ページにちょっと動きをつけるような場合に特に最適化してある

と述べましたが、もうちょっと具体的に説明すると

FE/BEと分けず、サーバー側のテンプレートエンジン等でhtmlを組み立てているようなアプリケーションが該当します。

具体的なアプリケーションとしては、単に社内や部内などで使ってるようなちょっとしたDBの確認ツールなどがこのように作られていることが多いのではないでしょうか？

一般的にこの手のツールは、わざわざSPA化をする必要はなく、インタラクション等も少ないことが多いでしょう。

ただ、若干フォームなどの制御をjsで行いたいような場合に

# 例: SpringBoot + Thymeleafで組まれているフォームにちょっとしたボタンの制御を追加する
サンプルは[こちら](https://github.com/jiko21/petit-vue-sample)

基本的にhtmlのinputフォームはテキストで入力を行うのでボタンで値の変更等はできません。

ただ、ボタンによってフォームの値を変更したりする場合にはJavaScriptが必要だったりします。

実際にpureなjsで書いた場合、以下のようになります。

```jsx
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>let form
</head>
    <body>
        <h1>Petite Vueのサンプル</h1>
        <form action="" method="post">
            <div>
                <label for="name">商品名</label>
                <input type="text" name="name" id="name"/>
            </div>
            <div>
                <label for="count">個数</label>
                <button onclick="decrement(event)">-</button>
                <input type="number" name="count" id="count"/>
                <button onclick="increment(event)">+</button>
            </div>
            <button type="submit">追加</button>
        </form>
        <ul th:each="cart : ${carts}">
            <li>
                商品名: <td th:text="${cart.name}"></td>
                個数: <td th:text="${cart.count}"></td>
            </li>
        </ul>
        <script>
            const count = document.getElementById('count');
            function increment(event) {
                event.preventDefault();
                count.value = (count.value |  0) + 1;
            }

            function decrement(event) {
                event.preventDefault();
                count.value = (count.value |  0) - 1;
            }
        </script>
    </body>
</html>
```

今回の場合なら、あまり複雑ではないですが、

テンプレートエンジンで分割等を行い、同様の制御を行う箇所が増える場合、管理が煩雑になります。

これをpetit-vueで書くと以下のようになります。

```jsx
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
    <body>
        <h1>Petite Vueのサンプル</h1>
        <script src="https://unpkg.com/petite-vue" defer init></script>
        <form action="" method="post">
            <div>
                <label for="name">商品名</label>
                <input type="text" name="name" id="name"/>
            </div>
            <div v-scope="{ count: 0 }">
                <label for="count">個数</label>
                <button @click.prevent="count--">-</button>
                <input type="number" name="count" id="count" v-model="count"/>
                <button @click.prevent="count++">+</button>
            </div>
            <button type="submit">追加</button>
        </form>
        <ul th:each="cart : ${carts}">
            <li>
                商品名: <td th:text="${cart.name}"></td>
                個数: <td th:text="${cart.count}"></td>
            </li>
        </ul>
    </body>
</html>
```

ほぼほぼvueのテンプレートでの記述と同様のもので簡単にボタンの制御を記述できます。

また、`v-scope`という新たなディレクティブがありますが、これにより、同様のコンポーネントを記述しても状態はv-scopeごとに独立になります。

そのため、テンプレートエンジンでのhtmlの分割の際も、簡単に分割ができ、複数箇所での利用も容易となるのです。

# 注意点

これだけ見ると、テンプレートエンジンで実装されているWebアプリケーションをすべてpetit-vueで置き換えたくなるかと思いますが2店ほど注意があります。

- まだまだバグや破壊的変更があること
- そもそも最新のブラウザ機能を利用しており、それに最適化されていること

そのため、社外向けに使用したりする場合はまだおすすめできない面があります。

しかしながら、社内のエンジニア向けツール等で利用するのであれば、バグや破壊的変更はあるものの、最新のブラウザ、という要件は満たしているのでけんとうしてみるのもよいかもしれません。