Vue插槽(slot)详解

插槽是Vue中很重要的一部分,官方文档的这一小节对初学者还是不太友好…
总结一下,插槽可以分为几点:
1.插槽内可以放置的内容
2.默认插槽
3.具名插槽
4.插槽作用域

一.插槽的内容

一句话:插槽内可以是任意内容。

先看一下下面的代码:声明一个child组件,

如果现在我想在这个组件内放置一些内容,结果会是怎样?

<div id="#app">
	<child></child>
</div>

<script>
Vue.component('child', {
  template: `
    <div></div>
  `
});
let vm = new Vue({
	el: "#app",
	data: {}
})
</script>
<child>Hello World</child>

输出内容还是在组件中的内容,在 <child></child>内写的内容没起作用

我们现在给组件增加一个<slot></slot>插槽

Vue.component('child', {
  template: `
    <div>
      <slot></slot>
    </div>
  `
});

我们在<child></child>内写的Hello World起作用了…
在这里插入图片描述
到现在,我们知道了什么是插槽:

插槽就是Vue实现的一套内容分发的API,将元素作为承载分发内容的出口。

也就是说,没有插槽的情况下在组件标签内写的内容是不起任何作用的,只有在组件中声明了slot元素后,在组件元素内写的内容就会跑到<slot></slot>中。

二.具名插槽

具名插槽,就是给这个插槽起个名字

在组件中,给三个插槽加上名字。

在创建新的组件<parent></parent>内,slot属性对应的内容都会和组件中name一一对应。

而没有名字的,就是默认插槽。

  <parent>
  
    <template slot="header">
      this is header 
    </template>
    
    <template slot="main">
      this is main
    </template>
    
    <template slot="footer">
      this is footer
    </template>
    
  </parent>
Vue.component('parent', {
  template: `
  <div>
  
    <div style="margin-top: 2em;color: red">
      <slot name="header"></slot>
    </div>
    
    <div style="color: orange ">  
        <slot name="main"></slot>
    </div>
    
    <div style="color: yellow">
        <slot name="footer"></slot>
    </div>
    
  </div>
  `
});

在这里插入图片描述

三、默认插槽

不加name就是默认插槽…

四.插槽作用域

先看一个最简单的例子!!

我们给元素上定义一个属性say(随便定义的!),接下来在使用组件child,然后在template元素上添加属性slot-scope!!随便起个名字context

我们把a打印一下发现是 {“say” : “Hello World”},也就是slot上面的属性和值组成的键值对…

这就是作用域插槽!

我可以把组件上的属性/值,在组件元素上使用!!

<child> 
    <template slot-scope="context">
      {{ context }}
    </template>
 </child>
 <script>
 Vue.component('child', {
  template: `
    <div>
      <slot say="Hello World"></slot>
    </div>
  `
});
let vm = new Vue({
  el: '#app',
  data: {}
})
</script>

结果如下:
在这里插入图片描述
我个人觉得Vue中插槽是借鉴了React的设计
react使用构造函数构造组件


<div id="#app"><div>

<script>
function Slot(props) {
	return (
	  <div>
	  	 <h1>{ props.name }</h1>
	  </div>
	)
};
ReactDOM.render(
	<Slot name={ 'slot' }  />,
	document.getElementById('app')
)
</script>

好了,好像扯远了…

我们接着看下面的例子

  <child :lists="lists"> 
    <template slot-scope="context">
      {{ context }}
    </template>
  </child>

<script>
Vue.component('child', {
  props: {
    lists: Array
  },
  template: `
    <div>
      <ul>
        <li v-for="list in lists">
          <slot :frame="list"></slot>
        </li>
      </ul>
    </div>
  `
}) ;
let vm = new Vue({
  el: '#app',
  data: {
    lists: [
      { id: 1, name: 'Vue' },
      { id: 2, name: 'React' },
      { id: 3, name: 'Angular'}
    ]
  }
})
</script>

结果如下:
在这里插入图片描述
更新!!!
刚刚在看官方文档v-slot 指令自 Vue 2.6.0 起被引入,提供更好的支持 slot 和 slot-scope 特性的 API 替代方案。在接下来所有的 2.x 版本中 slot 和 slot-scope 特性仍会被支持,但已经被官方废弃且不会出现在 Vue 3 中。

等待进一步更新。。。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值