摘要:首先来看下的的实现组件,具名插槽定义以及默认插槽提供内容渲染的组件最终会渲染出已下架结构言归正传,怎样使用的实现的这一功能呢首先确认下组件的结构对此结构输出具体内容的组件这里可能是一个页面标题主要内容的一个段落。
首先来看下vue的slot的实现
提供内容渲染的组件
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组件的结构Here might be a page title
A paragraph for the main content.
And another one.
import React, { Component } from "react"; import SlotProvider from "./SlotProvider" import Slot from "./Slot" class AppLayout extends Component { static displayName = "AppLayout" render () { return (2 对此结构输出具体内容的组件) } } export default SlotProvider(AppLayout)
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 = () => null AddOn.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 (5 接下来就是对Slot进行解析的HOC SlotProvider组件了{(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 Slot
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)})` // 用于缓存每个6 最终渲染结果的内容 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
摘抄:张国钰
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/54208.html
摘要:首先来看下的的实现组件,具名插槽定义以及默认插槽提供内容渲染的组件最终会渲染出已下架结构言归正传,怎样使用的实现的这一功能呢首先确认下组件的结构对此结构输出具体内容的组件这里可能是一个页面标题主要内容的一个段落。 首先来看下vue的slot的实现 组件,具名插槽name定义以及默认插槽 提供内容渲染的组件 ...
摘要:案例持续触发事件时,并不立即执行函数,当毫秒内没有触发事件时,才会延时触发一次函数。也以函数形式暴露普通插槽。这样的场景组件用函数式组件是非常方便的。相关阅读函数式组件自定义指令前言 有echarts使用经验的同学可能遇到过这样的场景,在window.onresize事件回调里触发echartsBox.resize()方法来达到重绘的目的,resize事件是连续触发的这意味着echarts...
摘要:假如以的作用域链作为类比,组件提供的对象其实就好比一个提供给子组件访问的作用域,而对象的属性可以看成作用域上的活动对象。所以,我借鉴了作用域链的思路,把当成是组件的作用域来使用。 前言 Context被翻译为上下文,在编程领域,这是一个经常会接触到的概念,React中也有。 在React的官方文档中,Context被归类为高级部分(Advanced),属于React的高级API,但官方...
摘要:结合我们的例子,子组件则会生成以下代码到目前为止,对于普通插槽和作用域插槽已经谈的差不多了。下面我们将仔细谈谈这块的内容。在看具体实现逻辑前,我们先通过一个例子来先了解下其基本用法然后进行使用页面展示效果如下看着好。本篇文章是细谈 vue 系列第二篇了,上篇我们已经细谈了 vue 的核心之一 vdom,传送门 今天我们将分析我们经常使用的 vue 功能 slot 是如何设计和实现的,本文将围...
阅读 2620·2021-11-25 09:43
阅读 2724·2021-11-04 16:09
阅读 1634·2021-10-12 10:13
阅读 880·2021-09-29 09:35
阅读 879·2021-08-03 14:03
阅读 1777·2019-08-30 15:55
阅读 2988·2019-08-28 18:14
阅读 3489·2019-08-26 13:43