Vue中slot的介紹與使用(通俗版)

什麼是插槽?

插槽(Slot)是Vue提出來的一個概念,正如名字一樣,插槽用於決定將所攜帶的內容,插入到指定的某個位置,從而使模板分塊,具有模塊化的特質和更大的重用性。插槽顯不顯示、怎樣顯示是由父組件來控制的,而插槽在哪裏顯示就由子組件來進行控制

slot官方介紹

Props:

  • name - string,用於命名插槽。

Usage:

  • 元素作爲組件模板之中的內容分發插槽。 元素自身將被替換。

官方demo

< slot > 元素

Shadow DOM 使用 元素將不同的 DOM 樹組合在一起。Slot 是組件內部的佔位符,用戶可以使用自己的標記來填充。

通過定義一個或多個 slot,您可將外部標記引入到組件的 shadow DOM 中進行渲染。 這相當於您在說“在此處渲染用戶的標記”。

注:Slot 是爲網絡組件創建“聲明性 API”的一種方法。它們混入到用戶的 DOM 中,幫助對整個組件進行渲染,從而將不同的 DOM
樹組合在一起。

個人理解
slot是對組件的擴展,通過slot插槽向組件內部指定位置傳遞內容,通過slot可以父子傳參;是“佔坑”,在組件模板中佔好了位置,當使用該組件標籤時候,組件標籤裏面的內容就會自動填坑(替換組件模板中< slot >位置),當插槽也就是坑< slot name=”mySlot”>有命名時,組件標籤中使用屬性slot=”mySlot”的元素就會替換該對應位置內容;

Slot出現時爲了解決什麼問題呢?

正常情況下,< Child>< span style=”color:red;”>hello world</ span></ Child>在組件標籤Child中的span標籤會被組件模板template內容替換掉,當想讓組件標籤Child中內容傳遞給組件時需要使用slot插槽;

具體怎麼使用slot呢?(重點)

事先準備了一個demo

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Slot</title>
	<style type="text/css">
		.panel{
			width: 400px;
			border: 1px solid #ccc;	
		}
		.panel>*{
			padding: 15px;
			border-bottom: 1px solid #ccc;
		}
		.footer{
			border: none;
		}
	</style>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
	<div id="app">
		<Child></Child>
	</div>

	<template id="child">
		<div>
			<div class="panel">
				<div class="title">這是標題</div>
				<div class="content">這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容</div>
				<div class="footer">這是頁腳</div>
			</div>
		</div>
	</template>
</body>
<script type="text/javascript">
	new Vue({
		el:"#app",
		data:{

		},
		components:{
			Child:{
				template:"#child"
			}
		}
	})
</script>
</html>

在這裏插入圖片描述

單個或多個匿名插槽

	<div id="app">
		<Child>這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容</Child>
	</div>

	<template id="child">
		<div>
			<div class="panel">
				<div class="title">這是標題</div>
				<div class="content">
					<slot></slot>	
				</div>
				<div class="footer">這是頁腳</div>
			</div>
		</div>
	</template>
	結果和初始demo一樣,也可以把內容放到slot標籤裏,不過也就沒啥意義了
	<div id="app">
		<Child>
			這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容<slot  style="color:red;" >這是在slot上添加了樣式</slot>
		</Child>
	</div>

	<template id="child">
		<div>
			<div class="panel">
				<div class="title">這是標題</div>
				<div class="content">
					<slot></slot>
					<slot  style="color:blue;" >這是在slot上添加了樣式</slot>
					<slot name="boboy">我是boboy</slot>					
				</div>
				<div class="footer">這是頁腳</div>
			</div>
		</div>
	</template>
	結果會輸出兩遍--這是內容....+這是slot上添加了樣式+我是boboy

注意:只有匿名插槽,若child標籤有內容,看模板組件中有幾個slot就渲染幾次內容, 且slot標籤添加樣式無效。擁有命名的插槽不能被不含slot屬性的標籤內容替換,會顯示slot的默認值(具名slot具有對應性);

單個或多個具名插槽

	<div id="app">
		<Child>
			<div slot="title">這是頁腳</div>
			<div slot="content">這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容</div>
			<div slot="footer">這是頁腳</div>
			
		</Child>
	</div>

	<template id="child">
		<div>
			<div class="panel">
				<div class="title"><slot name="title"></slot></div>
				<div class="content">
					<slot name="content"></slot>			
				</div>
				<div class="footer"><slot name="footer"></slot></div>
			</div>
		</div>
	</template>

作用域插槽
使用時候子組件標籤中要有標籤,再通過scopeName.childProp就可以調用子組件模板中的childProp綁定的數據,所以作用域插槽是一種子傳父傳參的方式,解決了普通slot在parent中無法訪問child數據的去問題;

作用域插槽代表性的用例是列表組件,允許在parent父組件上對列表項進行自定義顯示,如下該items的所有列表項都可以通過slot定義後傳遞給父組件使用,也就是說數據是相同的,不同的場景頁面可以有不同的展示方式,在這就不多展示了,網上很多可供參考。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Slot</title>
	<style type="text/css">
		.panel{
			width: 400px;
			border: 1px solid #ccc;	
		}
		.panel>*{
			padding: 15px;
			border-bottom: 1px solid #ccc;
		}
		.footer{
			border: none;
		}
	</style>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
	<div id="app">
		<Child>
			<template slot="content" slot-scope="msg"><div>{{msg.data}}</div></template>
		</Child>
	</div>

	<template id="child" >
		<div>
			<div class="panel">
				<div class="title">這是標題</div>
				<div class="content">
					<slot name="content" :data="msg"></slot>			
				</div>
				<div class="footer">這是頁腳</div>
			</div>
		</div>
	</template>
</body>
<script type="text/javascript">
	new Vue({
		el:"#app",
		data:{
		},
		components:{
			Child:{
				template:"#child",
				data(){
					return{
						msg:"這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容這是內容"
					}
					
				}
			}
		}
	})
</script>
</html>

幫助理解:
https://www.jb51.net/article/150676.htm
https://www.jb51.net/article/91976.htm
https://www.jb51.net/article/139214.htm
https://www.jb51.net/article/158639.htm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章