v-slot 应该注意的细节

slot (2.6.0+ 被废弃但未被移除)
  • 不会解析成节点
  • 同名插槽可以提供多个内容
  • 同名插槽可以多次使用(同v-slot; 2.6.0- 只能用一次)
  • 提供内容的节点, 必须是其组件的一级子节点; 二级节点提供内容的话, 将不被视为插槽内容(同 v-slot). 另外, 普通标签将以普通节点解析; 则内容标签均不解析
  • slot 可以直接作用在子组件上, 但不可以作用于父组件(不同v-slot)
v-slot (2.6.0+ v3.0 之后改用这个)
  • v-slot 只能添加到 或自定义组件上
  • slot 在2.6.0+中已弃用, v-slot 跟 slot 是冲突的, 同名 v-slot 会覆盖 slot 的内容
  • 同名插槽不可以提供多个内容, 后者会覆盖前者
  • 同名插槽可以多次使用(同 slot)
  • template.v-slot 不会解析出节点(跟 slot.slot 类似); 要想解析出节点, 可以在 中使用可解析的子节点
  • 必须是其组件的一级子节点; 二级节点提供内容的话, 将不被视为插槽内容(同 slot; template 标签内容不被解析, 组件未验证), 而且会报错
  • v-slot:default 可以定义默认插槽内容; slot=“default” 则不可以, 或者根本没这个用法(反正是弃用的内容)
  • v-slot 可以直接作用在父组件上, 但不可以作用于子组件(不同slot); 或者说 [子组件 + v-slot] 不会解读为父组件的插槽, 而是子组件自己的插槽
  • v-slot 不可以直接作用在子组件(c3)上; 只能作用于父组件, 此例就是不能作 c1 的插槽, 却可以作 c3 自己的插槽, 而且前提是 c3 仅有一个插槽

上面的内容看不懂没关系,运行代码的代码慢慢摸索

