一、初步了解slot
什么是slot呢?通俗的来说就是“占坑”,举个简单的例子看看
在child.vue中有如下代码
<template>
<div>
<slot></slot>
</div>
</template>
在App.vue中的代码如下:
<template>
<div id="app">
<child>
<h1>我就是占坑的内容啦,哈哈哈~</h1>
</child>
</div>
</template>
结果:

可以看到,在child组件中slot就相当于一个坑,让App组件往里面填充任何你想要填充的东西,这个坑就是专为你准备的,如果这时候将child组件里面的<slot></slot>去掉,那么<h1>我就是占坑的内容啦,哈哈哈~</h1>将会被抛弃。
哇~原来是那么简单的呀,如果此时你有这样的想法,那么我就要残忍的告诉你,你想多了,这只是简单的一个例子,关于插槽,我们还需要了解它的编译作用域、具名插槽、作用域插槽等等。
二、编译作用域
关于编译作用域,我们只需记住一句话:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
三、具名插槽
在实际的开发中,有时候我们需要多个插槽而不是一个,这个时候我们又该怎么做呢?对于这个情况,<slot> 元素有一个特殊的特性:name。这个特性可以用来定义额外的插槽:
child组件代码如下:
<template>
<div>
<header>
<slot name="header"></slot>
</header>
<slot></slot>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
一个不带 name 的 <slot> 出口会带有隐含的名字“default”。
在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:
App组件的代码如下:
<template>
<div id="app">
<child>
<template v-slot:header>
<h1>i am header</h1>
</template>
<template v-slot:default>
<h1>i am default</h1>
</template>
<template v-slot:footer>
<h1>i am footer</h1>
</template>
</child>
</div>
</template>
在 <template> 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot 的 <template> 中的内容都会被视为默认插槽的内容。
然而,如果你希望更明确一些,仍然可以在一个 <template> 中包裹默认插槽的内容,如上面的dafault部分,也可以选择直接写
<h1>i am default</h1>
注意 v-slot 只能添加在一个 <template> 上 (只有一种例外情况),这一点和已经废弃的 slot 特性不同。
四、作用域插槽
有时让插槽内容能够访问子组件中才有的数据是很有用的。如下面的例子,在App组件里面去访问child组件里面的数据
child组件的代码如下:
<template>
<div>
<header>
<slot name="header" :user="user"></slot> //将 user 作为一个 <slot> 元素的特性绑定上去,绑定在 <slot> 元素上的特性被称为插槽 prop
</header>
<slot></slot>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
<script>
export default {
data(){
return {
user:{
firstname:'zhangsan'
}
}
}
}
</script>
App组件的代码如下:
<template>
<div id="app">
<child>
<template v-slot:header="onuser"> //给 v-slot 带一个值来定义我们提供的插槽 prop 的名字,这里的onuser也可以起你们喜欢的名字
<h1>i am header</h1>
<h2>{{ onuser.user.firstname }}</h2>
</template>
<template v-slot:default>
<h1>i am default</h1>
</template>
<template v-slot:footer>
<h1>i am footer</h1>
</template>
</child>
</div>
</template>
五、动态插槽名
动态指令参数也可以用在 v-slot 上,来定义动态的插槽名:
child组件的代码如下:
<template>
<div>
<header>
<slot name="header"></slot>
</header>
<slot></slot>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
App组件的代码如下:
<template>
<div id="app">
<child>
<template v-slot:[dynamicSlotName]>
<h1>i am header</h1>
</template>
<template v-slot:default>
<h1>i am default</h1>
</template>
<template v-slot:footer>
<h1>i am footer</h1>
</template>
</child>
</div>
</template>
export default {
name: 'App',
data(){
return{
dynamicSlotName: 'header' //可以动态改变插槽名
}
}
}
六、具名插槽的缩写
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header
本文详细解析了Vue.js中的插槽(slot)概念,包括基本的占位符使用、编译作用域、具名插槽、作用域插槽、动态插槽名及具名插槽的缩写技巧,帮助开发者掌握组件间复杂内容传递的方法。
6427

被折叠的 条评论
为什么被折叠?



