dva+umi+antdを使用してページを構築する(3)
59618 ワード
dva+umi+antdを使用してページを構築する(3)
レイアウトができたらシステム全体のルーティングとそれに対応するルーティングコンポーネントの構築を開始することができるが,ルーティングを要求するページがTabsラベルページにある場合があり,各ラベルページをクリックして切り替えることができ,次にこのレイアウトの実現を検討する.
Tabsコンポーネント Tabsコンポーネントを追加し、src/components/layoutにTabsを追加する.jsコンポーネントは、まず公式サイトでhttps://ant.design/components/tabs-cn/Tabsコンポーネントをコピーすると、次のようになります. を正常に追加削除できます.ステータスアップは、次にtabコンポーネントのステータスアップをdvaによって管理する必要があるので、tabコンポーネント 参照コード:https://github.com/enusune/myapp
レイアウトができたらシステム全体のルーティングとそれに対応するルーティングコンポーネントの構築を開始することができるが,ルーティングを要求するページがTabsラベルページにある場合があり,各ラベルページをクリックして切り替えることができ,次にこのレイアウトの実現を検討する.
Tabsコンポーネント
import React from 'react'
import { Tabs, Button } from 'antd';
const TabPane = Tabs.TabPane;
class Mytab extends React.Component {
constructor(props) {
super(props);
this.newTabIndex = 0;
const panes = [
{ title: 'Tab 1', content: 'Content of Tab Pane 1', key: '1' },
{ title: 'Tab 2', content: 'Content of Tab Pane 2', key: '2' },
];
this.state = {
activeKey: panes[0].key,
panes,
};
}
onChange = (activeKey) => {
this.setState({ activeKey });
}
onEdit = (targetKey, action) => {
this[action](targetKey);
}
add = () => {
const panes = this.state.panes;
const activeKey = `newTab${this.newTabIndex++}`;
panes.push({ title: 'New Tab', content: 'New Tab Pane', key: activeKey });
this.setState({ panes, activeKey });
}
remove = (targetKey) => {
let activeKey = this.state.activeKey;
let lastIndex;
this.state.panes.forEach((pane, i) => {
if (pane.key === targetKey) {
lastIndex = i - 1;
}
});
const panes = this.state.panes.filter(pane => pane.key !== targetKey);
if (panes.length && activeKey === targetKey) {
if (lastIndex >= 0) {
activeKey = panes[lastIndex].key;
} else {
activeKey = panes[0].key;
}
}
this.setState({ panes, activeKey });
}
render() {
return (
<div>
<div style={{ marginBottom: 16 }}>
<Button onClick={this.add}>ADD</Button>
</div>
<Tabs
hideAdd
onChange={this.onChange}
activeKey={this.state.activeKey}
type="editable-card"
onEdit={this.onEdit}
>
{this.state.panes.map(pane => <TabPane tab={pane.title} key={pane.key}>{pane.content}</TabPane>)}
</Tabs>
</div>
);
}
}
export default Mytab
で、src/layouts/indexに置き換えます.jsのContent rander関数は、return (
<Layout>
<MySider collapsed={collapsed}>
<MyMenu {...menuProps}/>
MySider>
<Layout>
<Header collapsed={collapsed} onCollapseChange={onCollapseChange}/>
<MyTab>
{this.props.children}
MyTab>
Layout>
Layout>
);
ページにtabコンポーネントが表示され、import React from 'react'
import {Tabs,Button} from 'antd';
import PropTypes from "prop-types";
const TabPane = Tabs.TabPane;
class MyTab extends React.Component {
onEdit = (targetKey, action) => {
this[action](targetKey);
}
remove = (targetKey) => {
const {onPaneRemove} = this.props
onPaneRemove(targetKey)
}
render() {
const {
panes,
activeKey,
onPaneChange,
onPaneAdd,
} = this.props
return (
<div>
<div style={{ marginBottom: 16 }}>
<Button onClick={onPaneAdd}>ADD</Button>
</div>
<Tabs
hideAdd
onChange={onPaneChange.bind(this)}
activeKey={activeKey}
type="editable-card"
onEdit={this.onEdit}
>
{panes.map(pane => <TabPane tab={pane.title} key={pane.key} closable={pane.closable}>
{pane.content}
</TabPane>)}
</Tabs>
</div>
);
}
}
MyTab.propTypes = {
panes: PropTypes.array.isRequired,
activeKey: PropTypes.string.isRequired,
onPaneChange: PropTypes.func.isRequired,
}
export default MyTab
を改造してsrc/layouts/indexを変更する.js import React from 'react'
import {Layout} from 'antd';
import Header from '../components/layout/Header'
import MySider from '../components/layout/Sider'
import MyMenu from '../components/layout/Menu'
import MyTab from '../components/layout/Tabs'
import {connect} from 'dva';
class BasicLayout extends React.Component {
onCollapseChange = collapsed => {
this.props.dispatch({
type: 'app/handleCollapseChange',
payload: {collapsed},
})
}
handelMenuClick = (element) => {
//
this.props.history.push(element.item.props.url)
}
onPaneAdd = () => {
//todo something
}
onPaneChange = () => {
//todo something
}
onPaneRemove = () => {
//todo something
}
render() {
const {app, children} = this.props
const {menus, theme, collapsed,panes,activeKey,} = app
const {handelMenuClick, onCollapseChange,onPaneAdd,onPaneChange,onPaneRemove} = this
const menuProps = {
theme,
menus,
children,
handelMenuClick,
onCollapseChange,
}
const tapProps = {
panes,
children,
activeKey,
onPaneAdd,
onPaneChange,
onPaneRemove,
}
return (
<Layout>
<MySider collapsed={collapsed}>
<MyMenu {...menuProps}/>
</MySider>
<Layout>
<Header collapsed={collapsed} onCollapseChange={onCollapseChange}/>
<MyTab {...tapProps}>
{this.props.children}
</MyTab>
</Layout>
</Layout>
);
}
}
export default connect((({app}) => ({app})))(BasicLayout)
その後、src/models/appを変更する.js export default {
namespace: 'app',
state: {
collapsed: false,
activeKey: '1',
panes: [
{title: `dashboard`, content: '', key: '1', closable: false, url: '/dashboard'},
],
theme: 'dark',
menus: [{
id: '1',
name: 'dashboard',
icon: 'dashboard',
url: '/dashboard',
}, {
id: '2',
name: ' ',
icon: 'user',
url: '1',
children: [{
id: '3',
name: ' ',
icon: 'user',
url: '/user',
},]
}, {
id: '3',
name: ' ',
icon: 'user',
url: '1',
children: [{
id: '4',
name: ' ',
icon: 'user',
url: '/user',
},]
}],
},
subscriptions: {},
effects: {},
reducers: {
updateState(state, {payload}) {
return {
...state,
...payload,
}
},
handleCollapseChange(state, {payload}) {
return {
...state,
...payload,
}
},
},
}
は最後にsrc/layouts/indexを完了した.jsのいくつかの制御状態の関数onPaneAdd = () => {
const {app, dispatch} = this.props
const {panes,} = app
let newPane = {title: 'new Tab', content: '', key: panes.length + '1',}
let flag = false
let newPanes = panes.map(item => {
if (newPane.key === item.key) {
flag = true
return {...item, ...newPane}
}
return item
})
dispatch({
type: 'app/updateState',
payload: {
panes: flag ? newPanes : [...newPanes, newPane],
activeKey: newPane.key,
},
})
}
onPaneChange = targetKey => {
const {dispatch,} = this.props
dispatch({
type: 'app/updateState',
payload: {
activeKey: targetKey
},
})
}
onPaneRemove = targetKey => {
const {dispatch,} = this.props
const payload = this._removeTap(targetKey)
dispatch({
type: 'app/updateState',
payload: payload,
})
}
_removeTap = (targetKey) => {
const {panes, activeKey} = this.props.app
let newActiveKey = activeKey
let lastIndex;
panes.forEach((pane, i) => {
if (pane.key === targetKey) {
lastIndex = i - 1;
}
});
const newPanes = panes.filter(pane => pane.key !== targetKey);
if (newPanes.length && activeKey === targetKey) {
if (lastIndex >= 0) {
newActiveKey = newPanes[lastIndex].key;
} else {
newActiveKey = newPanes[0].key;
}
}
return {
panes: newPanes,
activeKey: newActiveKey
}
}
はこれで追加と削除が可能になるが、メニューをクリックして追加し、このページを表示する必要があるので、src/layouts/indexをもう少し改造する.jsの関数は、Tabコンポーネントの追加ボタンをindexから削除する.js //
handelMenuClick = element => {
let newPane = {title: element.item.props.name, content: '', key: element.key, url: element.item.props.url}
this.onPaneAdd(newPane)
}
// tab
onPaneAdd = (newPane) => {
const {app, dispatch, history,} = this.props
const {panes,} = app
let flag = false
//
history.push(newPane.url)
setTimeout(()=>{
newPane.content = this.props.children
let newPanes = panes.map(item => {
if (newPane.key === item.key) {
flag = true
return {...item, ...newPane}
}
return item
})
dispatch({
type: 'app/updateState',
payload: {
panes: flag ? newPanes : [...newPanes, newPane],
activeKey: newPane.key,
},
})
},100)
}
Tabs.js // tab
componentWillMount(){
const {panes, onPaneAdd,} = this.props
if (panes.length === 1) {
const pane = panes[0]
onPaneAdd(pane)
}
}
これによりtabの追加と削除を実現できる: