DOM指定マウント方式なコンポーネントを作りたい
svelteでcustom elementにしないというのが一番求めているものに近いかもしれない。
この場合はsvelteコンポーネントの挙動通りでpropsをnew
時点で渡せる。
new App({ target, props })
コンポーネントを単体でlibビルドするだけでいい、これが答えっぽい。
build: {
lib: {
entry: path.resolve(__dirname, 'src/Target.svelte'),
name: 'target-element',
}
}
こういうやつ。
import { Player } from 'blendic-svg-player'
const player = new Player('target_id', {
width: '100%',
height: '100%',
})
web componentが登場しているものの、昔ながらのこの方式の使い勝手が捨てがたい。
しかしこの方式を実現するのに適したツールがない(多分)。つまりオプションの渡し方やレンダリングの更新やらは自作しないといけなくなって面倒が多い。
custom elementになっているとattributeとして文字列を渡すことしかできない。
入り組んだデータを渡したい場合はJSON.stringify
が必要だったりと微妙。
attributeで宣言的に渡すのは諦めてscriptからpropsとして渡してもらう前提にすればいいかもしれない。
そしてこの方法ならdom指定マウント方式と似た使用感になるか?
似た使用感になる気もするけどscript側で触る前提のcustom elementに存在意義があるのか問題。
それならやはり最初からdom指定マウント方式になっていた方が分かりやすい。
script制御なしで宣言的にも設置できるよう両対応しておけるならありか。
こういう使い方もできはする。この方向がいいかもしれない。
const myComponent = document.createElement('my-component')
myComponent.foo = [1, 2, 3]
document.body.append(myComponent )
svelte利用のcustom componentだとこういう風にscript側でnew
することもできる(custom element自体がそういう仕様なのか?)。
マウントと同時にprops
を渡せないので、createElement
するのと実質大差ないかもしれない。
.es.jsになっていてもimport
した時点でグローバルにelementが登録されるしで。
Image
なんかもnew
してからsrc
などしていくからHTMLElementというのはそういうものなのかもしれない。
new
時に必須なpropsはない。ただしappend
なりされてレンダリングされるときには必須扱いとなるpropsがある。そのライフサイクルイベントで必須チェックを行えばいい(できるのか?)。
custom element側ではconnectedCallback
がそれにあたるっぽい。
このissue見るにonMounted
がそれに対応してるような気がする。でも実際にそうなっていない気もする。
↑のissueよく見たらロングランしていて結局戻されたような気配ある。まだ揉めているのかもしれない。
実際に試してみてもやはりonMount
時点でpropsは渡っていない。
親側でonMount
よりも前のタイミングでnew
するとなぜかpropsを渡せる。
$: {}
記法でマウント先のelementをtarget
にすればそうなる。
このあたり怪しさ満載でまだ実用的ではない可能性高い。
どちらにせよやはりnew
と同時にpropsを渡すことはできない。
custom elementとはそういうもの。