天天看點

關于vue中的元件渲染函數render中的scopedSlots屬性和this.$scopedSlots和this.$slots的疑惑記錄

最近研究了vue的官方文檔,到元件自定義渲染函數時,對第二個屬性對象參數中的scopedSlots不太明白作用是什麼,官網的案例也是一筆帶過,于是連查帶試算是明白了他的作用,這裡記錄一下,希望能幫到遇到相同問題的童鞋.

先說一下函數中的$slots吧,這個用起來很簡單,直接擷取到元件中對應的插槽虛拟節點.this.$slots.插槽名稱.

廢話少說,直接上代碼:

<div id="app">
	<cus-node>
		<template v-slot:content>
			Hello everyone, I'm content slot!
		</template>
	</cus-node>
</div>
<script type="text/javascript">
	Vue.component ("cus-node", {
		render: function (createElement) {
			return createElement ("div", [
				createElement ("h1", "the title"),
                                //這裡直接把上面template中的内容搞到p标簽裡面
				createElement ("p", this.$slots.content)
			]);
		}
	});

	var vm = new Vue ({
		el: "#app"
	});
</script>
           

效果如下:

關于vue中的元件渲染函數render中的scopedSlots屬性和this.$scopedSlots和this.$slots的疑惑記錄

下面來看一下this.$scopedSlots的用法和作用, 個人認為,他的作用是向插槽内傳遞參數,代碼如下:

<div id="app">
		<cus-node>
			<template v-slot:title="datas">
				<div>
					new title: today is a special day <br />
					old title: {{datas.name}}
				</div>
			</template>
			<template v-slot:content>
				he content slot
			</template>
		</cus-node>
	</div>
	<script type="text/javascript">
		Vue.component ("cus-node", {
			render: function (createElement) {
				//切記, 插槽如上面的寫法: v-slot:title="datas"醬紫是無法使用this.$slots擷取的!!!
				console.log (this.$slots.title);//undefined
				return createElement ("div", [
					//把title插槽内容放在h1标簽中,并向title插槽傳遞一個參數name
					createElement ("h1", this.$scopedSlots.title ({
						name: this.name
					})),
					//把content插槽植入新建立的p之中
					createElement ("p", this.$slots.content)
				]);
			},
			data: function () {
				return {
					name: "component data title"
				}
			}
		});

		var vm = new Vue ({
			el: "#app"
		});
	</script>
           

this.$scopedSlots同樣是擷取到插槽内容,比this.$slots厲害的一點是他可以向插槽中傳遞參數,隻需要在調用的時候傳遞一個參數對象就好了.值得注意的是,父元件插入插槽标簽的時候,如果使用屬性v-slot:name="datas"的方式擷取參數時,this.$slots是擷取不到内容的,列印為undefined.

接下來,看一下大Boss:scopedSlots屬性.

上面兩個都是擷取到父元件中建立的插槽,而scopedSlots屬性是建立一個插槽,當在渲染函數中建立自定義元件時,可以使用這個屬性建立一個插槽進去.直接上代碼吧:

<!DOCTYPE html>
<html>
<head>
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<title>vue pro</title>
	<style type="text/css">
	</style>
</head>
<body>
	<div id="app">
		<cus-node2>origin cus-node2</cus-node2>
	</div>
	<script type="text/javascript">
		//定義元件cus-node1
		Vue.component ("cus-node1", {
			//向default插槽傳遞一個text參數,當沒有default插槽時,展示cus-node1 default slot
			template: "<div>this is cus-node1<slot :text='text'>cus-node1 default slot</slot></div>",
			data: function () {
				return {
					text: "I'm cus-node1.text"
				}
			}
		});
		//定義元件cus-node2
		Vue.component ("cus-node2", {
			render: function (createElement) {
				//建立一個cus-node1标簽
				return createElement ("cus-node1", {
					scopedSlots: {
						//建立一個default插槽插入cus-node1中
						default: function (props) {
							//此處props為cus-node1元件向default插槽傳遞的參數
							//插槽内容是一個span标簽,如果cus-node1有對插槽傳遞text參數時,就展示出來;否則展示props.text is null
							return createElement ("span", props.text || "props.text is null");
						}
					}
				});
			}
		});

		var vm = new Vue ({
			el: "#app"
		});
	</script>
</body>
</html>
           

注釋很詳細了,效果如下:

關于vue中的元件渲染函數render中的scopedSlots屬性和this.$scopedSlots和this.$slots的疑惑記錄

可以看到span标簽就是建立出的插槽.賊6!

好了,希望能幫助大家,有錯誤的地方歡迎大家指正.轉載請表明出處,蟹蟹

vue