最近在一个web前端开发的项目中,遇到了这样一个需求:项目本身使用react搭建,用antd来完成各种组件的展示,有一个需求,是要将另外一个项目中的部分页面功能加进来,另外的一个项目使用的是bootstrap+ajax库写的纯html页面。

最直接的方法,将这些要加进来的页面功能使用react组件重写一遍,加到项目中,但是这样做成本非常高。于是想有没有方法,将这些html页面直接以连接的方式嵌入到现有react组件中展示。google了一下,可以通过ifram来完成。

现有的react项目使用的是【上中下】布局,点击header中的menu会触发路由,渲染不同的react组件在content中显示。如下:

react组件中通过iframe嵌入html页面_ico

改造的思路是:写一个带有ifram的react组件(HtmlPage.js),点击对应的menus,传入不同的参数到对应的路由,路由会渲染该组件,同时组件会接受一个参数,用来给ifram指定不同的页面url路径。具体代码如下:

1、HtmlPage.js组件代码:

import React, { Component } from 'react';

var root_path = "http://abc.edf/test/";

export default class HtmlPage extends Component {
constructor(props) {
super(props);
this.state = {
iFrameHeight: '0px'
}
}
render() {
let path = this.props.match.params.path;//路由参数
let url = root_path+"default.html";
if (path === "service") {
url = root_path+"service.html";
} else if (path === "interfaceCase") {
url = root_path+"interface_view.html";
}
console.log(path,url);
return (
<div>
<iframe ref="iframe" scrolling="yes" frameBorder="0"
style={{width:'100%',height:this.state.iFrameHeight, overflow:'visible'}}
onLoad={() => {//iframe高度不超过content的高度即可
let h = document.documentElement.clientHeight - 20;
this.setState({
"iFrameHeight": h + 'px'
});
}}
src={url}
/>
</div>
)
}
}

这个组件中使用了iframe,并且根据参数来设置iframe的src。此外,组件还根据不同ifram src页面的高度,动态设置了ifram的height属性。

参考:​​https://www.jianshu.com/p/a288aa0f73fa​

2、主框架代码App.js:

function App() {
return (
<div >
<Layout style={{ height:"100%" }}>
<HashRouter>
<Header style={{ height: "48px", padding: "0 10px", position: 'fixed', zIndex: 9, width: '100%' }}>
<HeaderNav/>
</Header>
<Content style={{ backgroundColor: 'white', marginTop: '48px',minHeight: document.documentElement.clientHeight - restHeight }}>
<Switch>
<Route exact path="/home" component={Home} />
<Route path="/htmlPage/:path"component={HtmlPage} />
<Route path="/caseManage" component={JEditorComponent} />
<Route path="/other" render={() => <h1>未完待续。。。</h1>} />
<Redirect to="/home"/>
</Switch>
</Content>
<Footer style={{ height: "20px", padding: '0px', textAlign: 'center', color: 'rgba(0,0,0,0.5)' }}>
Copyright © 2020 abc Limited All Rights Reserved.
</Footer>
</HashRouter>
</Layout>
</div>
);
}

这里设置了一个路由“/htmlPage/:path”,当menu路由到这个规则上,就会渲染上面的HtmlPage.js组件,同时传递一个path参数,用来指定iframe的url连接地址,这个地址就可以是另外一个项目的html页面。

3、导航菜单组件HeaderNav.js:

import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import { Menu, Icon } from 'antd';
import "./HeaderNav.css";

const { SubMenu } = Menu;

export default class HeaderNav extends Component {

render() {
return (
<div className="header-nav">
<Menu mode="horizontal" theme="dark" defaultSelectedKeys={['home']}>
<Menu.Item key="home">
<Link to="/home">
<Icon type="home" />
Home
</Link>
</Menu.Item>
<SubMenu
title={
<span className="submenu-title-wrapper">
<Icon type="setting" />
Meta data
</span>
}
>
<Menu.Item key="service_manage">
<Link to="/htmlPage/service">
service manage
</Link>
</Menu.Item>
<Menu.Item key="interface_manage">
<Link to="/htmlPage/interfaceCase">
interface manage
</Link>
</Menu.Item>
<Menu.Item key="case_manage">
<Link to="/caseManage">
case manage
</Link>
</Menu.Item>
</SubMenu>
</Menu>
</div>
)
}
}

好了,到这里就基本完成了如何在react中嵌入html页面的需求。