8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HTMLにちょい足しでリアクティブ機能が!?

8
Posted at

HTMLにリアクティブな状態管理があったら? — @wcstack/state 入門

ちょっと想像してみてください。

Reactを使わず、Vueも使わず、ビルドツールも設定ファイルも何もなく、HTMLファイルひとつで「値が変わったらDOMが自動で更新される」世界。

それが @wcstack/state のコンセプトです。HTMLにちょい足しでリアクティブ機能が付いてくるお手軽ライブラリ、CDN一発で始められます。


CDN一行で始まる

index.html
<script type="module" src="https://esm.run/@wcstack/state/auto"></script>

これだけです。npm installvite.config.js も不要。HTMLファイルをテキストエディタで書いて、ブラウザで開けばそのまま動きます。


基本の形

状態は <wcs-state> タグの中に書きます。

index.html
<wcs-state>
  <script type="module">
    export default {
      count: 0,
      increment() { this.count += 1; }
    };
  </script>
</wcs-state>

<p data-wcs="textContent: count"></p>
<button data-wcs="onclick: increment">+1</button>

data-wcs 属性でDOMと状態を繋ぐ。count が変わればテキストが自動で更新される。それだけです。

value にバインドすれば入力欄との双方向も自動で有効になります。{{ name }}のようにテキストを埋め込むこともできます。

index.html
<input data-wcs="value: name">
<p>こんにちは、{{ name }}さん!</p>

ルールはひとつ

状態をリアクティブに更新するルールは一つだけです。パスに直接代入する。

index.html
this.count = 10;            // ✅ DOMが更新される
this["user.name"] = "Bob";  // ✅ DOMが更新される

this.user.name = "Bob";     // ❌ 検知されない

this.user.name のように書くと、Proxyが変更を捕捉できません。ドット区切りのパス文字列で代入することが、このライブラリの唯一のルールです。

配列の更新も同様で、pushsplice は使えません。代わりに非破壊メソッドで新しい配列をパスに代入します。

index.html
// ✅
this.items = this.items.concat({ text: "新しいアイテム" });
this.items = this.items.toSpliced(index, 1);

// ❌
this.items.push({ text: "新しいアイテム" });

リストの表示とワイルドカード

リストの繰り返しは <template> タグで書きます。

index.html
<template data-wcs="for: users">
  <div data-wcs="textContent: users.*.name"></div>
</template>

users.*.name* が「現在の要素」を指します。ループが回るたびに * が自動的に正しいインデックスに解決されるため、手動でインデックスを管理する必要はありません。

ループの中では .name という省略記法も使えます。

index.html
<template data-wcs="for: users">
  <div data-wcs="textContent: .name"></div>  <!-- users.*.name と同じ -->
</template>

条件分岐

if / elseif / else<template> で書けます。

index.html
<template data-wcs="if: count|gt(0)">
  <p>カウントは正の値です。</p>
</template>
<template data-wcs="else:">
  <p>ゼロ以下です。</p>
</template>

|gt(0) はフィルタで、「0より大きいか」を判定します。条件が偽のとき、要素はDOMから物理的に取り除かれます(display: none ではありません)。フィルタは組み込みで40種類用意されています。


他のライブラリとの違い

Alpine.jsのように既存のDOM要素に状態を埋め込むアプローチとは異なり、<wcs-state> は状態を独立したタグとして分離します。状態とUIの結合点はパス文字列だけで、両者はお互いの実装を知りません。

ReactやVueのような仮想DOMも持ちません。ES Proxyによってパス単位で変更を検知し、影響する要素だけを直接更新します。

シンプルなHTMLページや、フレームワークなしで動かしたい場面にフィットするライブラリです。


まとめ

特徴 内容
インストール CDN一行のみ
状態の置き場所 <wcs-state> タグ
DOM連携 data-wcs 属性
更新ルール パス代入のみ
ループ <template data-wcs="for: ...">
条件分岐 <template data-wcs="if: ...">
依存 ゼロ

ビルドレスでリアクティブなUIが書きたい方は、ぜひ試してみてください。

8
5
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
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?