最近在一個web前端開發的項目中,遇到了這樣一個需求:項目本身使用react搭建,用antd來完成各種元件的展示,有一個需求,是要将另外一個項目中的部分頁面功能加進來,另外的一個項目使用的是bootstrap+ajax庫寫的純html頁面。
最直接的方法,将這些要加進來的頁面功能使用react元件重寫一遍,加到項目中,但是這樣做成本非常高。于是想有沒有方法,将這些html頁面直接以連接配接的方式嵌入到現有react元件中展示。google了一下,可以通過ifram來完成。
現有的react項目使用的是【上中下】布局,點選header中的menu會觸發路由,渲染不同的react元件在content中顯示。如下:
改造的思路是:寫一個帶有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頁面。
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>
)
}
}