Vue.js 你需要知道的 scopedSlots

栏目: JavaScript · 发布时间: 5年前

内容简介:面试官:Vue如何在 Jsx 中使用 scopedSlots ?自己先想一分钟。早先我在

面试官:Vue如何在 Jsx 中使用 scopedSlots ?

自己先想一分钟。

Vue.js 你需要知道的 scopedSlots

早先我在 Vue.js 你不知道的一些小技巧 一文中简单介绍过 scopedSlots 的使用场景,但不是很详细。群里也有好多同学问关于 scopedSlots 如何使用,当然自己也有点小生疏。今天借此机会重新梳理下,以便日后学习之用。文笔有限,有不对或阐述有误的地方希望留言斧正!

谁可以看?

本文针对有下面情况的同学:

  • 经常使用 Render 函数 和 Jsx 语法开发组件的同学
  • 基础薄弱想进一步提升的同学

你会学到什么?

  • ScopedSlots 的使用

和 slot-scope 的区别?

下面的区别仅仅代表个人理解:

  • 作用相同:都是作用域插槽
  • 场景不同: slot-scope 是模板语法, scopedSlots 则是编程式语法
  • 使用不同:在 <template> 中使用 slot-scope ,在 render() 函数中使用 scopedSlots

Tips:欢迎留言补充~

在渲染函数中如何使用?

假设我们有一个叫 <base-layout> 的组件,它的模板内容如下:

<div class="child-node">
  <slot name="header" :text="headerText"></slot>
  <slot :text="defaultText"></slot>
  <slot name="footer" :text="footerText"></slot>
</div>
复制代码

可以看到, div#child-node 容器中有三个插槽,分别是 header , default , footer 。正常情况下我们会用一个块级标签分别把他们包裹,这里为了简单起见我没有这么做。接下来我们在渲染函数(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>
复制代码

假设我们有一个叫 <scoped-slots> 的父组件。按照模板语法的定义,我们可以使用slot-scope 或者v-slot 获取插值内容,从而达到自定义内容的效果,这里我们使用 Vue@2.6.x 提供的最新语法v-slot 的简写形式,来演示一下如何在父组件中使用:

<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>
复制代码

上面代码输出的结果是:

Vue.js 你需要知道的 scopedSlots

以上只是模板语法的写法,接下来我们在渲染函数(render)中利用scopedSlots 属性重构上面的代码:

<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>
复制代码

同样的,上面代码的输出结果是:

Vue.js 你需要知道的 scopedSlots

以上就是我要讲的 scopedSlots 在 Render 函数中的用法了,你可以狠狠的戳这里查看沙箱中的示例。大家不妨跟着 demo 自己敲一遍体会后自然明白。

在 Jsx 中如何使用?

我们知道,Vue中的大部分语法在 Jsx 中的写法是不一样的,具体看 这里 ,本文不再赘述。但文档中并没有介绍 scopedSlots 的用法,今天我们来看下如何使用。

使用之前我们需要安装解析 Jsx 语法相关的插件:

npm install\
  babel-plugin-syntax-jsx\
  babel-plugin-transform-vue-jsx\
  babel-helper-vue-jsx-merge-props\
  babel-preset-env\
  --save-dev
复制代码

接着配置 .babelrc 文件:

{
  "presets": ["env"],
  "plugins": ["transform-vue-jsx"]
}
复制代码

最后我们使用 Jsx 语法重构上面 render 函数中的代码:

<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>
复制代码

上面代码的输出结果是:

Vue.js 你需要知道的 scopedSlots

你会发现跟 render 函数相比起来还是有些不同的:

以上就是我要讲的 scopedSlots 在 Jsx 中的用法了,你可以狠狠的戳这里查看沙箱中的示例。同样的大家不妨跟着 demo 自己敲一遍体会后自然就明白了。

参考

结尾!

啰嗦了这么多,希望看到的同学或多或少有点收获吧。不对的地方还请留言指正,不胜感激。俗话说, 三人行则必有我师! 希望更多热衷于 Vue 的小伙伴能聚在一起交流技术!下面是我维护的一个Q群,欢迎扫码进群哦,让我们一起交流学习吧。也可以加我个人微信:G911214255 ,备注 掘金 即可。

Vue.js 你需要知道的 scopedSlots

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Hit Refresh

Hit Refresh

Satya Nadella、Greg Shaw / HarperBusiness / 2017-9-26 / USD 20.37

Hit Refresh is about individual change, about the transformation happening inside of Microsoft and the technology that will soon impact all of our lives—the arrival of the most exciting and disruptive......一起来看看 《Hit Refresh》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具