24 什么是作用域插槽

插槽

  • 创建组件虚拟节点时,会将组件儿子的虚拟节点保存起来。当初始化组件时,通过插槽属性将儿子进行分类{a:[vnode],b[vnode]}
  • 渲染组件时会拿对应的 slot 属性的节点进行替换操作。(插槽的作用域为父组件)
    <app>
        <div slot="a">xxxx</div>
        <div slot="b">xxxx</div>
    </app> 
    
    slot name="a" 
    slot name="b"

作用域插槽

  • 作用域插槽在解析的时候不会作为组件的孩子节点。会解析成函数,当子组件渲染时,会调用此函数进行渲染。(插槽的作用域为子组件)
  • 普通插槽渲染的作用域是父组件,作用域插槽的渲染作用域是当前子组件。

    // 插槽
    
    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', [_v("node"), _v(" "), _t(_v("vue")])]), _v(" "), _t("default")], 2) 
    }
    //  _t定义在 core/instance/render-helpers/index.js
    // 作用域插槽:
    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) }
Last Updated:
Contributors: leeguooooo