エッグは、vue3.0関連の知識を学ぶために、最近の意図の前に書き込むようになり、物事を学ぶの精神に沿って、最良の方法は、それの書き込みを模倣することですので、vue3.0の簡易版を書くために自分で行うには、彼らはミニvue3.0と呼ばれる 大きな助けの理解のvue3.0またはvue2.xのコア原則の感触は、それを共有するように。主に、テンプレートのコンパイル、レスポンシブ、コンポーネントのレンダリング処理などが含まれ、リポジトリのアドレスは、、welcome starです!
コンポーネントレンダリングの原則
この記事では、vue3.0のコンポーネント・レンダリングのプロセスを簡単に紹介します。コンポーネント・レンダリングの原理をわかりやすく説明するために、簡単な例と組み合わせて全体のプロセスを説明します。
よりシンプルなレンダリング工程図
より複雑なレンダリング
マウントポイントを
<div id="app"></div>
ルートコンポーネントは次のように定義されます。
const rootComponent = {
 template: `<div class="parent">
 <div :class="data.class">コンポーネントの内容をレンダリングする</div>
 </div>`,
 setup() {
 // reactive 役割は、データの応答性を設定することである
 const data = reactive({
 class: 'demo'
 })
 return {
 data
 }
 }
}
アプリのグローバルコンテキストの作成
まず、App Global Contextを以下のように作成します:
const appContext = {
 mixins: [], // グローバルミキシンを格納する
 components: {}, // グローバルコンポーネントを格納する
 directives: {}, // グローバルコマンドを格納する
}
コンポーネントVNodeを作成します。
const rootVnode = {
 type: rootComponent, // typesubTreeの値には、divやコンポーネントオプションオブジェクトなどの文字列を指定できる。
 props: {},
 children: {},
 component: null, // コンポーネントのインスタンス
 appContext: appContext // グローバルコンテキストを取得する。
}
appContext: グローバル・コンポーネント、命令のグローバル・コンテキスト。コンポーネントを生成するために render 関数が実行されるときに、グローバル・コンポーネント、命令を解析するために使用されます。この例では、コンポーネントのオブジェクトを定義します。
VNodeに従ってルート・コンポーネントをレンダリングします。
コンポーネントインスタンスの作成
コンポーネント VNode に基づいてコンポーネント・インスタンスを初期化します。
 const instance = {
 vnode: rootVnode,// コンポーネントvnode
 parent: null,// 親コンポーネントのインスタンスは、この例ではnullである
 appContext, // グローバルコンテキスト
 type: rootVnode.type, // ノードタイプ
 subTree: null, // コンポーネント内のVNodeツリーをレンダリングする
 render: null,
 proxy: null,
 data: {},
 props: {},
 setupState: {},
 // グローバルコンポーネントと命令を継承する
 components: Object.create(appContext.components), 
 directives: Object.create(appContext.directives),
 ctx: { _: instance }
 }
 
ctx: この ctx 属性は、インスタンス自身を実行コンテキストとしてテンプレートをレンダリングするために使用されます。
コンポーネントインスタンス関連プロパティの初期化
 // テンプレートレンダリングレンダリング関数を設定する
 const Component = instance.type // コンポーネントのオプション
 if (!Component.render && Component.template && compile) {
 // render関数のテンプレートをコンパイルする
 Component.render = compile(Component.template)
 }
 if (!Component.render) {
 throw Error('テンプレートが正しいかどうか確認してほしい。')
 }
 instance.render = Component.render
 // render関数が呼ばれたときに、レンダリングコンテキストを設定する。
 instance.proxy = new Proxy(instance.ctx, {
 get({ _: instance }, key) {
 const { setupState } = instance
 // setupState  
 if (setupState[key] && hasOwn(setupState, key)) {
 return setupState[key]
 }
 },
 set({ _: instance }, key, val) {
 const { setupState } = instance
 if (setupState[key] && hasOwn(setupState, key)) {
 setupState[key] = val
 }
 },
 })
 const { setup } = Component
 // セットアップ関数を呼び出す
 if (setup) {
 const setupResult = setup()
 // ここでは、応答性を設定する
 instance.setupState = reactive(setupResult)
 }
コンパイル関数のコードでは、mini-vue3.0原則の特定の実装にコンパイルします。
この記事の例に基づいて、render、setupStateを取得します。
// _c VNodeを作成する
instance.render = function () { return _c('div', 
 {class: "parent"},
 [_c('div', 
 {class: this.data.class},
 [_c('text', {value: 'コンポーネントの内容をレンダリングする'})]
 )]
 ) 
 }
instance.setupState = {
 dataProxy: {
 class: 'demo'
 }
}
コンポーネントコンテンツのレンダリング
 // レンダリングコンポーネントの効果は、依存関係の収集のための応答関数であり、コンポーネントの更新の更新関数を設定する。
 // effect vue2と同等.x ウォッチャー
 instance.update = effect(function componentEffect() {
 // コンポーネントテンプレートをレンダリング、コンポーネントサブツリーVNodeを取得すると同時に、依存関係のコレクションを完了するには、インスタンス.proxy 実際には、プロキシは自己生成コンポーネントである
 const subTree = (instance.subTree = instance.render.call(instance.proxy, instance.proxy))
 // コンポーネントサブツリーVNodeに従って、コンポーネントの内容をレンダリングする
 mountElement(subTree, container, anchor, instance)
 rootVnode.el = subTree.el
 instance.isMounted = true
 })
// VNodeによると、特定のDom要素を作成する
// container 親 Dom 要素は、この例では id である。="app"  
const mountElement = (vnode, container, anchor, parentComponent) => {
 const { type, props, children } = vnode
 let el
 // テキストノードの特別な処理
 if (type === 'text') {
 el = vnode.el = document.createTextNode(props.value)
 } else {
 el = vnode.el = document.createElement(type)
 // マウントされたサブツリーの再帰的レンダリング
 if (children) {
 mountChildren(vnode.children, el, null, parentComponent)
	}
	// ここでの props は Dom 要素の props である。
 if (props) {
 for (const key in props) {
 el.setAttribute(key, props[key])
 }
 }
 }
 // DOMに挿入する
 document.appendChild(container, el, anchor)
}
この記事の例でルート・コンポーネントから得られるサブツリーは以下の通りです:
{
	"type": "div",
	"props": {
		"class": "parent"
	},
	"children": [{
		"type": "div",
		"props": {
			"class": "before"
		},
		"children": [{
			"type": "text",
			"props": {
				"value": "コンポーネントのレンダリングコンテンツ"
			},
			"component": null,
			"appContext": null
		}],
		"component": null,
		"appContext": null
	}],
	"component": null,
	"appContext": null
}





