vue作用域插槽

slot插槽

-创建组件虚拟节点时,会将组件的儿子的虚拟节点保存起来。当初始化组件时,通过插槽属性将儿子进行分类 {a:[vnode],b[vnode]}
-渲染组件时会拿对应的slot属性的节点进行替换操作。(插槽的作用域为父组件)
(父组件向子组件通讯方式之一)

源码

const VueTemplateCompiler = require('vue-template-compiler');
let ele = VueTemplateCompiler.compile(`
    <my-component>
        <div slot="header">node</div>
        <div>react</div>
        <div slot="footer">vue</div>
    </my-component>
`)
/** 
with(this) {
    return _c('my-component', [_c('div', {
        attrs: {
            "slot": "header"
        },
        slot: "header"
    }, [_v("node")]), _v(" "), _c('div', [_v("react")]), _v(" "), _c('div', {
        attrs: {
            "slot": "footer"
        },
        slot: "footer"
    }, [_v("vue")])])
}
*/
const VueTemplateCompiler = require('vue-template-compiler');
let ele = VueTemplateCompiler.compile(`
    <div>
        <slot name="header"></slot>
        <slot name="footer"></slot>
        <slot></slot>
    </div>
`);
/**
with(this) {
    return _c('div', [_t("header"), _v(" "), _t("footer"), _v(" "), _t("default")], 2)
}
**/
// _t定义在 core/instance/render-helpers/index.js

作用域插槽

-作用域插槽在解析的时候,不会作为组件的孩子节点。会解析成函数,当子组件渲染时,会调用此函数进行渲染。(插槽的作用域为子组件)
(子组件向父组件通讯方式之一)

使用实例

子组件

<template>
  <div class="child">

    <h3>这里是子组件</h3>
    // 作用域插槽
    <slot  :data="data"></slot>
  </div>
</template>

 export default {
    data: function(){
      return {
        data: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
      }
    }
}

父组件

通过slot-scope来接收子组件的数据,其属性名可自定义。

<template>
  <div class="father">
    <h3>这里是父组件</h3>
    <!--第一次使用:用flex展示数据-->
    <child>
      <template slot-scope="user">
        <div class="tmpl">
          <span v-for="item in user.data">{{item}}</span>
        </div>
      </template>

    </child>

    <!--第二次使用:用列表展示数据-->
    <child>
      <template slot-scope="user">
        <ul>
          <li v-for="item in user.data">{{item}}</li>
        </ul>
      </template>

    </child>

    <!--第三次使用:直接显示数据-->
    <child>
      <template slot-scope="user">
       {{user.data}}
      </template>

    </child>

    <!--第四次使用:不使用其提供的数据, 作用域插槽退变成匿名插槽-->
    <child>
      我就是模板
    </child>
  </div>
</template>

源码

let ele = VueTemplateCompiler.compile(`
    <app>
        <div slot-scope="msg" slot="footer">{{msg.a}}</div>
    </app>
`);
/**
with(this) {
    return _c('app', {
        scopedSlots: _u([{ // 作用域插槽的内容会被渲染成一个函数
            key: "footer",
            fn: function (msg) {
                return _c('div', {}, [_v(_s(msg.a))])
            }
        }])
    })
    }
}
*/
const VueTemplateCompiler = require('vue-template-compiler');
VueTemplateCompiler.compile(`
    <div>
        <slot name="footer" a="1" b="2"></slot>
    </div>
`);
/**
with(this) {
    return _c('div', [_t("footer", null, {
        "a": "1",
        "b": "2"
    })], 2)
}
**/
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。