以下の内容はhttps://let.blog.jp/tag/lit-htmlより取得しました。


lit-html のリポジトリが lit に移されてる
以前の URL (https://github.com/Polymer/lit-html) にアクセスすると https://github.com/lit/lit に飛ばされる
Polymer プロジェクトの一部だったのが lit という独自のプロジェクトに分かれたみたい

リポジトリは monorepo になって lit リポジトリの中に lit-html や lit-element が入ってる
こっちで管理されるのは時期メジャーアップデートで lit-html 2.0 と lit-element 3.0 らしい
他にも SSR やスターターキットなどのパッケージもある

lit-html と lit-element はそれぞれパッケージに分かれてるけど lit というパッケージもできてこれだけで lit-html と lit-element の両方が使えるみたい

公式サイトも新しくなってる
https://lit.dev/

公式サイト内のドキュメントと同じ内容かもだけど リポジトリの Wiki には lit2.0 の説明やアップグレードガイドが用意されてる
https://github.com/lit/lit/wiki/About-Lit-2.0
lit-html の分岐処理を見やすくしたい
こんな テンプレートがあって

html`
<div>
<div class="a">
${a()}
</div>
<div class="b">
${b()}
</div>
<div class="c">
${c()}
</div>
</div>
`

c の div の表示条件を追加して useC 変数が true のときのみ表示するようにしたい

html`
<div>
<div class="a">
${a()}
</div>
<div class="b">
${b()}
</div>
${useC
? html`
<div class="c">
${c()}
</div>
`
: null
}
</div>
`

すごく見づらい
かと言って if 文を使うなら 文が書けないといけないので関数の即時実行になって その中で if 文なのでもっと見づらい
{} が増えてネストや行数が増える

別のところで関数定義しておけばシンプルにはなるけど 別のところに書いてるのでテンプレートだけを見て理解できないから微妙
相当複雑でもないならテンプレート中に分岐の条件とかあってほしい

タグの html に条件を指定できて こうなってたら少しましかも

${
htmlIf(useC)`
<div class="c">
${c()}
</div>
`
}

でもこれだと htmlIf の出力が切り替わるだけで c() の実行は常に行われる
表示しないときは表示用のデータがないこともあって エラーが出ないように工夫が必要になってくる
いらないはずの処理のために余計なことはしたくない

となるとやっぱり分岐か関数にして実行を遅延させるか
関数にするとこういう感じ

callIf(useC, () => html`
<div class="c">
${c()}
</div>
`)

条件演算子よりマシな気もするけど なんかイマイチ
全体だとこうなってる

html`
<div>
<div class="a">
${a()}
</div>
<div class="b">
${b()}
</div>
${callIf(useC, () => html`
<div class="c">
${c()}
</div>
`)}
</div>
`

やっぱり一般的なテンプレートみたいな書き方がベスト

html`
<div>
<div class="a">
${a()}
</div>
<div class="b">
${b()}
</div>
{IF useC}
<div class="c">
${c()}
</div>
{/IF}
</div>
`

これが一番見やすい
ただテンプレートリテラルの使用上 埋め込む処理は事前計算されるから実現不可

html`
<div>
<div class="a">
${a()}
</div>
<div class="b">
${b()}
</div>
${IF(useC)}
<div class="c">
${() => c()}
</div>
${ENDIF}
</div>
`

こういう構文にすればできるけど c() のところみたいに関数にしないとダメだし html は自作のものにして特別な事前処理が必要になるからやりたくない

ネストしない意味では hidden みたいな感じで使えるといいんだけどなー

html`
<div>
<div class="a">
${a()}
</div>
<div class="b">
${b()}
</div>
<div if=${useC}>
${c()}
</div>
</div>
`
lit-html で大文字のタグ名・属性名はどうとってるのか
lit-html 風なもの作ったり jsx 代わりのものを作ったとき テンプレートリテラルの文字列から DocumentFragment 作って DOM をパースしてってやったけどタグ名や属性名は大文字でも小文字になる

html`
<Component fooBar=${value}></Component>
`

って書いても DOM になったときには属性名は foobar になってて B が大文字って情報は消えてる
だから lit-html でプロパティに代入するときに .fooBar って書いてもダメかなと考えてたけど普通に使えた

どうやってるのか気になってソースみてみたら 属性名は分割点の直前なので一つ前のパートに対して正規表現で元々の属性名を抽出してた
正規表現は lastAttributeNameRegex って変数名に入ってる
lit-html でリスナの this は eventContext で設定できる
カスタムエレメント中で render にこんなオプション付きで実行

    render() {
return render(this.template, this.shadowRoot, { eventContext: this })
}

eventContext: this を render の 3 つ目の引数に設定しておくと テンプレートの HTML に @XXXX で設定したリスナ実行時の this がそのカスタムエレメントになる
なにも設定しないと this はイベントが起きた要素

    get template() {
return html`
<div @click=${this.onClickDiv}>click me</div>
`
}

onClickDiv(eve) {
console.log(this)
}

こう書いたときの this が他メソッドと同じようにカスタムエレメント自身なので見やすい

テンプレート側でこうも書けるけど見づらいし忘れがちなので render で設定するほうがおすすめ

html`<div @click=${this.onClickDiv.bind(this)}></div>`

この方法だと render のたびに bind で作った新しい関数を設定してるから毎回リスナを再設定することにもなるしね



以上の内容はhttps://let.blog.jp/tag/lit-htmlより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14