如何使用React实现带淡入淡出效果的小型可复用弹窗
React小型可复用淡入淡出弹窗实现
直接封装无额外依赖的通用弹窗组件即可,完全可控尺寸、动画效果,一次封装全局可复用,不需要引入第三方UI库。
核心特性
- 默认小尺寸自适应内容,不会出现占满全屏的问题
- 自带淡入淡出过渡效果,动画时长可自定义
- 支持全局调用,不需要每个页面重复写弹窗结构
- 支持自定义位置、显示时长、内容样式
代码实现
首先新建弹窗组件文件:
1. 组件逻辑 Popup.jsx
import { useState, useEffect, useCallback } from 'react'; import './Popup.css'; // 全局调用方法句柄 let openPopup = null; /** * 全局调用弹窗方法 * @param {string|React.ReactNode} content 弹窗显示内容 * @param {object} options 配置项 * @param {number} options.duration 自动关闭时长,传0则不自动关闭 * @param {string} options.position 弹窗位置:center/top/bottom */ export const showPopup = (content, options = {}) => { openPopup?.(content, options); }; const Popup = () => { const [visible, setVisible] = useState(false); const [content, setContent] = useState(''); const [config, setConfig] = useState({ duration: 2000, position: 'center' }); const handleClose = useCallback(() => { setVisible(false); }, []); useEffect(() => { openPopup = (content, options) => { setContent(content); setConfig(prev => ({ ...prev, ...options })); setVisible(true); if (options.duration !== 0) { setTimeout(handleClose, options.duration || 2000); } }; return () => { openPopup = null; }; }, [handleClose]); return ( <> {/* 半透明遮罩,不需要可删除 */} {visible && <div className="popup-mask" onClick={handleClose} />} <div className={`popup-box popup-${config.position} ${visible ? 'fade-in' : 'fade-out'}`} > {content} </div> </> ); }; export default Popup;
2. 样式文件 Popup.css
/* 遮罩层 */ .popup-mask { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.1); z-index: 999; } /* 弹窗基础样式 小尺寸默认配置 */ .popup-box { position: fixed; z-index: 1000; min-width: 120px; max-width: 280px; padding: 12px 20px; border-radius: 8px; background: #ffffff; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); font-size: 14px; line-height: 1.5; text-align: center; /* 淡入淡出动画配置 */ transition: opacity 0.2s ease, transform 0.2s ease; opacity: 0; pointer-events: none; } /* 位置配置 */ .popup-center { top: 50%; left: 50%; transform: translate(-50%, -48%); } .popup-top { top: 20%; left: 50%; transform: translate(-50%, -48%); } .popup-bottom { bottom: 20%; left: 50%; transform: translate(-50%, 52%); } /* 动画状态 */ .fade-in { opacity: 1; transform: translate(-50%, -50%); pointer-events: auto; } .fade-out { opacity: 0; pointer-events: none; }
使用方法
- 先在项目根组件(如
App.jsx)挂载一次弹窗,全项目共用:
import Popup from './Popup'; function App() { return ( <div className="app-container"> {/* 原有业务路由、组件 */} <Popup /> </div> ); }
- 任意业务页面需要触发弹窗时,直接引入调用方法即可,不需要重复挂载组件:
import { showPopup } from './Popup'; // 业务逻辑中直接调用 const handleAction = () => { // 基础调用 showPopup('操作已提交'); // 自定义配置调用 showPopup('内容已删除', { duration: 1500, position: 'top' }); };
自定义调整说明
- 调整弹窗尺寸:直接修改
.popup-box的min-width/max-width/padding属性即可 - 调整淡入淡出速度:修改
transition属性的时长数值 - 支持复杂内容:
showPopup方法的content参数支持传入React节点,可以放按钮、图片、表单等任意自定义内容 - 不需要遮罩层直接删除对应JSX和样式代码即可
内容的提问来源于stack exchange,提问作者Sexy Guy
相关产品推荐
相关产品推荐

