相对于v-slot指令,对大家来说都应该不是很陌生,在 2.6.0 中,vue为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 在新版中的应用,当然vue官方暂时还木有删除老版本中具名插槽和作用域插槽的和 slot-scope,也就是说,还可以用,但是不推荐,在vue-cli 3.0将不能使用
关于v-slot的指令,可以让我们不用再写过多的代码就可以做出slot具名插槽和slot-scope作用域插槽的功能,而且v-slot指令更加强大,提高了代码效率
写个组件模板:
<div>
<h1>slot具名插槽</h1>
<slot name="header">
<h2>插槽的默认值,当没有插入内容时将会渲染该元素</h2>
</slot>
</div>
使用slot将信息插入到插槽中
<自定义组件>
<!-- 注意:组件中如果没有插槽将不能放入任何元素,且插槽在哪里元素就会被插入到那个位置 -->
<div slot="header">
<h1>插入到插槽中的元素需要设置根标签,template或div都可</h1>
</div>
</自定义组件>
如果我们想要插入元素到指定的位置需要借助slot,不然的话将插入失败,当一个组件中具有多个插槽的时候,如果没有借助slot属性会默认把元素插入到没有设置name属性值的slot组件中,当然,会把元素在每一个没有name属性的插槽中都插入一遍
使用v-slot将信息插入到插槽中:
<自定义组件>
<template v-slot:header>
<h1>v-slot需要放置在template中</h1>
</temaplate>
</自定义组件>
如果相比较slot,v-slot在没有设置name属性的插槽出口也会带有隐含的名字“default”,当然这里先埋下伏笔,如果想用v-slot指令不插入具名的插槽,v-slot不带参数就可以
同样的写个组件模板:
<div>
<h1>slot具名插槽</h1>
<slot name="header" :prop_herder="prop_herder_arg">
<h2>插槽的默认值,当没有插入内容时将会渲染该元素</h2>
</slot>
</div>
使用slot-scope将想要传入的值传入到父组件中使用
<自定义组件>
<!-- 注意:slot-scope会把插槽中的属性都传入prop中,如果没有slot默认会是default的属性 -->
<div slot="header" slot-scope="prop">
<h1>插入到插槽中的元素需要设置根标签,template或div都可</h1>
{{prop.prop_herder_arg}}
</div>
</自定义组件>
使用v-slot将想要传入的值传入到父组件中使用
例一:
<自定义组件>
<template v-slot:header>
<h1>v-slot需要放置在template中</h1>
{{header.prop_herder_arg}}
</div>
</自定义组件>
例二:
<自定义组件>
<template v-slot:header="prop">
<!-- 注意: v-slot:header="prop"意思是把具名插槽header的属性赋值给prop,如果不写值则可以使用具名插槽的name来使用属性-->
<h1>v-slot需要放置在template中</h1>
{{prop.prop_herder_arg}}
</div>
</自定义组件>
对于默认插槽,v-slot具有一个单独的缩写语句,不带参数的 v-slot 被假定对应默认插槽
例如:
<!-- 只有默认插槽时,组件的标签才可以被当作插槽的模板来使用,这样我们就可以把 v-slot 直接用在组件上,
不然必须放在template标签内 -->
<自定义组件 v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</自定义组件>
缩写语法:
<自定义组件 v-slot="slotProps">
{{ slotProps.user.firstName }}
</自定义组件>
注意默认插槽的单独写法不能和带参数的v-slot混合使用否则会可能造成作用域混乱:
<!-- 无效,会导致警告 -->
<自定义组件 v-slot="parent">
{{ parent.user.firstName }}
<template v-slot:header="children">
parent is NOT available here
</template>
</自定义组件>
可以使用 ES2015 解构来传入具体的插槽 prop
例如:
<!-- 这样可以把插槽的user属性传过来 -->
<自定义组件 v-slot="{ user }">
{{ user.Name }}
</自定义组件>
还可以给属性起别名
<!-- 这样可以把插槽的user属性传过来 -->
<自定义组件 v-slot="{ user:person }">
{{ person.Name }}
</自定义组件>
<!-- 当没有要接受的属性没有定义时(undefine),我们可以自己设置值 -->
<自定义组件 v-slot="{ user = { Name: '小明' } }">
{{ user.Name }}
</自定义组件>
动态指令参数也可以用在 v-slot 上,来定义动态的插槽名
<自定义标签>
<template v-slot:[slotName]>
...
</template>
</自定义标签>
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header
例如:
<自定义标签>
<template #header>
<h1>Here might be a page title</h1>
</template>
</自定义标签>
同样的,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的
例如:
<自定义标签>
<!-- 会报错 -->
<template #=user>
<h1>{{user.name}}</h1>
</template>
</自定义标签>
如果希望使用缩写,则必须带参数,也就是默认插槽的缩写和这个插槽缩写不能够连用
例如:
<自定义标签>
<!-- 会报错 -->
<template #defalut=user>
<h1>{{user.name}}</h1>
</template>
</自定义标签>