简介
插槽作用是将子组件某部分内容交给父组件渲染,在子组件中申明占位符,父组件中使用插槽对应。
语法
在子组件标签中增加标签并添加对应插槽相关属性,未指定属性则当做默认插槽填充至默认插槽。
- \#插槽名称="参数"
- v-slot:插槽名称="参数"
标签上增加属性 slot="插槽明" slot-scope="参数"
- vue2.6之后弃用,下面例子中未使用此语法
参数为子组件传递参数的合集,如需直接访问具体使用可展开"{属性1,属性2……}"
实例
父组件
<template>
<div id="app">
<div class="container">
父容器
<slot-demo>
<div style="background-color: lightblue;">默认插槽</div>
<template #abbreviationSlot>
<div style="background-color: lavender;">
插槽名:abbreviationSlot
</div>
</template>
<template #abbreviationSlotWithArg="args">
<div style="background-color: lightcoral;">
abbreviationSlotWithArg参数:<br/>
propA:{{ args.argPropA }}<br/>
</div>
</template>
<template #abbreviationSlotWithArg2="{argPropA,argPropB}">
<div style="background-color: lightseagreen;">
abbreviationSlotWithArg2参数:<br/>
propA:{{ argPropA }}<br/>
propA:{{ argPropB }}<br/>
</div>
</template>
<template v-slot:keywordSlot>
<div style="background-color: lightgoldenrodyellow;">
插槽名:keywordSlot
</div>
</template>
<template v-slot:keywordSlotWithArgs="args">
<div style="background-color: lightcyan;">
插槽名 keywordSlotWithArgs<br/>
propB:{{ args.argPropB }}
</div>
</template>
</slot-demo>
<slot-jsx>
<template #jsxSlot1="argPropA,argPropB">
<div style="background-color: lightgreen;">
jsxSlot1参数:<br/>
argPropA:{{ argPropA }}<br/>
argPropB:{{ argPropB }}<br/>
</div>
</template>
<template #jsxSlot2="jsxparam">
<div style="background-color: lightgreen;">
jsxSlot2参数:<br/>
argPropA:{{ jsxparam.jsxPropA }}<br/>
argPropB:{{ jsxparam.jsxPropB }}<br/>
</div>
</template>
</slot-jsx>
</div>
</div>
</template>
<script>
import SlotDemo from "./components/slotDemo/SlotDemo";
import SlotJsx from "./components/slotDemo/SlotJsx";
export default {
components: {SlotDemo,SlotJsx},
data() {
return {};
},
mounted() {
}
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.container {
border: 1px black solid;
background: gainsboro;
display: flex;
flex-direction: column;
width: 50%;
}
</style>
模板子组件
文件名称:SlotDemo.vue
<template>
<div style="border: 1px #2c3e50 solid;background-color: papayawhip">
子组件
<slot></slot>
<slot name="abbreviationSlot"></slot>
<slot name="abbreviationSlotWithArg" :argPropA="propA" :argPropB="propB"></slot>
<slot name="abbreviationSlotWithArg2" :argPropA="propA" :argPropB="propB"></slot>
<slot name="keywordSlot" ></slot>
<slot name="keywordSlotWithArgs" :argPropA="propA" :argPropB="propB"></slot>
</div>
</template>
<script>
export default {
name: 'SlotDemo',
data(){
return {
"propA":"属性A",
"propB":"属性B"
};
}
}
</script>
JSX子组件
文件名称:SlotJsx.js
export default {
data () {
return {
"jsxPropA":"jsx属性A",
"jsxPropB":"jsx属性B"
}
},
render() {
return (
<div style={{color:'red'}}>
<div>{this.$slots.jsxSlot1(this.jsxPropA,this.jsxPropB)}</div>
<div>{this.$slots.jsxSlot2({jsxPropA:this.jsxPropA,jsxPropB:this.jsxPropB})}</div>
</div>
);
}
}
通过JSX绑定插槽需要手动合并传递参数如jsxSlot2中参数的传递,不合并则在使用时也需要使用逗号分隔多个参数
其它
在antd-1.x的表格customRender中使用时会发现,插槽参数并没有打包为一个集合,而且也不需要展开参数直接访问即可,但是2.x里就和vue官方的事例用法一致了,找到下面的代码,仅供参考。
customRender传参方式变化。
antd-1.x
components/vc-table/src/TableCell.jsx
//72 行
if (customRender) {
text = customRender(text, record, index, column);
if (isInvalidRenderCellText(text)) {
tdProps.attrs = text.attrs || {};
tdProps.props = text.props || {};
tdProps.class = text.class;
tdProps.style = text.style;
colSpan = tdProps.attrs.colSpan;
rowSpan = tdProps.attrs.rowSpan;
text = text.children;
}
}
antd-2.x
components/vc-table/src/TableCell.jsx
//90 行
if (customRender) {
text = customRender({ text, record, index, column });
if (isInvalidRenderCellText(text)) {
tdProps = text.props || text.attrs || tdProps;
({ colSpan, rowSpan } = tdProps);
text = text.children;
}
}
参考资料
https://cn.vuejs.org/guide/extras/render-function.html#rendering-slots
https://cn.vuejs.org/guide/components/slots.html#slot-content-and-outlet