<!DOCTYPE html>
<html>

	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta charset="utf-8">
		<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
		<title>slot 应该注意的细节</title>
		<style>
			.outline,
			.outline * {
				outline: 1px solid red;
				margin: 0;
				padding: 10px 7px;
			}
			
			.slot__default,
			.slot__default * {
				outline: 1px solid green;
			}
		</style>
	</head>

	<body>

		<div id="swq">

			<swq></swq>

		</div>

		<script type="text/x-template" id="swq-template">
			<div class="outline">父节点

				<c1>
					<!--txt.oSlot1-->
					<div slot="oSlot1">div.oSlot1 常规用法</div>

					<!--txt.oSlot2-->
					<slot slot="oSlot2">slot.oSlot2 &lt;slot&gt; 不会解析成节点</slot>

					<!--txt.oSlot3-->
					<slot slot="oSlot3">slot.oSlot3-1; </slot>
					<slot slot="oSlot3">slot.oSlot3-2 同名插槽可以提供多个内容</slot>

					<!--txt.oSlot4-->
					<div slot="oSlot4">div.oSlot4 同名插槽可以多次使用(同v-slot; 2.6.0- 只能用一次)</div>

					<!--txt.oSlot5-->
					<!--<slot slot="oSlot5">div.oSlot5 没有提供内容 或 内容为空</slot>-->

					<!--txt.oSlot6-->
					<slot slot="oSlot6">slot.oSlot6 提供内容的节点, 必须是其组件的一级子节点; 二级节点提供内容的话, 将不被视为插槽内容(同 v-slot)</slot>
					<div>
						<div slot="oSlot6">div.oSlot6 另外, 普通标签将以普通节点解析; &lt;slot&gt; 则内容标签均不解析</div>
						<slot slot="oSlot6">slot.oSlot6 被抛弃的内容</slot>
					</div>

					<!--txt.oSlot7-->
					<c3 slot="oSlot7">c3.oSlot7 slot 可以直接作用在子组件上, 但不可以作用于父组件(不同v-slot)</c3>

					<!------------ slot 与 v-slot 的分界线 ------------>

					<!--txt.vSlot1-->
					<template v-slot:vSlot1>template.v-slot1 2.6.0+ 的玩法;v-slot 只能添加到 &lt;template&gt; 或自定义组件上</template>

					<!--txt.vSlot2-->
					<template v-slot:vSlot2>template.v-slot2 slot 在2.6.0+中已弃用, v-slot 跟 slot 是冲突的, 同名 v-slot 会覆盖 slot 的内容</template>
					<slot slot="vSlot2">slot.vSlot2 被覆盖的内容</slot>

					<!--txt.vSlot3-->
					<template v-slot:vSlot3>template.v-slot3-1 被覆盖的内容</template>
					<template v-slot:vSlot3>template.v-slot3-2 v-slot 同名插槽不可以提供多个内容, 后者会覆盖前者</template>

					<!--txt.vSlot4-->
					<template v-slot:vSlot4>
						<div>template.v-slot4 同名插槽可以多次使用(同 slot)</div>
					</template>

					<!--txt.vSlot5-->
					<template v-slot:vSlot5>
						<div>template.v-slot5 template.v-slot 不会解析出节点(跟 slot.slot 类似); 要想解析出节点, 可以在 &lt;template&gt; 中使用可解析的子节点</div>
					</template>

					<!--txt.vSlot6-->
					<!--<template v-slot:vSlot6>template.v-slot6 没有提供内容 或 内容为空</template>-->

					<!--txt.vSlot7-->
					<div>
						template.v-slot7 被抛弃的内容
						<!--<template v-slot:vSlot7>template.v-slot7 被抛弃的内容</template>-->
					</div>

					<!--txt.vSlot8-->
					<template v-slot:vSlot8="vSlot8">template.v-slot8 作用域插槽 {{ vSlot8.user.firstName }}</template>

					<!--txt.vSlot9-->
					<template v-slot:vSlot9>
						<c3>c3.v-vSlot9 v-slot 可以直接作用在父组件上, 但不可以作用于子组件(不同slot); 或者说 [子组件 + v-slot] 不会解读为父组件的插槽, 而是子组件自己的插槽</c3>
					</template>

				</c1>
				<c2>
					被抛弃的内容
					<!--<slot slot="default">slot.default</slot>-->
					<template v-slot:default>v-slot:default 可以定义默认插槽内容; slot="default" 则不可以, 或者根本没这个用法(反正是弃用的内容)</template>
					被抛弃的内容
				</c2>

				<c3 v-slot:vSlot9>c3.v-vSlot9 v-slot 不可以直接作用在子组件(c3); 只能作用于父组件, 此例就是不能作 c1 的插槽, 却可以作 c3 自己的插槽, 而且前提是 c3 仅有一个插槽</c3>

			</div>
		</script>
		<script type="text/x-template" id="c1-template">
			<div class="c1">子节点
				<div>
					<slot name="oSlot1"></slot>
				</div>
				<div>
					<slot name="oSlot2"></slot>
				</div>
				<div>
					<slot name="oSlot3"></slot>
				</div>
				<div>
					<slot name="oSlot4"></slot>
					<slot name="oSlot4"></slot>
				</div>
				<div>
					<slot name="oSlot5">div.oSlot5 默认内容 [没有提供内容 或 内容为空 时显示]</slot>
				</div>
				<div>
					<slot name="oSlot6"></slot>
				</div>
				<div>
					<slot name="oSlot7"></slot>
				</div>

				<div>---------- slot 与 v-slot 的分界线 ----------</div>

				<div>
					<slot name="vSlot1"></slot>
				</div>
				<div>
					<slot name="vSlot2"></slot>
				</div>
				<div>
					<slot name="vSlot3"></slot>
				</div>
				<div>
					<slot name="vSlot4"></slot>
					<slot name="vSlot4"></slot>
				</div>
				<div>
					<slot name="vSlot5"></slot>
				</div>
				<div>
					<slot name="vSlot6">template.v-slot6 默认内容 [没有提供内容 或 内容为空 时显示]</slot>
				</div>
				<div>
					<slot name="vSlot7">template.v-slot7 必须是其组件的一级子节点; 二级节点提供内容的话, 将不被视为插槽内容(同 slot; template 标签内容不被解析, 组件未验证), 而且会报错</slot>
				</div>
				<div>
					<slot name="vSlot8" v-bind:user="user">{{ user.lastName }}</slot>
				</div>
				<div>
					<slot name="vSlot9"></slot>
				</div>

				<div class="slot__default">
					默认插槽的内容
					<div>
						<slot></slot>
					</div>
				</div>
				<div>c1 end</div>
			</div>
		</script>
		<script type="text/x-template" id="c2-template">
			<div>
				<slot name="default"></slot>
			</div>
		</script>
		<script type="text/x-template" id="c3-template">
			<div>
				<slot name="vSlot9" v-if="$slots.vSlot9"></slot>
				<slot name="default" v-else=""></slot>
			</div>
		</script>
		<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
		<script type="text/javascript">
			var c1 = {
				template: "#c1-template",
				data() {
					return {
						user: {
							firstName: "firstName c1",
							lastName: "lastName c1"
						}
					};
				},
				mounted() {
					console.log("c1")
					console.log(this.$slots)
				},
			}
			var c2 = {
				template: "#c2-template",
				mounted() {
					console.log("c2")
					console.log(this.$slots)
				},
			}
			var c3 = {
				template: "#c3-template",
				mounted() {
					console.log("c3")
					console.log(this.$slots)
				},
			}
			var swq = {
				template: "#swq-template",
				data: function() {
					return {
						user: {
							firstName: "firstName swq",
							lastName: "lastName swq"
						}
					}
				},
				components: {
					c1,
					c2,
					c3,
				},
			};
			var vu = new Vue({
				el: "#swq",
				components: {
					swq: swq,
				},
			})
		</script>
	</body>

</html>

end

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值