Skip to content

其他弹出层

推荐使用命令式的封装!

antd中封装Modal的几种方式

https://blog.csdn.net/baidu_41601048/article/details/123004625?spm=1001.2014.3001.5502

提示

注意弹出层的封装 弹窗组件的关闭并没有让它销毁。 这样会出现一个问题:页面加载的时候自动加载子组件,也就是子组件挂载一次以后如论如何打开关闭都不在任何生命周期函数。 而我们的显示需求是每次打开的时候要请求接口,而不是只挂载一次。

正确思路: 在父组件中定义一个变量,弹窗组件只有在父组件中的变量为真时它才出现,否则就不存在与dom结构中。 而弹窗组件的显示和隐藏,通过这个变量的传值传到子组件中。 在关闭的时候, 触发一个父组件函数,通过该函数改变变量值为false,从而引发弹窗组件的销毁。

父组件

jsx
import React, { useEffect, useState, useRef } from 'react'

function PicMgr() {
	let [drawFlag, setDrawFlag] = useState(false)
	//打开关闭抽屉
	const toggleDrawer = (type) => {
		if (type === "open") {
			setDrawFlag(true)
			console.log("ref:", drawRef.current)
			let val = Math.random() * 100 + 10
			setRandKey(val)
		} else {
			setDrawFlag(false)
			console.log("ref:", drawRef.current)
			let val = Math.random() * 100 + 10
			setRandKey(val)
		}
	}

	return (
		<span className={style['check-btn']} onClick={() => toggleDrawer('open')}>审核</span>
	{
		drawFlag ? (
			<PicDrawer2 randomKey={randKey} closeDrawer={() => toggleDrawer('close')} vis={drawFlag}></PicDrawer2>
		) : null
	}
)
}

子组件

jsx
function Drawer(props) {
	useEffect(() => {
		console.log("useEffect----")
	}, [])

	const onClose = () => {
		console.log("onClose--this.props:", props)
		props.closeDrawer()  //组件间传值,通过调用父组件传过来的属性closeDrawer,由于它本身就是引用的toggleDrawer方法,所以 props.closeDrawer() 的执行就相当于执行了toggleDrawer()

	}

	return (

		<Drawer
			closable={true}
			width="420"
			title="审核"
			placement="right"
			closable={false}
			key={randomKey}
			onClose={onClose}
			destroyOnClose
			visible={props.vis}
		>
			<Form
				{...layout}
				name="nest-messages"
				onFinish={onFinish}
				validateMessages={validateMessages}
			>
				<Form.Item
					label="图片"
					name="image"
				>
					<Image src=""></Image>
				</Form.Item>
			</Form>
		</Drawer>
	)
}

如何取消Modal.confirm的onCancel事件?

业务开发中遇到这么一个需求。点击按钮弹出确认框。点击确认按钮以后需要再出现一个弹窗。 暂且叫它弹窗B,当点击弹窗B的关闭按钮时,发现confirm已经不存在了?这个问题很诡异。 找了很多办法,终于解决了这个问题:

(方案一:) 在antd的Modal.confirm-api中对onCancel和onOk的描述:

onCancel 取消回调,参数为关闭函数,返回 promise 时 resolve 后自动关闭 function(close) - onOk 点击确定回调,参数为关闭函数,返回 promise 时 resolve 后自动关闭 也就是说该函数的参数是一个函数。如果我们不让其返回一个promise,就可以阻止它的默认行为。

接下来我们进行改造:

jsx
const delCatgory = () => {
	Modal.confirm({
		title: "确认删除改属性",
		closable: true,
		width: 420,
		okText: "确认",
		cancelText: "取消",
		onOk: (close) => {
			delModalRef.current.showModelRef() //这里通过ref直接操作弹窗B的显示
		},
		onCancel: (close) => {
			return false
		}
	});
};
//注意这里onok和onCancel里传入了close函数。这样就可以再关闭弹窗B的时候让confirm依然存在

(方案二:)通过自定义内容,隐藏页脚的按钮,然后通过自定义内容添加确认和取消两个按钮

jsx
const delCatgory = () => {
	Modal.confirm({
		title: "确认删除改属性",
		closable: true,
		width: 420,
		okText: "",
		cancelText: "",
		content: <>
			<p>'执行删除类目,子级类目将同步被删除,确认删除吗?'</p>
			<div>
				<Button onClick={confirmDelAttrModal}>确定</Button>
				<Button onClick={cancelDelAttrModal}>取消</Button>
			</div>
		</>,
	})
}

剩下的就是对Modal.confirm默认的底部按钮通过样式进行了隐藏

Modal不刷新的问题(使用destroyOnClose解决)

jsx
<Modal visible={ifShow} destroyOnClose></Modal>

警告信息:Warning: Instance created by useForm is not connected to any Form element. Forget to pass form prop?

1.使用 Form 组件的 form 属性将 form 对象与 Form 组件进行关联 2.将 useForm 方法的返回值 form 对象作为参数传递给需要使用 form 对象的组件 3.还有一种情况就是确实写了form,并且<Form>写了form={form},但还警告 原因是:在调用form的实例时,Modal内部的组件并未渲染,才导致了该错误, 如果遇到了,设置值没设置上,原因也是先设置了值,但表单dom还没渲染完。 利用Modal的forceRender 或者 form.setFieldsValue({...xxx})放到定时器里 需要注意的是,当 forceRender 为 true 时,Modal 组件会在第一次渲染时就会渲染子组件,这可能会导致一些组件的生命周期函数提前执行,从而产生一些不符合预期的结果。

因此,在使用 forceRender 属性时,需要特别注意 Modal 中子组件的生命周期函数的执行顺序和时机。 总的来说,forceRender 属性可以在 Modal 渲染时立即渲染子组件,从而提高用户体验,但是也可能会对性能造成一定的影响。 在使用时需要根据具体情况进行权衡和选择。

Popover

处理Ant Design 3.24.3版本Popover在父元素fixed的情况下跟随滚动条改变位置的问题

背景: select和popover弹层当页面内容过高时滚动悬浮固定在页面某个位置

1.导航栏fixed到顶部 2.悬浮出现popover气泡卡片,但气泡卡片随着滚动条滚动改变位置

解决方案:在popover上使用 getPopupContainer={triggerNode => triggerNode.parentNode}

jsx
<Popover
	getPopupContainer={triggerNode => triggerNode.parentNode}
	content={content}
	title="Title"
	trigger="hover"

Contributors

作者:Long Mo
字数统计:1.3k 字
阅读时长:4 分钟
Long Mo
文章作者:Long Mo
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Longmo Docs