一、前言
最近本人在看react,目标是快速上手可以开发前端页面。
好不容易搞清楚了react项目启动流程、路由规则;
(接上文:https://blog.csdn.net/BHSZZY/article/details/128497110
)
下一步就总结下如何写新页面。
二、新增页面方法
以本人项目为例。
1.修改路由文件router.config.js
(1)项目启动后会加载.../项目名/config/config.js
文件,这个文件里会加载.../项目名/config/router.config.js
,所以路由规则就在router.config.js
文件里。
(2)router.config.js
文件中,有一段是这样配置的:
export default [
// user
{
path: '/user',
component: '../layouts/UserLayout',
routes: [
{
path: '/user',
redirect: '/user/login',
},
{
path: '/user/login',
name: 'login',
component: './User/Login',
},
],
},
......
其中, path: '/user',component: '../layouts/UserLayout',
配置的是父页面;
path: '/user/login', component: './User/Login',
配置的是子页面;
当访问http://localhost:8000/user/login
时,会先加载父页面,然后父页面中通过<div>{children}</div>
显示的子页面。
(3)因此,可以在router.config.js
文件中,新增一段:
// myuser
{
path: '/myuser',
component: '../layouts/MyUserLayout',
routes: [
{
path: '/myuser',
redirect: '/myuser/login',
},
{
path: '/myuser/login',
name: 'mylogin',
component: './MyUser/Login',
},
],
},
这样,可以当访问http://localhost:8000/myuser/login
的时候,先显示父页面MyUserLayout.js
,再通过{children}
、显示子页面.../MyUser/Login.js
。
2.创建父页面MyUserLayout.js
(1)本人项目中,有一个模板页面.../项目名/src/layouts/UserLayout.js
,以及样式文件.../项目名/src/layouts/UserLayout.less
;
因此可以复制模板文件,在相同位置创建个.../项目名/src/layouts/MyUserLayout.js
,以及.../项目名/src/layouts/MyUserLayout.less
,然后修改下里面的内容。
(2)MyUserLayout.js
里,有:
import React, { Component } from 'react';
import { connect } from 'dva';
import DocumentTitle from 'react-document-title';
import getPageTitle from '@/utils/getPageTitle';
import styles from './MyUserLayout.less';
/* eslint-disable */
class MyUserLayout extends Component {
render() {
const {
children,
location: { pathname },
breadcrumbNameMap,
} = this.props;
return (
<DocumentTitle title={getPageTitle(pathname, breadcrumbNameMap)}>
<div className={styles.container}>
<div className={styles.content}>
<div className={styles.top}>
<div className={styles.header}>
<span className={styles.title}>{'父页面'}</span>
</div>
</div>
{children}
</div>
</div>
</DocumentTitle>
);
}
}
export default connect(({ menu: menuModel }) => ({
menuData: menuModel.menuData,
breadcrumbNameMap: menuModel.breadcrumbNameMap,
}))(MyUserLayout);
其中,主要是 const { children, location: { pathname }, breadcrumbNameMap, } = this.props;
,这句是ES6写法,相当于:
const children = this.props.children
//注意这个是props里的location里的pathname,而不是location里的pathname,两个值有可能是不一样的。
const pathname = this.props.location.pathname
const breadcrumbNameMap = this.props.breadcrumbNameMap
然后,有这句 </div> {children} </div>
,就可以在这个位置显示子页面了。
(3)MyUserLayout.less
里,有:(这个就是个样式文件)
@import '~antd/lib/style/themes/default.less';
.container {
display: flex;
flex-direction: column;
height: 100vh;
overflow: auto;
background: @layout-body-background;
}
.lang {
width: 100%;
height: 40px;
line-height: 44px;
text-align: right;
:global(.ant-dropdown-trigger) {
margin-right: 24px;
color: #ffffffba;
}
}
.content {
padding: 32px 0;
}
@media (min-width: @screen-md-min) {
.container {
background: url('./img/bg.png') no-repeat 20%;
}
.content {
position: relative;
top: 24%;
width: 350px;
margin-left: calc(~'50% + 260px');
padding: 32px 0 24px 0;
background: rgba(255, 255, 255, 1.36);
border-radius: 10px;
box-shadow: 0 0 50px 5px #c8cffa87 inset;
:global(.ant-input-affix-wrapper) {
width: 83%;
}
}
}
.top {
text-align: center;
}
.header {
height: 44px;
line-height: 44px;
a {
text-decoration: none;
}
}
.logo {
height: 44px;
margin-right: 16px;
vertical-align: top;
}
.title {
position: relative;
top: 2px;
color: @heading-color;
font-weight: 500;
font-size: 33px;
font-family: Avenir, 'Helvetica Neue', Arial, Helvetica, sans-serif;
}
.desc {
margin-top: 12px;
margin-bottom: 40px;
color: @text-color-secondary;
font-size: @font-size-base;
}
这个样式文件被页面文件用到了,例如<div className={styles.container}>
,就对应.container
的样式。
3.创建子页面Login.js
(1)本人项目中,有一个页面.../项目名/src/pages/User/Login.js
;
因此可以复制整个文件夹User
,在相同位置创建个.../项目名/src/pages/MyUser
文件夹,这样子页面就是.../项目名/src/pages/MyUser/Login.js
。
(2)Login.js
页面中,主要就是子页面显示的内容了。
在此记录下需要注意的点:
●通过 export 方式导出,在import时要加{ },export default 则不需要;
export 向外暴露的成员,需要用同名变量来接收;
export default 向外暴露的成员,可以使用任意变量来接收。
/*-----export [test.js]-----*/
let name = "A";
let age = 18;
export default name;
export { age };
----------------------------------
/*-----import [xxx.js]-----*/
import test_name, { age } from "./test.js";
●方法不会自动绑定this,需要手动绑定。(例如onclick方法,就需要绑定this,才能后续正常使用this,否则会undefined)
绑定this,可以用箭头方法:
import React, { Component } from 'react';
class MyPage extends Component {
// 这个写可以绑定this,让this被调用时不再是undefined
myClick = () => {
console.log('this------', this);
}
render() {
return (
<button onClick={this.myClick }>
button
</button>
);
}
}
●react页面间传递参数的方法-query方式:
1.例如,第一个页面有:
import Redirect from 'umi/redirect';
return <Redirect to="/MyUser/login?a=1&b=2" />;
2.跳转后的页面中,可以这样接收:
//this.props是react框架里的,直接用就行
console.log("a-------",this.props.location.query.a);
console.log("b-------",this.props.location.query.b);
----------------------------------------
●react页面间传递参数的方法-state方式:
state同query差不多,只是属性不一样;
注意state传的参数是加密的,query传的参数是公开的,在地址栏
1.发送参数的页面
HTML方式:
<Link to={{ path : '/test' , state : { name : 'a' }}}>
JS方式:
this.props.router.push({ pathname:'/test',state:{name : 'a' } })
2.接收参数的页面
this.props.location.state.name
4.测试
可以访问http://localhost:8000/myuser/login
,就可以跳转到新建的父页面MyUserLayout.js
与子页面Login.js
了。
(注意,如果config.js
里配置了base: '/mybase/'
参数,那就需要访问http://localhost:8000/mybase/myuser/login
进行测试)