(This is a further question after this one: In Vue, what is the relationship of template, render, VNode?)
Found createElement()
‘s source code (from here):
function createElement ( context, tag, data, children, normalizationType, alwaysNormalize ) { ... }
Code
main.js: (partly)
import App from './App.vue' new Vue({ el: '#app', render: h => h(App), router })
App.vue:
<template> <div id="content"> <!-- <img src="./assets/logo.png" alt="">--> <router-view></router-view> </div> </template> <script> export default {} </script>
Questions
- A. In
App.vue
,export default {}
will return an empty object, is that correct? - B. In
main.js
:- B-1.
import App from './App.vue'
, will bindApp
to the empty object, is that correct? - B-2.
render: h => h(App)
, if the answer to previous two questions were yes, then hereh
(which is alias of vue’screateElement()
function) will get a single parameter, forcontext
with value as empty object, is that correct? - B-3. But, that doesn’t make much sense, because the template are actually rendered in the browser in my test, it’s not empty.
- B-1.
- C. So, in the code above, how many parameters are passed to
createElement()
, and what is the value of each of them? - D. Which part did I misunderstand about
Vue
orES6
in above description?
Advertisement
Answer
Single-file components, i.e. .vue
files, go through special processing by Vue Loader. See:
https://vue-loader.vuejs.org/#what-is-vue-loader
This will interfere in the export
/import
process so that everything works as expected.
So:
In
App.vue
,export default {}
will return an empty object, is that correct?
It would for a .js
file. But for a .vue
file it won’t, not once it’s been through Vue Loader.
Try console logging the value of App
in main.js
to see what actual gets imported. You should see a render
function (compiled from your template) as well a few other little supporting pieces.
Update
To answer your follow-up question from the comments.
createElement
just creates a VDOM node. It does not create the component instance for that node. Vue further processes the tree of VDOM nodes after they are returned from render
and creates any child component instances it needs. It’ll then call render
on those components to generate the VDOM nodes that they need and so on until everything is rendered.
I’ve created a small example to try to illustrate this. It consists of a parent with two component children. Notice that the logging for creating and rendering the child components does not happen straight away when calling createElement
. Instead it happens after the render
function has returned.
const child = { render (createElement) { console.log('rendering the child') return createElement('div', null, ['hello']) }, created () { console.log('child is created') } } new Vue({ el: '#app', components: { child }, created () { console.log('parent is created') }, render (createElement) { console.log('rendering the parent') const children = [ createElement('child'), createElement('child') ] const root = createElement('div', null, children) console.log('finished calling createElement') return root } })
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script> <div id="app"></div>