Vue--插槽slot

344 阅读3分钟

插槽的引入

使用场景:

当我们父组件向子组件传值时想传递DOM元素,往往需要使用v-html来实现,如下:

<div id="root">
	<child content = '<p>Dell</p>'></child>
</div>

<script type="text/javascript">
	Vue.component('child',{
		props:['content'],
		template:`<div>
						<p>hello</p>
						<div v-html = "this.content"></div>
				 </div>`
	})

	var vm = new Vue({
		el:'#root',
	})
</script>

上述代码虽然实现了将DOM元素传递给子组件,但是如果想要传递的DOM元素内容过多,且都以属性的形式写在html代码中,会降低代码的可读性

插槽的使用

当向子组件传递DOM元素时,直接在子组件标签内添加DOM元素内容,并在子组件模板内添加<slot></slot>标签即可将DOM元素正常插入

<div id="root1">
	<children>
		<p>哦我的小宝贝</p>
	</children>
</div>

<script type="text/javascript">
	Vue.component('children',{
		template:`<div>
						<slot></slot>
				  </div>`
	})
	var vm = new Vue({
		el:'#root1',
	})
</script>

插槽使用小tips

默认值

若我子组件内没有添加DOM元素具体内容,却想有一个默认值时,直接在slot标签内编写默认值,若添加了DOM元素内容即会替换掉默认内容

<children>
	<p></p>
</children>
<slot>默认值</slot>

具名插槽

当我子组件DOM元素内容不完全由模板中定义的内容提供时,我们需要插槽插入DOM元素,但希望不同的插槽插入不同的DOM元素内容,这时需要给插槽元素起名字

具名插槽也可以拥有默认值

<div id="root1">
	<children>
		<div class="header" slot="header">可可爱爱没有脑袋</div>
		<div class="footer" slot="footer">晃晃可爱的小jiojio</div>
	</children>
</div>

<script type="text/javascript">
	Vue.component('children',{
		template:`<div>
					<slot name="header"></slot>
					<div class = "content">肥胖又笨重的身体</div>
					<slot name="footer"></slot>
			  </div>`
	})

	var vm = new Vue({
		el:'#root1',
	})
</script>

如上代码:给插槽内的两个div起了不同的名字,并在使用插槽时使用name属性备注了对应名字,使得插槽插入相对应部分的DOM内容

效果如下:

作用域插槽

作用域插槽的使用

作用域插槽即为<template></template>,他可以接收子组件向外传递的数据,并存储在slot-scope="props"

使用场景:

  • 子组件中内容做循环
  • 某一部分的DOM结构由外界传递控制

作用域插槽实例分析

例:完成一个对list内容的循环输出,以h1标签的形式

<div id="root2">
	<girl>
		<template slot-scope="props">
		<!-- 使子组件传递的list内的数据存储在props内 -->
			<h1>数数字:{{props.num}}</h1>
		</template><!-- 这是一个作用域插槽 -->
	</girl>
</div>

<script type="text/javascript">
	Vue.component('girl',{
		data:function(){
			return{
				list:[1,2,3,4]
			}
		},
		template:`<div>
					<ul>
						<slot v-for="item of list" :num=item></slot>
					</ul>
				 </div>`
	})//将list内的值传入存储到item中,并将num与item绑定

	var vm = new Vue({
		el:'#root2',
	})
</script>

作用域插槽使用步骤分析:

  1. 在子组件模板中添加<slot>标签,设置循环方式,并将num值与item绑定
  2. 在HTML使用子组件的地方使用<template></template>标签,这就是作用域插槽
  3. 在作用域插槽标签内添加slot-scope="props",调用子组件时会给该组件传入一个值num,将该值存储到props当中,名字可以自定义
  4. 在template标签内填写想要如何循环列表中的内容,我们将传入的值存储在num当中,故使用插值表达式并利用props.num进行调用

数据传递图示: