render函数、createElement函数与vm.$slots

1、render函数、createElement函数

Vue.component('es-header', {
  render: function (createElement) {
    return createElement({
      'div',
      '我是header'
    })
  },
  props: {}
})
// 等同于
Vue.component('es-header', {
  template: '<div>我是dom元素</div>',
  props: {}
})

  createElement 函数的作用就是生成一个 VNode节点(虚拟dom),

  render 函数得到createElement() 创建的 VNode 节点之后,返回给 Vue.js 的 mount 函数,渲染成真实 DOM 节点,并挂载到根节点上。

  就是这么简单 别想多了。

2、vm.$slots

  vm.$slots是一个对象,键名是所有具名slot的名称,加上一个default,而键值则是一个存放VNode节点的数组。

  官方文档:用来访问被 slot 分发的内容。每个具名 slot 有其相应的属性(例如:slot="foo" 中的内容将会在 vm.$slots.foo 中被找到),default 属性则包括了所有没有被包含在具名 slot 中的节点。

  实例:

<blog-post>
  <h1 slot="header">我属于header</h1>
  <h1 slot="header">我也属于header</h1>
  <p>我谁都不属于</p>
  <p slot="footer">我属于footer</p>
  <p>谁来认领我</p>
</blog-post>

  我们看下这个blog-post的示例:在blog-post标签里,元素被我们这样设置:属于header的slot有2个h1;属于footer的slot的有1个<p>,属于不具名slot(会归到default里)的有2个<p>及4个空的VNode节点

   如果像下面这样,指定了render函数的话,就可以手动创建出html标签。

Vue.component('blog-post', {
  render: function (createElement) {
    var header = this.$slots.header
    var body = this.$slots.default
    var footer = this.$slots.footer
    return createElement('div', [
      createElement('header', header),
      createElement('main', body),
      createElement('footer', footer)
    ])
  }
})

  createElement(html标签名,VNode节点数组) 会编译出一个指定的html标签,然后把VNode节点数组里非空的节点编译回原来的html内容。其结果就相当于把原来的那些<blog-post>标签之间的内容根据它们的slot属性,放进了指定的标签里。

posted @ 2019-07-03 13:20  古兰精  阅读(1520)  评论(0编辑  收藏  举报