你也说slot,我也说slot__Vue.js
发布于 3 年前 作者 banyungong 1320 次浏览 来自 分享
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利

slot使用

这一章节主要代用代码解释

  • 匿名slot
  • 具名slot
  • 作用域slot

匿名slot

首先定义两个组件 一个子组件 一个父组件

//子组件  定义slot的地方
    <template>
        <div>
            <p>我是子组件的文字</p>
            <span class="custom-button">我是子组件的按钮</span>
            <slot></slot>
        </div>
    </template>
    <style>
    .custom-button{
        color: #fff;
        width:300px;
        height:60px;
        line-height:60px;
        background-color: #409eff;
        padding: 10px 20px;
        font-size: 14px;
        border-radius:6px;
    }
    </style>


父组件
<template>
	<div id="myvideo">
		<child></child>
	</div>
</template>
<script>
import child from './demo'
	export default{
		data(){
			return {

			}
		},
		components:{
			child
		}
	}
</script>
<style scoped>

</style>

然后我们可以看到浏览器是这样渲染的

<div  id="myvideo">
    <div data-v-be15bc60="">
        <p>我是子组件的文字</p> 
        <span class="custom-button">我是子组件的按钮</span> 
    </div>
</div>

slot 就是允许父组件向子组件插入一些内容的东西 俗称插槽或者是占位 现在我们向子组件插入一段内容

//父组件
<template>
	<div id="myvideo">
		<child><h1>我在这里插入一个H1标签</h1></child>
	</div>
</template>
<script>
import child from './demo'
	export default{
		data(){
			return {

			}
		},
		components:{
			child
		}
	}
</script>
<style scoped>

</style>

这里向子组件插入了一个标签 那么浏览器是如何渲染的呢

<div  id="myvideo">
    <div data-v-be15bc60="">
        <p>我是子组件的文字</p> 
        <span class="custom-button">我是子组件的按钮</span> 
        <h1>我在这里插入一个H1标签</h1>
    </div>
</div>

有人就说了 如果父组件传递很多数据呢 会插入哪一些内容呢 有兴趣的童鞋 可以自己尝试下 结论是 全部被插入

这时候 一些爱思考的童鞋 就问了 如果没有插入内容 可以给slot一个默认值么 ?


很好 能提出这样的问题 说明很善于思考 我们都知道 函数 就有默认值 其实 slot也有默认值 我们可以这么去写

//父组件
<template>
	<div id="myvideo">
		<child></child>
	</div>
</template>
<script>
import child from './demo'
	export default{
		data(){
			return {

			}
		},
		components:{
			child
		}
	}
</script>


//子组件
    <template>
    <div>
        <p>我是子组件的文字</p>
        <span class="custom-button">我是子组件的按钮</span>
        <slot><b>如果没有内容就显示默认的b标签</b></slot>
    </div>
</template>
<style>
.custom-button{
    color: #fff;
    width:300px;
    height:60px;
    line-height:60px;
    background-color: #409eff;
    padding: 10px 20px;
    font-size: 14px;
    border-radius:6px;
}
</style>

浏览器会这样解析

    <div>
        <p>我是子组件的文字</p> 
        <span class="custom-button">我是子组件的按钮</span> <b>如果没有内容就显示默认的b标签</b>
    </div>

其实 slot跟函数的思想是相近的 后面我会总结下 这种思想到底是什么

具名slot

具名slot用处很多 举例来说 一个通用的导航栏组件 有的导航栏带搜索 有的导航栏带返回 有的带分享 这时候就需要具名slot 来在对应的地方插入相应的内容 我举个栗子

//子组件
<template>
    <div>
        <p>我是子组件的文字</p>
        <span class="custom-button">我是子组件的按钮</span>
        <slot name="left"></slot>
        <slot name="right"></slot>
        <slot name="center"></slot>
    </div>
</template>
<style>
.custom-button{
    color: #fff;
    width:300px;
    height:60px;
    line-height:60px;
    background-color: #409eff;
    padding: 10px 20px;
    font-size: 14px;
    border-radius:6px;
}
</style>


