代码之家  ›  专栏  ›  技术社区  ›  Eric

在Vue中,createElement()实际获得哪些参数?

  •  0
  • Eric  · 技术社区  · 5 年前

    (这是在这一问题之后的另一个问题: In Vue, what is the relationship of template, render, VNode? )

    发现 createElement() 的源代码(来自 here ):

    function createElement (
        context,
        tag,
        data,
        children,
        normalizationType,
        alwaysNormalize
    ) { ... }
    

    代码

    MI. JS: (部分)

    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>
    

    问题

    • a. App.vue , export default {} 会返回一个空对象,对吗?
    • B. main.js :
      • B-1。 import App from './App.vue' 将绑定 App 对空物体来说,是这样吗?
      • B-2。 render: h => h(App) ,如果前两个问题的答案是肯定的,那么这里 h (这是Vue的别名 创建元素() 函数 会得到一个参数,因为 context 值为空对象,对吗?
      • B-3 但是,这没什么意义,因为在我的测试中,模板实际上是在浏览器中呈现的,它不是空的。
    • C. 所以,在上面的代码中,传递给 创建元素() ,它们各自的价值是什么?
    • d. 我误解了哪一部分 Vue ES6 在上述描述中?
    2 回复  |  直到 5 年前
        1
  •  2
  •   skirtle    5 年前

    单个文件组件,即 .vue 文件,通过Vue加载程序进行特殊处理。见:

    https://vue-loader.vuejs.org/#what-is-vue-loader

    这会干扰 export / import 使一切按预期工作的过程。

    所以:

    App.vue , export default {} 会返回一个空对象,对吗?

    如果是一个 .js 文件。但是为了 VUE 文件不会,一旦通过Vue加载程序就不会。

    尝试控制台记录的值 App 在里面 main.js 以查看实际导入的内容。你应该看看 render 函数(从模板编译)以及其他一些小的支持部分。

    更新

    从评论中回答你的后续问题。

    createElement 只需创建一个vdom节点。它不会为该节点创建组件实例。Vue在VDOM节点从返回后进一步处理它们的树 提供 并创建它需要的任何子组件实例。它会打电话来的 提供 在这些组件上生成所需的vdom节点,依此类推,直到呈现所有内容。

    我创建了一个小例子来说明这一点。它由具有两个子组件的父组件组成。注意,在调用 createElement公司 . 相反,它发生在 提供 函数已返回。

    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>
        2
  •  1
  •   Cue    5 年前

    在app.vue中,导出默认值{}将返回一个空对象,对吗?

    不, .vue 文件是 Single File Components 是由 vue-loader .

    b.在main.js中: 小精灵。从“./app.vue”导入应用程序将把应用程序绑定到空对象,对吗?

    不,见上面。

    B-2。render:h=>h(app),如果前面两个问题的答案是yes,那么这里h(Vue的createElement()函数的别名)将得到一个参数,对于值为空对象的上下文,这是正确的吗?

    不。 App 是准备附加到Vue实例的组件。 import App 只是将编译后的文件作为ES6模块导入。

    所以,在上面的代码中,有多少参数被传递给createElement(),它们的值是多少?

    如果你 console.log(App) 您将看到编译后的模块(至少):

    {
      render: function render() {}
      staticRenderFns: Array[0]
      _compiled: true
      beforeCreate: Array[2]
      __file: "/src/App.vue"
      beforeDestroy: Array[1]
      _Ctor: Object
    }
    

    D.在上述描述中,我对Vue或ES6的哪一部分有误解?

    两者。将Vue文件编译为Vue实例。es6模块封装了各种功能,并将这些功能作为库公开给其他javascript文件。