如果对组件不太了解,可以先阅读笔者的这两篇文章,在对组件有了一定的了解之后,在查看本篇文章:
vue进阶(一),深入了解组件,自定义组件
Vue进阶(二)设计高级组件——自定义通知
注意:本篇文章的重点是使用slot开发一个分页组件,如果希望详细了解Vue中slot的用法,可以查看官网文档,同时,如果您在阅读本文中发现错误或者使用不当的地方,还请您指出修正!
1. 什么是插槽
Vue实现了一套内容分发的API,而<slot>
元素就是承载分发内容的出口。
使用<slot>
,我们可以这样写一个组件:
slotTest.vue:
<div>
<span>这个组件中使用了slot元素</span>
<slot></slot>
</div>
使用slotTest.vue:
<current-name>
这个内容将展示在slot的位置
</current-name>
显示效果:
当组件在渲染时,<slot></slot>
将会被替换为“这个内容将展示在slot的位置”。插槽内可以包含任何模板代码,包括 HTML,甚至其他自定义组件:
<current-name>
<div>这个内容将展示在slot的位置</div>
</current-name>
显示结果:
如果slotTest的template
中没有包含一个<slot>
元素,那么,在使用slotTest是,<slot>任意内容</slot>
组件起始标签和结束标签之间的任何内容都会被抛弃。
2. 插槽的具体使用
现在有这样的一个组件,其可以显示一些个人信息。
person.vue:
<template>
<div>
<span>这个组件中使用了slot元素</span>
<div>
firstName:
<slot name="firstName"></slot>
</div>
<div>
lastName:
<slot name="lastName" :last_name="lastname"></slot>
</div>
<div>
sex:
<slot name="sex">男(如果没有使用到这个插槽,那么这就是这个插槽的默认填充)</slot>
</div>
<div>
身高:
<slot name="height">如果使用了这个插槽,那么这里的内容就无效了</slot>
</div>
<div>
体重:
<slot name="weight"></slot>
</div>
<slot/>
</div>
</template>
<script>
export default {
name: "currentName",
data(){
return{
firstName: 'Niall',
lastname: 'August'
}
}
}
</script>
使用person.vue:
<template>
<div>
<person>
<template v-slot:height>180cm</template>
<template v-slot:[slotName]>{
{
firstname}}</template>
<template v-slot:lastName=last>{
{
last.last_name}}</template>
<template #weight>90kg</template>
<template><div>这个内容将展示在default slot的位置</div></template>
</person>
</div>
</template>
<script>
import person from "./components/person";
export default {
name: "Test",
components: {
person
},
data(){
return{
slotName:'firstName',
firstname: 'Jack'
}
}
}
</script>
显示结果:
2.1 具名插槽
在person.vue中,我们设置了多个插槽,为了能够区分不同的插槽,我们为设置了每个插槽的name
属性,一个不带name的slot出口都会带有一个默认名字default
。
当我们在使用组件时,在分发内容上就需要在一个 <template>
元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称,以上面我们分发height时:
<template v-slot:height>180cm</template>
这里我们还需要注意,我们根据slot.name
来分发内容,但是和我们在使用组件时的顺序没有关系,也就是说,我们分发内容的顺序和显示没有关系,显示的顺序由我们的组件中slot的顺序决定。所以,虽然我们在使用person时将<template v-slot:height>180cm</template>
写在了最前面,但是最终的显示内容还是按照了person中slot的顺序来显示的。
在设置了slot.name
之后,<template>
元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot 的 <template>
中的内容都会被视为默认插槽的内容。
也就是上文中的:
<template><div>这个内容将展示在default s