vm.$slots

作者: 一只大椰子 | 来源:发表于2017-02-24 11:44 被阅读0次

    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标签里,元素们被这样的设置:

    • 属于名称为headerslot的有2个<h1>
    • 属于名称为footerslot的有1个<p>
    • 属于不具名slot(会归到default里)的有2个<p>

    尝试查看blog-post组件的$slots,得到结果如下:

    vm.$slots

    可以看到:

    • header对应一个长为2的数组,就是刚才那2个<h1>对应的VNode节点。
    • footer对应一个长为1的数组,就是刚才那1个<p>对应的VNode节点。
    • default对应一个长为6的数组,其中有4个是空的VNode节点(产生的原因尚不清楚),2个是刚才没有指定slot属性的<p>对应的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节点数组里非空的VNode节点编译回原来的html内容。其结果就相当于把原来的那些<blog-post>标签之间的内容根据它们的slot属性,放进了指定的标签里。

    刚刚的例子里,最终编译出的html结构如下:

    html结构

    相关文章

      网友评论

        本文标题:vm.$slots

        本文链接:https://www.haomeiwen.com/subject/zvziwttx.html