slot插槽与slot作用域插槽的区别

前言

不小心接触了vue-template-compiler,所以借助他看一下底层编译出来的数据来探寻vue源码,接触的依然是最外层的源码(o_o)

slot插槽的概念

官方说明

image.png

个人理解
插槽就是在子组件里做定制化内容,当一个复用的组件内有一部分需要针对不同的场景有所差异,且无规律可循时,我们就可以使用<slot></slot>让父组件自定义内容。
这种时候又可以分为两个场景:

  1. 内容与子组件内的数据无关
  2. 内容与子组件内的数据有关
    前者使用普通插槽,后者使用作用域插槽,作用域插槽的作用就是拿到子组件的数据
    具体介绍及使用可参考官方文档
    https://cn.vuejs.org/v2/guide/components-slots.html

区别:

\color{#51839a}{普通插槽} 在父组件初始化期间会编译成文本子节点存起来,在子组件渲染的时候直接将插槽替换成父组件里渲染的节点
\color{#51839a}{作用域插槽} 在父组件初始化期间会编译成一个函数,在子组件初始化的时候执行这个函数生成vnode再进行渲染

\color{#e2abbe}{下面会针对两种插槽看用vue模板编译器对模板编译后的render函数}
了解一下vue的渲染函数的缩写

image.png

_c(createElement),_t(renderSlot),_v(createTextVNode)是下面会常看到的

普通插槽

r1为子组件,r2为父组件

let r1 = VueTemplateCompiler.compile('
    <div>
        <span>hello</span>
        <slot name="header">name</slot>
    </div>
');
let r2 = VueTemplateCompiler.compile('
    <div>
        <span>hello</span>
        <div slot="header">name</div>
    </div>
');

先看父组件渲染结果

r2.render=
'with(this){
    return _c(\'div\',[
        _c(\'span\',[
            _v("hello")
        ]),
        _c(\'div\',{     //在编译时将插槽已经编译成虚拟节点存进[_v("name")]
            attrs:{
                "slot":"header"
            },
            slot:"header"
        },[_v("name")])
    ])
}'

下面是子组件的render函数

r1.render=
'with(this){
    return _c(\'div\',[
        _c(\'span\',[
              _v("hello")
        ]),
        _t("header",[_v("name")])   //在渲染时将header替换成父组件编译完成的[_v("name")]
    ],2)
}'

可以看出父组件在编译组件时就将slot插槽内容调用_c方法编译成节点了,并用_v("name")将文件节点保存,当子组件初始化时,会调_t()方法渲染插槽,会先去父组件中寻找名为"header"的插槽,将"header"替换成_v("name"),渲染过程就是将vnode渲染成真实Dom

作用域插槽

r3为子组件,r4为父组件

let r3 = VueTemplateCompiler.compile('
    <div>
        <span>hello</span>
        <slot name="footer" a="1"></slot>
    </div>
');

let r4 = VueTemplateCompiler.compile('
    <div>
        <span>hello</span>
        <div slot="footer" slot-scope="msg">{{msg.a}}</div>
    </div>
');

先看父组件

r4.render=
'with(this){
    return _c(\'div\',{
        scopedSlots:  
            _u([{
                  key:"footer",
                  fn:function(msg){  //将插槽编译成函数
                      return _c(\'div\',{},[_v(_s(msg.a))])
                  }
            }])
        },
        [_c(\'span\',[_v("hello")])]
  )
}'

子组件

r3.render=
'with(this){
      return _c(\'div\',[
                _c(\'span\',[_v("hello")]),
                _t("footer",null,{a:"1"})
    ],2)
}'

父组件编译时将插槽编译成函数存进数组里,子组件初始化时会根据插槽名"footer"去父组件里找key"footer"的函数并执行,然后生成vnode进行渲染

在vue2.6.0以后,旧版的slot、slot-scope的使用就被废弃了,但是还可以用,推荐统一使用v-slot


我用作用域插槽用的最多的还是在使用组件库的时候,可见大型组件库内部留了很多插槽,便于客户去定制化使用
我们在封装组件的时候也可以去考虑使用哪种插槽能符合更多场景,提高复用性

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • Vue的组件提供了一个非常有用的特性,slot插槽,它让组件的实现变的更加灵活。我们平时在开发组件库的时候,为了让...
    LoveBugs_King阅读 5,249评论 0 0
  • 1、什么是插槽 VUE官方文档的解释: Vue 实现了一套内容分发的 API,将 <slot> 元素作为承载分发内...
    五花漏Z阅读 36,493评论 3 26
  • 探索Vue高阶组件 高阶组件(HOC)是 React 生态系统的常用词汇,React 中代码复用的主要方式就是使用...
    君惜丶阅读 963评论 0 2
  • 探索Vue高阶组件高阶组件(HOC)是 React 生态系统的常用词汇,React 中代码复用的主要方式就是使用高...
    videring阅读 10,614评论 5 30
  • 这是李婷365日写作计划第182天的写作内容 7.29日工作日清: 1.整体了解安得物流 了解了公司的发展历程和组...
    婷婷玉立水墨画阅读 105评论 0 0