<slot></slot>
对组件的扩展,通过插槽向组件内部指定位置传递内容,通过slot可以父子传参
填空
<!-- 这是子组件哦-->
<div class="child">
<h2>Child的标题</h2>
<slot>空</slot>
</div>
<!-- 这是父组件哦-->
<div class="father">
<h1>Father的标题</h1>
<Child>
内容
</Child>
</div>
看一下运行效果:
Father的标题
Child的标题
内容
**slot 与 props 的区别:**通过props属性,父组件可以向子组件传递属性、方法,可是父组件不能通过属性传递带标签的内容、甚至是组件,而插槽可以。
<!-- 这是父组件哦-->
<div class="father">
<h1>Father的标题</h1>
<Child>
<button>我是一个按钮</button> <!-- 带标签的内容-->
<Child2></Child2> <!-- 组件-->
</Child>
</div>
插槽的使用
匿名插槽(单个插槽、默认插槽)
-
匿名插槽就是没有设置name属性的插槽。
-
可以放置在组件的任意位置。
-
一个组件中只能有一个该类插槽。
-
作为找不到匹配的内容片段时的备用插槽。
-
匿名插槽只能作为没有slot属性的元素的插槽。
<div class="child">
<h1>子组件</h1>
<slot name="head">头部默认值</slot>
<slot name="body">主体默认值</slot>
<slot>这是个匿名插槽(没有name属性),这串字符是匿名插槽的默认值。</slot>
</div>
<div class="parent">
<h1>父组件</h1>
<child>
<p slot="body">我是主体</p>
<p>我是其他内容</p>
<p slot="footer">我是尾巴</p>
</child>
</div>
运行效果:
父组件
子组件
头部默认值 (head的默认值被渲染:默认值只会在没有提供内容的时候被渲染。)
我是主体 (body的默认值被覆盖)
我是其他内容 (名插槽的默认值被覆盖)
<p slot="footer">我是尾巴</p>—— 被丢弃了,因为子组件中没有name="footer"的插槽与之匹配。
如果子组件中的匿名插槽不存在,则
我是其他内容
也会被丢弃。具名插槽
-
意思就是具有名字的插槽,名字通过属性name来定义。
-
一个组件中可以有很多具名插槽,出现在不同的位置。
<!-- <base-layout>组件-->
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
我们可以在一个 <template>
元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供插槽名称:
<base-layout>
<template v-slot:header>
<h1>我是头header</h1>
</template>
<p>我是main的内容111</p>
<p>我也是main的内容222</p>
<template v-slot:footer>
<p>我是footer</p>
</template>
</base-layout>
任何没有被包裹在带有 v-slot 的 template 中的内容都会被视为默认插槽的内容。
一个不带 name 的 slot 插槽会带有隐含的名字 default 。如果你希望更明确一些,可以在一个 <template>
中包裹默认插槽的内容:
<base-layout>
<template v-slot:header>
<h1>我是头header</h1>
</template>
<template v-slot:default>
<p>我是main的内容111</p>
<p>我也是main的内容222</p>
</template>
<template v-slot:footer>
<p>我是footer</p>
</template>
</base-layout>
两种写法的渲染效果是一样的:
<div class="container">
<header>
<h1>我是头header</h1>
</header>
<main>
<p>我是main的内容111</p>
<p>我也是main的内容222</p>
</main>
<footer>
<p>我是footer</p>
</footer>
</div>
作用域插槽
<!-- <Child> 组件: -->
<template>
<div>
<h1>hey,我是组件Child的标题</h1>
<slot></slot>
</div>
</template>
<script>
export default {
data() {
return{
childUser:{Name:"Tom",Age:23}
}
}
</script>
当使用Child组件时,想访问Child中的数据childUser并且将其展示在插槽的位置:
<!-- 这是父组件<Father>哦-->
<div>
<h1>hey,我是父组件Father的标题</h1>
<Child>
{{childUser.Name}},
{{childUser.Age}}
</Child>
</div>
上述代码不会正常工作
因为父级模板里的所有内容都是在父级作用域中编译的;子级模板里的所有内容都是在子作用域中编译的。
只有 <Child>
组件可以访问到 childUser,而我们提供的内容【{{childUser.Name}}, {{childUser.Age}}】是在父级<Father>
渲染的。
为了让 childUser 在父级的插槽内容中可用,需要把 childUser 从 <Child>
子级作用域传递到 <Father>
父级作用域。
将 childUser 作为 元素的一个属性绑定上去:
<template>
<div>
<h1>hey,我是组件Child的标题</h1>
<slot v-bind:childData="childUser"></slot>
</div>
</template>
<script>
export default {
data() {
return{
childUser:{Name:"Tom",Age:23}
}
}
</script>
绑定在 元素上的 属性childData被称为插槽 prop。
现在在父级作用域中,我们可以使用带值的 v-slot 来定义 插槽 prop 的名字:
<!-- 这是父组件哦-->
<div>
<h1>hey,我是父组件Father的标题</h1>
<Child>
<template v-slot:default="slotProps">
{{ slotProps.childData.Name}}
{{ slotProps.childData.Age}}
</template>
</Child>
</div>
多个插槽
<Child >
<template v-slot:default="slotProps">
{{ slotProps.childData.Name }}
</template>
<template v-slot:other="otherSlotProps">
...
</template>
</Child>
v-slot
v-slot
指令自 Vue 2.6.0 起被引入,提供更好的支持 slot 和 slot-scope 的 API 替代方案。
在一个 <template>
元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称。
匿名插槽&具名插槽&作用域插槽看上面的例子
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把 v-slot: 替换为字符 #。
例如 v-slot:header 可以被重写为 #header,和其它指令一样,该缩写只在其有参数的时候才可用。
如果你希望使用缩写的话,你必须始终以明确插槽名取而代之,default不可以省略:
<Child #default="{ childData}">
{{ childData.Name }}
</Child >