Vue.js scopedSlots you need to know
What is the difference between scopedSlots and slot-scope?
- Same effect: both are scoped slots
- Different scenarios:
slot-scope
template grammar,scopedSlots
programmatic grammar - Use different: use in
<template>
, useslot-scope
inrender()
functionscopedSlots
How to use it in the rendering function?
Suppose we have a <base-layout>
component called , and its template content is as follows:
<div class="child-node">
<slot name="header" :text="headerText"></slot>
<slot :text="defaultText"></slot>
<slot name="footer" :text="footerText"></slot>
</div>
复制代码
Can be seen, div#child-node
the container has three slots, respectively header
, default
, footer
. Under normal circumstances, we would wrap them separately with a block-level label, which I did not do here for the sake of simplicity. Next, we refactor the above code in the render function (render):
<script>
export default {
data() {
return {
headerText: "child header text",
defaultText: "child default text",
footerText: "child footer text"
};
},
render(h) {
return h("div", { class: "child-node" }, [
// 相当于 <slot name="header" :text="headerText"></slot>
this.$scopedSlots.header({ text: this.headerText }),
// 相当于 <slot :text="defaultText"></slot>
this.$scopedSlots.default(this.defaultText),
this.$scopedSlots.footer({ text: this.footerText })
]);
}
};
</script>
复制代码
Suppose we have a <scoped-slots>
parent component called . According to the definition of template grammar, we can use slot-scope or v-slot to get the interpolation content, so as to achieve the effect of custom content. Here we use the abbreviation of the latest grammar v-slot provided by [email protected] to demonstrate How to use in the parent component:
<div class="parent-node">
parent content
<base-layout>
<template #header="{ text }">
<p style="color: red">{
{ text }}</p>
</template>
<template #default="text">
<!-- 默认内容是个字符串直接输出 -->
<p style="color: deeppink">{
{ slotProp }}</p>
</template>
<template #footer="{ text }">
<p style="color: orange">{
{ text }}</p>
</template>
</base-layout>
</div>
复制代码
The above is just the way to write the template syntax. Next, we use the scopedSlots property to reconstruct the above code in the render function (render) :
<script>
import BaseLayout from "./base-layout.vue";
export default {
name: "ScopedSlots",
components: {
BaseLayout
},
render(h) {
return h("div", { class: "parent-node" }, [
this.$slots.default,
h("base-layout", {
scopedSlots: {
// 相当于下面代码:
// <template #header="props">
// <p style="color:red">
// {
{ props.text }}
// </p>
// <template>
header: props => {
return h("p", { style: { color: "red" } }, [props.text]);
},
default: props => {
return h("p", { style: { color: "deeppink" } }, [props]);
},
footer: props => {
return h("p", { style: { color: "orange" } }, [props.text]);
}
}
})
]);
}
};
</script>
复制代码
How to use it in Jsx?
We know that most of the grammars in Vue are written differently in Jsx. See here for details, and I won't repeat them in this article. But the document does not introduce the usage of scopedSlots. Today we will look at how to use it.
Before using, we need to install plugins related to parsing Jsx syntax:
npm install\
babel-plugin-syntax-jsx\
babel-plugin-transform-vue-jsx\
babel-helper-vue-jsx-merge-props\
babel-preset-env\
--save-dev
复制代码
Then the configuration .babelrc
file:
{
"presets": ["env"],
"plugins": ["transform-vue-jsx"]
}
复制代码
Finally, we use Jsx syntax to reconstruct the code in the render function above:
<script>
import BaseLayout from "./base-layout.vue";
export default {
name: "ScopedSlots",
render() {
return (
<div class="parent-node">
parent content
<BaseLayout
{...{
scopedSlots: {
header: props => {
return <p style={
{ color: "red" }}>{props.text}</p>;
},
default: props => {
return <p style={
{ color: "deeppink" }}>{props}</p>;
},
footer: props => {
return <p style={
{ color: "orange" }}>{props.text}</p>;
}
}
}}
/>
</div>
);
}
};
</script>
复制代码
You will find that there are still some differences compared to the render function:
BaseLayout
Imported can be used directly- The render function omits the
h
parameters. Because [email protected]+ helped you automatically inject - Use the destructuring assignment syntax of the spread operator
{...{xxx}}
. The lower version of Babel needs babel-plugin-transform-object-rest-spread for compatibility processing