DDR爱好者之家 Design By 杰米
首先来看下vue的slot的实现
<base-layout>组件,具名插槽name定义以及默认插槽
<div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div> <template>
提供内容渲染的组件
<base-layout> <template v-slot:header> <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> <p>And another one.</p> <template v-slot:footer> <p>Here's some contact info</p> </template> </base-layout>
最终会渲染出已下架结构
<base-layout> <template v-slot:header> <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> <p>And another one.</p> <template v-slot:footer> <p>Here's some contact info</p> </template> </base-layout>
言归正传,怎样使用react的context实现vue的这一功能呢
1 首先确认下layout组件的结构
import React, { Component } from 'react'; import SlotProvider from './SlotProvider' import Slot from './Slot' class AppLayout extends Component { static displayName = 'AppLayout' render () { return ( <div className="container"> <header> <Slot name="header"></Slot> </header> <main> <Slot></Slot> </main> <footer> <Slot name="footer"></Slot> </footer> </div> ) } } export default SlotProvider(AppLayout)
2 对此结构输出具体内容的组件
import React, { Component } from 'react'; import AppLayout from './AppLayout' import AddOn from './AddOn' export default class App extends Component { render() { return ( <AppLayout> <AddOn slot="header"> <h1>这里可能是一个页面标题</h1> </AddOn> <AddOn> <p>主要内容的一个段落。</p> <p>另一个段落。</p> </AddOn> <AddOn slot="footer"> <p>这里有一些联系信息</p> </AddOn> </AppLayout> ) } }
3 其中AddOn类似于上面vue的template,所以下面来实现这个简单的只是用来提供slot标识和children内容的组件AddOn的实现
import React from 'react'; import PropTypes from 'prop-types' const AddOn = () => null AddOn.propTypes = { slot: PropTypes.string } AddOn.defaultTypes = { slot: '$$default' } AddOn.displayName = 'AddOn' export default AddOn
4 Slot组件
import React from 'react'; import { SlotContext } from './SlotProvider' import PropTypes from 'prop-types' const Slot = ({ name, children }) => { return ( <SlotContext.Consumer> {(value) => { const addOnRenderer = value.requestAddOnRenderer(name) return (addOnRenderer && addOnRenderer()) || children || null }} </SlotContext.Consumer> ) } Slot.displayName = 'Slot' Slot.propTypes = { name: PropTypes.string } Slot.defaultProps = { name: '$$default' } export default Slot
5 接下来就是对Slot进行解析的HOC SlotProvider组件了
import React, { Component } from 'react'; function getDisplayName(component) { return component.displayName || component.name || 'component' } export const SlotContext = React.createContext({ requestAddOnRenderer: () => { } }) const SlotProviderHoC = (WrappedComponent) => { return class extends Component { static displayName = `SlotProvider(${getDisplayName(WrappedComponent)})` // 用于缓存每个<AddOn />的内容 addOnRenderers = {} requestAddOnRenderer = (name) => { if (!this.addOnRenderers[name]) { return undefined } return () => ( this.addOnRenderers[name] ) } render() { const { children, ...restProps } = this.props if (children) { // 以k-v的方式缓存<AddOn />的内容 const arr = React.Children.toArray(children) const nameChecked = [] this.addOnRenderers = {} arr.forEach(item => { const itemType = item.type console.log('itemType',itemType) if (item.type.displayName === 'AddOn') { const slotName = item.props.slot || '$$default' // 确保内容唯一性 if (nameChecked.findIndex(item => item === slotName) !== -1) { throw new Error(`Slot(${slotName}) has been occupied`) } this.addOnRenderers[slotName] = item.props.children nameChecked.push(slotName) } }) } return ( <SlotContext.Provider value={{ requestAddOnRenderer: this.requestAddOnRenderer }}> <WrappedComponent {...restProps} /> </SlotContext.Provider > ) } } } export default SlotProviderHoC
6 最终渲染结果
总结
以上所述是小编给大家介绍的使用react context 实现vue插槽slot功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
DDR爱好者之家 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
DDR爱好者之家 Design By 杰米
暂无评论...
更新日志
2024年11月25日
2024年11月25日
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]