news 2026/11/3 2:46:06

前端基础之《React(16)—Modal组件封装》

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
前端基础之《React(16)—Modal组件封装》

一、组件化

1、使用组合思想来实现组件化
在react中组件的复用,是组合还是继承?是组合

2、一个正常的组件有哪些东西

3、字段校验
(1)一般校验两种:必填非必填,是什么类型
(2)PropTypes.element(react元素类型):包含jsx、string、null、undifined
(3)必填属性使用isRequired来约束,非必填属性一般给默认值
(4)所有属性都要给类型约束
(5)PropTypes.oneOf(['primary', 'danger', 'info']):取值是其中之一
(6)oneOfType([PropTypes.bool,PropTypes.instanceOf(Array), PropTypes.element]):取值类型是其中之一
(7)PropTypes.node:比PropTypes.element范围更广
(8)指定user这个对象类型的结构
user: PropTypes.shape({
name: PropTypes.string.isRequired,
age: PropTypes.number,
})

4、函数命名规则
(1)如果一个函数参与视图渲染,前面不加on
(2)如果一个函数跟事件有关,前面加on

5、什么是render props
(1)在封装React组件时,如果一个props属性其值是函数类型并返回JSX视图结果,那么这个props属性就是render props,即,可以参与组件的视图渲染。例如:<Modal footer={()=>{xxx}}。这个footer属性就被称为render props
(2)render props在组件化中,用的非常多

6、{...props}
属性穿透
父组件给的props,直接给到子组件

7、Protal
(1)protal提供了一种将子节点渲染到存在于父组件以外的DOM节点的方案,比如我要将弹窗挂载到body上
(2)可以把一段JSX结构,“穿梭”插入到父级节点中的一种能力
语法:ReactDOM.createPortal(<jsx/>,dom节点)

8、到底什么是组合,怎么理解组合
组合是一种设计模式,它是React组件化的基础

9、如何封装组件
第一步,根据UI视图拆解结构,得到一个一个可独立封装的小组件
第二步,把这些独立的小部件分别封装
第三步,再使用props把这些小组件串联起来

二、例子

import '@/assets/modal.scss'; import PropTypes from 'prop-types'; import { useState } from 'react'; import { createPortal } from 'react-dom'; // 封装button组件 function Button (props) { const { type, children, onClick } = props; return ( <div className='self-button'> <span className={type} onClick={onClick}>{children}</span> </div> ); } Button.propTypes = { type: PropTypes.oneOf(['default', 'primary', 'danger', 'info']), children: PropTypes.string, onClick: PropTypes.func, }; Button.defaultProps = { type: 'default', children: '点击按钮', }; // 封装组件 function Modal (props) { const { title, closable, children, type, visible, onCancel, onOk, onDelete, footer } = props; const randerFooter = () => { switch (type) { case 'confirm': return ( <div> <Button type="primary" onClick={onOk}>确认</Button> <Button onClick={onCancel}>取消</Button> </div> ); case 'danger': return ( <div> <Button type="danger" onClick={onDelete}>删除</Button> <Button onClick={onCancel}>取消</Button> </div> ); case 'info': return ( <div> <Button type="info" onClick={onOk}>确认</Button> <Button onClick={onCancel}>取消</Button> </div> ); default: return ( <div> <Button type='info' onClick={onCancel}>我知道了</Button> </div> ); } }; const handlerLayer = (ev) => { console.log('---ev.currentTarget', ev.currentTarget.dataset); console.log('---ev.target', ev.target.dataset); if (ev.target.dataset.self === 'layer') { // 防止事件冒泡到父元素 onCancel(); } }; return ( <div className="layer" style={{ display: visible ? 'block' : 'none' }} >.layer { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0, 0, 0, 0.7); .modal { width: 520px; background: white; border-radius: 3px; position: absolute; top: 150px; left: 50%; margin-left: -260px; box-sizing: border-box; header { line-height: 50px; padding: 0 20px; border-bottom: 1px solid #eee; font-size: 12px; &>div { width: 100%; height: 100%; overflow: hidden; &>div:first-child { float: left; } &>div:last-child { float: right; cursor: pointer; } } } footer { line-height: 50px; padding: 0 20px; border-top: 1px solid #eee; height: 50px; overflow: hidden; &>div>div { // 嵌套写法 &.self-button { float: right; } } } main { box-sizing: border-box; padding: 20px; font-size: 14px; } } } .self-button { display: inline-block; // 行内块元素 height: 30px; box-sizing: border-box; line-height: 25px; font-size: 12px; border-radius: 2px; border: 1px solid transparent; overflow: hidden; margin: 0 10px; cursor: pointer; span { display: block; padding: 0 15px; box-sizing: border-box; width: 100%; height: 100%; } span.default { color: #333; border: 1px solid #333; } span.primary { color: #fff; background-color: #007bff; border: 1px solid #007bff; } span.danger { color: #fff; background-color: #dc3545; border: 1px solid #dc3545; } span.info { color: #fff; background-color: #28a745; border: 1px solid #28a745; } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/3 2:44:57

8GB 显存能跑,但跑到第几页会崩:长文档显存曲线的实测

8GB 显存能跑&#xff0c;但跑到第几页会崩&#xff1a;长文档显存曲线的实测 最近技术圈最火的开源项目之一&#xff0c;是百度放出来的 Unlimited-OCR 2。 火到什么程度&#xff1f;上线几天 GitHub 星标破万&#xff0c;Hugging Face 和 GitHub 四个榜单同时登顶&#xff0c…

作者头像 李华
网站建设 2026/11/3 2:44:22

【维克】商品CTA策略:期货市场的量化主战场

"善战者&#xff0c;求之于势&#xff0c;不责于人。"——《孙子兵法兵势篇》将军不苛责士兵&#xff0c;而是善于借助"势"。量化交易也一样——高手不跟市场较劲&#xff0c;而是顺着市场的水势&#xff0c;顺势而为。而商品期货&#xff0c;就是那个&quo…

作者头像 李华