面试官:Vue如何在 Jsx 中使用 scopedSlots ?html
本身先想一分钟。vue
早先我在 Vue.js 你不知道的一些小技巧 一文中简单介绍过 scopedSlots
的使用场景,但不是很详细。群里也有好多同窗问关于 scopedSlots
如何使用,固然本身也有点小生疏。今天借此机会从新梳理下,以便往后学习之用。文笔有限,有不对或阐述有误的地方但愿留言斧正!node
本文针对有下面状况的同窗:git
下面的区别仅仅表明我的理解:es6
slot-scope
是模板语法,scopedSlots
则是编程式语法<template>
中使用 slot-scope
,在 render()
函数中使用 scopedSlots
Tips: 欢迎留言补充~github
假设咱们有一个叫 <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)中重构上面的代码:npm
<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>
复制代码
上面代码输出的结果是:json
以上只是模板语法的写法,接下来咱们在渲染函数(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>
复制代码
一样的,上面代码的输出结果是:
以上就是我要讲的 scopedSlots
在 Render 函数中的用法了,你能够狠狠的戳这里查看沙箱中的示例。你们不妨跟着 demo 本身敲一遍体会后天然明白。
咱们知道,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>
复制代码
上面代码的输出结果是:
你会发现跟 render 函数相比起来仍是有些不一样的:
BaseLayout
导入进来能够直接使用h
参数。由于 babel-plugin-transform-vue-jsx@3.4.0+ 帮你自动注入了{...{xxx}}
语法。低版本的 Babel 须要 babel-plugin-transform-object-rest-spread 作兼容性处理以上就是我要讲的 scopedSlots
在 Jsx 中的用法了,你能够狠狠的戳这里查看沙箱中的示例。一样的你们不妨跟着 demo 本身敲一遍体会后天然就明白了。
啰嗦了这么多,但愿看到的同窗或多或少有点收获吧。不对的地方还请留言指正,不胜感激。俗话说,三人行则必有我师! 但愿更多热衷于 Vue 的小伙伴能聚在一块儿交流技术!下面是我维护的一个Q群,欢迎扫码进群哦,让咱们一块儿交流学习吧。也能够加我我的微信:G911214255 ,备注 掘金
便可。