What you need to know about scopedSlots jsx in Vue

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> , use  slot-scopein  render() function scopedSlots

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  headerdefaultfooter. 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:

 

Guess you like

Origin blog.csdn.net/weixin_43844696/article/details/107639061