React 模态框解耦处理方法
再写React模态框的时候发现不能想Vue 一样能用 .sync修饰符处理模态框
然后查阅了以下解耦方式发现一个跟Vue.extend( )方法类似的API,然后看了以下使用方法如下
在这之前,我们先要了解一个API
createPortal ---> 他的前世是 ReactDOM.unstable_renderSubtreeIntoContainer
自己可以查阅以下资料下面直接上两端自己封装后的代码,后面有空传gitHub
/*
* @Description: 查看图片--组件
* @FilePath: \zslh_bet\src\views\publicTemplate\selectIMG\SelectIMG.js
* @auto: LiaoXiang
* @Date: 2020-03-02 10:22:56
* @LastEditTime: 2020-03-07 10:22:18
*/
import React, { Component } from 'react'
import './selectImg.scss'
import {createPortal} from 'react-dom';
class SelectIMG extends Component {
constructor(props) {
super(props);
this.state = {
node: document.createElement('div')
};
this.node = document.createElement('div')
}
render() {
return (
<div className="selectImg" onClick={ this.lookForIMG.bind(this) }>
<img
src={this.props.imgurl}
onError={ (e)=>{ e.target.src = require('../../../assets/icon/error_Load.png') }}
alt=""
/>
{
createPortal(
<div className="showModelImg" onClick={ this.removeModelIMG.bind(this) }>
<img
src={this.props.imgurl}
onError={ (e)=>{ e.target.src = require('../../../assets/icon/error_Load.png') }}
alt=""
/>
</div>,
this.node
)
}
</div>
)
}
lookForIMG(){
window.document.body.appendChild(this.node);
}
removeModelIMG(e){
e.stopPropagation();
window.document.body.removeChild(this.node);
}
}
export default SelectIMG;
scss
.selectImg{
height: 202px;
width: 228px;
display: inline-block;
margin-right: 10px;
overflow: hidden;
img{
pointer-events:none;
height: 100%;
}
}
.showModelImg{
position: fixed;
top: 0;
height: 100%;
width: 100%;
background-color: rgba(0,0,0,.6);
z-index: 199;
img{
width: 100%;
height: auto;
margin-top: 35%
}
}
一个自定义的弹框,只有弹框部分其他全是考slot 来处理自己的逻辑
图片自己自取 就一个X的图片
import React, { Component } from 'react'
import { createPortal } from 'react-dom'
import './myModel.scss'
class SModel extends Component {
constructor(props) {
super(props);
this.node = document.createElement('div');
this.node.classList.add('LX_MODEL_DOM_HIDLE')
this.state = {
};
}
render() {
let view = Array.isArray(this.props.children) ? this.props.children : [this.props.children];
return createPortal(
<div className="myModel" onClick={this.clearModel.bind(this)}>
<div className="smodelContent" onClick={(e) => { e.stopPropagation() }}>
<div className="headInfo">
<p>帮助说明</p>
<img
className="closeImg"
src={require('../../../assets/com/close.png')}
onClick={this.clearModel.bind(this)}
alt=""
/>
</div>
<div className="SmodelCt">
{view.map(item => item)}
</div>
</div>
</div>, //塞进传送门的JSX
this.node //传送门的另一端DOM node
);
}
clearModel(e) {
window.document.body.removeChild(this.node);
}
componentDidMount() {
this.props.visibel && window.document.body.appendChild(this.node);
}
componentDidUpdate() {
// window.document.body.appendChild(this.node);
if (this.props.visibel) {
window.document.body.appendChild(this.node);
} else {
document.querySelector('.LX_MODEL_DOM_HIDLE') && window.document.body.removeChild(this.node);
}
}
}
export default SModel
.smodel{
position: fixed;
height: 100%;
width: 100%;
background: rgba(0,0,0,0.6);
z-index: 199;
.smodelContent{
width: 600px;
position: absolute;
top: 420px;left: 50%;
transform: translateX(-50%);
border-radius: 8px;
background: #ffffff;
overflow: hidden;
.headInfo{
text-align: center;
line-height: 92px;
font-size:32px;
background: #EF2646;
color: #ffffff;
.closeImg{
height: 28px;
width: 28px;
position: absolute;
right: 24px;
top:30px;
}
}
.SmodelCt{
padding: 20px 10px;
height: 300px;
}
}
}