内容分发(插槽)的学习笔记

217 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

内容分发这个名字是我在《vue.js快速入门》这本书中看到的,学习了vue之后想回顾一下知识,之前只知道插槽这个东西,看书之后才发现这个方法也叫做内容分发,是vue组件化的一个基础的概念,通过内容分发我们可以通过父组件来传递一些决定子组件的内容,或者是混合父组件内容与子组件内容的方式,vue.js参考web component规范,用slot作为原始内容的插槽,下面是学习的一个案例。

1.基础用法

//父组件
<div id="app">
<my-slot>
 <p slot="title">{{ title }}</p>
 <div slot="content">{{ content }}</div>
</my-slot>
</div>
data : {
title : 'This is a title',
content : 'This is the content'
}
//子组件
<div>
 <div class="title">
     <slot name="title"></slot> 
 </div> 
 <div class="content"> 
    <slot name="content"></slot> 
 </div>
</div>

经过slot插槽的使用,父组件通过slot指定要分发的内容,我们这里可以理解为是替换掉子组件中的同名标签,所以我们可以看到替换后的内容是这样的

<div>
 <div class="title">
      <p slot="title">This is a title</p>//内容会被子组件中的data数据替换
 </div> 
 <div class="content"> 
    <div slot="content">{{ content }}</div>
 </div>
</div>

2.插槽的作用域 如果父子组件存在同样的模板数据,那么会在各自的作用域中执行模板数据

//子组件
<my-scope-slot>
<p slot="title">{{ childData }}</p>
</my-scope-slot>
Vue.component('my-scope-slot', {
template : '<div>\
 <p>{{ "child: " + childData }}</p> \
 <slot name="title"></slot> \
 </div>',
data() {
 return {
    childData : 'child scope'
 }
}

});

由于childData存在子组件中,所以应该在子组件的模板中进行编译 通过插槽进行内容分发后的结构为:

<div>
<p>child: child scope</p>
<p slot="title"></p>
</div>

3.默认插槽 父组件在子组件标签中的数据是表示要传给子组件插槽的数据,如果没有声明slot要插到的具体位置,那么子组件可以使用默认插槽的方法来接受父组件中没有slot的内容

<anonymous-slot>
<div id="content">{{ content }}</div>//没有声明slot插槽要插到的地方
<p slot="title">{{ title }}</p>
</anonymous-slot>
Vue.component('anonymous-slot', {
template : '<div>
 <div class="title">
<slot name="title"></slot> 
 </div>
 <div class="content"> 
<slot></slot>//接受没有插槽的传入的内容
 </div> 
</div>',
});

最终效果

<div>
<div class="title">
<p slot="title">This is a title</p>
</div>
<div class="content">
 <div>This is the content</div>
</div>
</div>

如果父组件中是多个没声明

<anonymous-slot>
<div id="content">{{ content }}</div>//没有声明slot插槽要插到的地方
<div id="conten1t">{{ content1 }}</div>//没有声明slot插槽要插到的地方
<p slot="title">{{ title }}</p>
</anonymous-slot>

最终效果

<div>
<div class="title">
<p slot="title">This is a title</p>
</div>
<div class="content">
 <div>This is the content</div>
 <div>This is the content1/div>
</div>
</div>

相同的slot属性

<Test1>
    <div id="content">{{ content }}</div>
    <p slot="title">{{ title }}</p>
    <p slot="title">{{ title1 }}</p>
</Test1>
<div>
<div class="title">
  <slot name="title"></slot> 
</div> 
<div class="content"> 
  <slot></slot> 
</div> 
</div>

由于父组件中存在俩个slot相同的属性,所以在子组件显示的时候,相同属性的slot会当做兄弟组件做展示

<div>
<div class="title">
  <p slot="title">{{ title }}</p>
  <p slot="title1">{{ title1 }}</p>
</div> 
<div class="content"> 
  <slot></slot> 
</div> 
</div>