使用react context 实现vue插槽slot功能
前端  /  管理员 发布于 4年前   181
首先来看下vue的slot的实现
提供内容渲染的组件
Here might be a page title
A paragraph for the main content.
And another one.
Here's some contact info
最终会渲染出已下架结构
Here might be a page title
A paragraph for the main content.
And another one.
Here's some contact info
言归正传,怎样使用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 () }}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 (这里可能是一个页面标题
主要内容的一个段落。
另一个段落。
这里有一些联系信息
) }}3 其中AddOn类似于上面vue的template,所以下面来实现这个简单的只是用来提供slot标识和children内容的组件AddOn的实现
import React from 'react';import PropTypes from 'prop-types'const AddOn = () => nullAddOn.propTypes = { slot: PropTypes.string }AddOn.defaultTypes = { slot: '$$default' }AddOn.displayName = 'AddOn'export default AddOn4 Slot组件
import React from 'react';import { SlotContext } from './SlotProvider'import PropTypes from 'prop-types'const Slot = ({ name, children }) => { return ({(value) => { const addOnRenderer = value.requestAddOnRenderer(name) return (addOnRenderer && addOnRenderer()) || children || null }} )}Slot.displayName = 'Slot'Slot.propTypes = { name: PropTypes.string }Slot.defaultProps = { name: '$$default' }export default Slot5 接下来就是对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)})` // 用于缓存每个的内容 addOnRenderers = {} requestAddOnRenderer = (name) => { if (!this.addOnRenderers[name]) { return undefined } return () => ( this.addOnRenderers[name] ) } render() { const { children, ...restProps } = this.props if (children) { // 以k-v的方式缓存的内容 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 () } } } export default SlotProviderHoC 6 最终渲染结果
总结
以上所述是小编给大家介绍的使用react context 实现vue插槽slot功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!您可能感兴趣的文章:
- 详解vue2.6插槽更新v-slot用法总结
- vue中slot(插槽)的介绍与使用
- Vue作用域插槽slot-scope实例代码
- 详解vue slot插槽的使用方法
123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..路人 在
php中使用hyperf框架调用讯飞星火大模型实现国内版chatgpt功能示例中评论 教程很详细,如果加个前端chatgpt对话页面就完美了..Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号