初めに
ただの自分用メモです
VueのVNodeの実装
hyperscript関数
Vueインスタンス内では、this.$createElement
関数が使える。これは、preactのh関数と同様の仕事をしてくれる。
戻り値としてVNodeを返してくれる。
考察1
element uiのライブラリコード読んで実装していた際に、render関数の第一引数にcreateElement関数(h関数)が渡ってくるけど、this.$createElement
ってなんだろう?って思って、plugin拡張かなと思ったけど、どこからかのバージョンから追加されていた。どのバージョンからは知らないけどソースはここ。
一応Vue.prototype.$createElement
ではアクセスできなくて、instance生成時(create時)にマウントされてるっぽい。
実験したjsfiddle
https://jsfiddle.net/kahirokunn/z7xb1948/2/
実験1
まず、createElement関数は第一引数に 文字列としてタグ名 又は VueComponent クラスを要求する。インスタンスじゃないよ!
createElementの実装ソース
Vueコンポーネントコンストラクタの実験: https://jsfiddle.net/kahirokunn/xer1wup8/5/
タグ名での実験: https://jsfiddle.net/kahirokunn/5yu2f0zg/1/
考察2
render関数では戻り値としてVNodeを返さなければならない。
考察3
vuejs + jsxで同じ様な事を実験してみた。
jsxはもしや、preactではh関数、vuejsではcreateElement関数の糖衣構文なのでは?(template然り)と思い、実際にconsole.logしてみた。なぜかe.hasOwnPropertyがないよってエラーはでるが、まぁ今は無視しよう。
codesandboxでの実験。
https://codesandbox.io/s/n3yjp23mpp
結果、考察はあっていた。
$mountのライフサイクルのコード
web runtimeでの$mountの実装コード
$mountの引数に渡せるElement
MDN: https://developer.mozilla.org/ja/docs/Web/API/Element
Proxyコンポーネント
Vueのコンポーネントをリアクティブに他の所へ飛ばす
まとめ
h関数案外使ってみると使いやすいし、jsxもいいなーって。やっぱコンポーネントをjqueryみたいに特定の所に挿入したいとかって要望が出てくると(主にplugin側の仕事)、template構文だけじゃあ足りなくなってくるのかなーって。
もうちょっと内部アルゴリズムから、実践への適用の経験が増えたら、まとめてちゃんと記事書こうかな。
参考資料
- 仮想DOMの内部の動き https://postd.cc/the-inner-workings-of-virtual-dom
- VNodeについて。 http://mithril-ja.js.org/vnodes.html
- Vue.jsの仮想DOMと差分レンダリングの仕組み1 http://blog.engineer.adways.net/entry/2018/01/19/200000
- Vue.jsの仮想DOMと差分レンダリングの仕組2 http://blog.engineer.adways.net/entry/2018/02/02/183000