这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战html
这篇文章咱们来说一下v-slot
的使用方法,以及在使用它的时候咱们须要注意的地方。vue
v-slot
结合<slot>
元素提供具名插槽或须要接收 prop 的插槽。v-slot
的简写为#
,只可用于<template>
和组件
中。编程
假定咱们自定义一个组件my-button为:markdown
<button>
<slot>提交</slot>
</button>
复制代码
slot
元素中,咱们能够给默认值(使用组件不传内容的时候会显示默认值,不然默认值会被替换),也能够为空,直接为<slot></slot>
。那么咱们该怎么去使用这个组件呢,以下:app
<my-button>
1. 此处什么都不放,编译后显示默认值
2. 此处能够放字符串
3.此处能够听任何模板代码 或 组件
</my-button>
复制代码
此外,须要咱们注意的是:父级模板里的全部内容都是在父级做用域中编译的;子模板里的全部内容都是在子做用域中编译的。也就是说<my-button></my-button>
包裹的内容不能访问my-button
的做用域。dom
有时咱们须要多个插槽,<slot>
元素有一个特殊的 attribute:name
,咱们可使用这个属性来写你须要的插槽,假定一个组件base-layout
以下:ide
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
复制代码
当属性name不存在的时候,<slot>
出口会带有隐含的名字“default”。那么咱们该怎么使用呢,以下:函数
<base-layout>
//使用 v-slot
<template v-slot:header>
<h1>name为header的插槽</h1>
</template>
//默认插槽能够不用写 v-slot:default ,可是若是用缩写的方式就须要写上 #default
<template #default>
<p>v-slot 时能够不用写</p>
<p>缩写时要加上 #default</p>
</template>
//使用缩写 #
<template #footer>
<p>缩写形式</p>
</template>
</base-layout>
复制代码
为了让插槽内容可以访问子组件中才有的数据,咱们可使用做用于插槽。oop
单个插槽 假定组件todo-list
为:post
<ul>
<li v-for="(item, index) in items">
<slot :item="item" :index="index"></slot>
</li>
</ul>
复制代码
使用时咱们能够有两种方式:
v-slot
做用在组件上<todo-list v-slot="slotProps">
//slotProps 是个对象,包含了绑定在 slot 上除 name 之外的全部属性,例如上述包含了item、index
//slotProps 是个变量,能够取任意名字
//此时不能用template包裹
<span>{{slotProps.item}}</span>
</todo-list>
复制代码
咱们这个例子是默认插槽,若是例子中是具名插槽,好比 slot
的 name="header"
,那咱们要这样使用:
<todo-list v-slot:header="slotProps">
<span>{{slotProps.item}}</span>
</todo-list>
复制代码
v-slot
做用在插槽包裹元素template
上<todo-list>
//必定要用 template 包裹,由于v-slot只能用于 template 或 组件中
<template v-slot="slotProps">
<span>{{slotProps.item}}</span>
</template>
</todo-list>
复制代码
若是组件给了一个具名插槽,使用方法和1相同。
多个插槽
此时v-slot
只能做用在插槽包裹元素template
上,假定组件todo-list
为:
<ul>
<li v-for="(item, index) in items">
<slot name="slot1" :item="item" :index="index"></slot>
<slot name="slot2" :item="item" :index="index"></slot>
<slot name="slot3" :item="item" :index="index"></slot>
</li>
</ul>
复制代码
使用方法以下:
<todo-list>
//slot1
<template v-slot:slot1="slotProps">
<span>{{slotProps.item}}</span>
</template>
//slot2
<template v-slot:slot2="slotProps">
<span>{{slotProps.item}}</span>
</template>
//slot3
<template v-slot:slot3="slotProps">
<span>{{slotProps.item}}</span>
</template>
</todo-list>
复制代码
经过上述内容咱们知道slotProps是个对象,那么咱们在使用的时候能够解构插槽。咱们以1的具名插槽为例:
<todo-list v-slot:header="{item,index}">
<span>{{item}} {{index}}</span>
</todo-list>
或者
<todo-list v-slot:header="{item:x,index:y}">
<span>{{x}} {{y}}</span>
</todo-list>
复制代码
动态指令参数也能够用在 v-slot
上,来定义动态的插槽名,也就是说你能够根据本身的需求,来动态的改变插槽内容,以下:
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>
复制代码
假设你有三个插槽,可是你每次只想展现一个插槽内容,那么咱们就能够用动态插槽来作这件事。
Vue3统一了普通插槽和做用域插槽。当使用渲染函数时,即 h
,将插槽定义为当前节点的子对象,以下:
h(LayoutComponent, {}, {
header: () => h('div', this.header),
content: () => h('div', this.content)
})
复制代码
当你须要以编程方式引用做用域插槽时,Vue3与Vue2的用法是不同的,在Vue3中它们如今被统一到 $slots 选项中,使用以下:
// 2.x 语法
this.$scopedSlots.header
// 3.x 语法
this.$slots.header()
复制代码
使用动态插槽可让咱们在处理同一区域复杂内容切换更灵活。
在Vue3
中<template>
里面能够放代码片断,因此咱们能够在使用插槽的时候,里面能够放不少的dom或组件。
具名插槽和解构插槽Prop均可以让我更好的去完成需求,咱们能够根据本身的状况,去合理的使用它们。