Open3

VanJSメモ

山田(ymd)山田(ymd)

配列の van.state で、要素の更新によって配列から除外する

class VanArray {
    constructor(){
        this.a = van.state([]);
        this.f = van.derive(() => {
            const a = this.a.val;

            // 更新の無限ループを避けるために、再代入せずオブジェクトそのものを変更する
            let i = 0;
            while(i < a.length){
                if(a[i].val){ // 個々の要素の変更で再トリガーされる
                    i++;
                }else{
                    a.splice(i, 1);
                }
            }

            // 新しい配列に詰め直して返す。
            // そのまま返すと更新が発火しない。おそらく `Object.is()` で新旧比較している
            return [...a];
        });
    }

    add(v){
        this.a.val = [...this.a.val, v];
    }
};

const App = () => {
    const array = new VanArray();
    
    return () => div(
        button({
            onclick: () => { array.add(van.state(true)); },
        }, "add"),
        ...array.f.val.map(e => button({
            onclick: () => { e.val = false; },
        }, "del")),
    )
};
山田(ymd)山田(ymd)

要素数が変わる配列の van.state をリストアップする場合

  1. .val getter を使う関数を子要素として渡す
  2. 関数の戻り値は、単一の要素である必要があるので、可変個の子要素をdiv や SVG の g 等でラップする
div( // 1
    () => div(...items.val.map(i => div(i))) // 2
)

要素数を変更しない (変更に追従しない) なら、そのまま子要素に渡せば良い。
※ 個々の子要素の変更自体には追従する

div(...items.val.map(i => div(i)))
山田(ymd)山田(ymd)

VanJS v1.4.0 の破壊的なAPI変更

https://github.com/vanjs-org/van/discussions/280

  • van.tagsNS()van.tags() に統合
  • van._()van.derive() に統合
  • van.val(), van.oldVal() の削除。代替関数はなく、ユーザーがスクリプトを書いて対応 [1]
[1]の代替スクリプト
const stateProto = Object.getPrototypeOf(van.state())
const val = v => {
  const protoOfV = Object.getPrototypeOf(v ?? 0)
  if (protoOfV === stateProto) return v.val
  if (protoOfV === Function.prototype) return v()
  return v
}