//父组件 
<template>
	<div id="myvideo">
		<child>
		    <span slot="left">左侧返回</span>
            <span slot="right">右侧分享</span>
			<span slot="center">中间搜索</span>
			<h1>啥也不是</h1>
		</child>
	</div>
</template>
<script>
import child from './demo'
	export default{
		data(){
			return {

			}
		},
		components:{
			child
		}
	}
</script>

浏览器是如何渲染的呢?

<div>
<p>我是子组件的文字</p> 
    <span class="custom-button">我是子组件的按钮</span> 
    <span>左侧返回</span> 
    <span>右侧分享</span> 
    <span>中间搜索</span>
</div>

具名slot 其实就是具备名字的slot 说明这个slot是属于谁的 子组件定义slot name取为left 换句话意思就是说 这个位置专门为一个叫left的slot准备的 其他人不能占有 这时候父组件 传进来一个<span slot="left">左侧返回</span> 那么子组件 看到这个slot=left就知道把内容安排到name=left的插槽位置 这叫对号入座 父组件还有一个<h1>啥也不是</h1> 子组件不认识啊 那不好意思 我没有位置给你 所以这个<h1></h1>就被舍弃了

其实 想一想 就跟我们买票看电影一样 对号入座 一个个座位就是一个个占位slot 座位号就是名字 你手里的票 决定了你坐在那里 找不到座位号的 对不起 你可能走错播放厅了


作用域slot

看到我标记的红色了吧 说明 这里是一个重点

有时候 我们做一个组件 比如一个列表展示组件

比如说这样的

  • 今天去逛街
  • 看见一东东
  • 上面的豆豆
  • 数也数不清

有人就说了这样的组件很好写啊

一顿操作 写出下面的代码

//子组件
<template>
  <div>
    <ul>
      <li v-for="(item,index) in items" :key="index">{{item}}
      </li>
    </ul>
  </div>
</template>
<script>
export default {
  data () {
    return {
      items:['今天去逛街','看见一东东','上面的豆豆','数也数不清']
    }
  }
}
</script>

·

//父组件
<template>
	<div id="myvideo">
		<child></child>
	</div>
</template>
<script>
import child from './demo'
	export default{
		data(){
			return {

			}
		},
		components:{
			child
		}
	}
</script>

很好 为这位童鞋的才思敏捷鼓掌 但是这时候 另外一个童鞋接到一个需求说 不能按无序列表的形式渲染 需要用一个逗号形式渲染 类似这样

今天去逛街,看见一东东,上面的豆豆,数也数不清

这时候怎么做呢 ?一番抓耳挠腮 咱们的作用域slot就登场了 什么是作用域slot呢?连官网都说的不是那么清晰 其实 作用域slot 其实就是可以传递数据的slot 子组件传递给父组件数据 但是怎么渲染完全看父组件的心情 我们写一下代码

//子组件
<template>
  <div>
    <slot :item="items"></slot>
  </div>
</template>
<script>
export default {
  data () {
    return {
      items:['今天去逛街','看见一东东','上面的豆豆','数也数不清']
    }
  }
}
</script>


//父组件
<template>
	<div id="myvideo">
		<child>
			<template slot-scope="scope">
				<li>
					{{scope.item.join(',')}}
				</li>
			</template>
		</child>
	</div>
</template>
<script>
import child from './demo'
	export default{
		data(){
			return {

			}
		},
		components:{
			child
		}
	}
</script>

三种slot就讲解完毕 其实slot在开发扩展性组件的时候很常用 slot在我看来就跟函数一样 函数有匿名也有非匿名 函数有默认值 slot也有默认值 函数有作用域 slot也有 子组件定义一个slot 类似于定义一个函数 没有name的slot就是匿名函数 父组件的引入子组件 就好比函数的调用 父组件插入的内容 就好比是函数的传参等等 我们都可以去类比 至于slot的作用域怎么理解呢 这个留给你们自己去探索吧 亲自动手你会学到更多

本章如有雷同 纯属虚构 欢迎转载 ^^

END

    版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    作者: 微信公众号_前端享乐园
    原文链接:<a href='https://juejin.im/post/6844904185343770632'>https://juejin.im/post/6844904185343770632</a>
  </p>
回到顶部