【共享单车】—— React后台管理系统开发手记:主页面架构设计
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录。最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star。
一、页面结构定义
- 左侧导航栏,右侧页面结构
- 右侧显示内容分别分为上Header、中Content和下Footer部分

二、目录结构定义
- src->admin.js:项目主结构代码(index.js中替换App.js挂载到根节点)
- src->common.js:项目公共结构代码(类似admin.js,负责路由详情页展示)
- src->components目录:项目公共组件
- components->Footer、Header、NavLeft目录:index.js+index.less
- src->pages目录:项目路由页面组件
- src->style目录:全局样式common.less
- src->config目录:菜单配置、项目其它变量配置
- src->axios目录:执行axios请求文件 index.js
- src->utils目录:项目工具方法
- src->resource->assets目录:项目图片资源(public->assets目录供打包后使用)
- src->resource->gellary目录:画廊图片资源(public->gellary目录供打包后使用)
- src->resource->carousel-img目录:轮播图片资源(public->carousel-img目录供打包后使用)
三、栅格系统使用
- AntD栅格系统一共24列(BootStrap一共12列)
- AntD中行用Row组件,列使用Col组件,列存在span属性(span={长度值}的方式写入span属性),同一Row下的Col span总和为24
import { Row,Col } from 'antd' <Row>
<Col span={4}>
Left
</Col>
<Col span={20}>
Right
</Col>
</Row>
四、calc计算方法使用
- calc()是less中动态计算长度值
- calc(四则运算):运算符前后都需要保留一个空格
width: calc(100% - 10px)//表示宽度属性是整个布局的100%减去50px的长度
- calc(100vh):vh的含义相当于1%,100vh即是100%
五、关于less
- less是预编译器
- 用法一:样式嵌套
//css中
div{...}
div a{...} //less中
div{
...
a{
...
}
} - 用法二:声明变量
@colorA:'red'
div{
color:@colorA
a{
color:black
}
}
六、架构代码
- admin.js
import React from 'react';
import { Row, Col } from 'antd';
import Header from './components/Header';
import Footer from './components/Footer';
import NavLeft from './components/NavLeft';
import './style/common.less'
class Admin extends React.Component{
render(){
return(
<Row className="container">
<Col span={4} className="nav-left">
<NavLeft/>
</Col>
<Col span={20} className="main">
<Header/>
<Row className="content">
content
</Row>
<Footer/>
</Col>
</Row>
);
}
}
export default Admin; style->common.less
.container{
display: flex;
.nav-left{
width: 15%;
min-width: 180px;
height: calc(100vh);
background-color: red;
}
.main{
flex: 1;
height: calc(100vh);
}
.content{
position: relative;
padding: 20px;
}
}components->Header/Footer/NavLeft->index.js
import React from 'react';
class Header extends React.Component{
render(){
return(
<div>Header</div>
)
}
}
export default Header;
七、导航栏内容
- 在config下编写manuConfig.js返回导航栏内容title和key(AntD 路由地址)
const menuList = [
{
title:'首页',
key:'/admin/home'
},
{
title:'UI',
key:'/admin/ui',
children:[
{
title:'按钮',
key:'/admin/ui/buttons',
},
{
title:'弹框',
key:'/admin/ui/modals',
},
{
title:'Loading',
key:'/admin/ui/loadings',
},
{
title:'通知提醒',
key:'/admin/ui/notification',
},
{
title:'全局Message',
key:'/admin/ui/messages',
},
{
title:'Tab页签',
key:'/admin/ui/tabs',
},
{
title:'图片画廊',
key:'/admin/ui/gallery',
},
{
title:'轮播图',
key:'/admin/ui/carousel',
}
]
},
{
title:'表单',
key:'/admin/form',
children:[
{
title:'登录',
key:'/admin/form/login',
},
{
title:'注册',
key:'/admin/form/reg',
}
]
},
{
title:'表格',
key:'/admin/table',
children:[
{
title:'基础表格',
key:'/admin/table/basic',
},
{
title:'高级表格',
key:'/admin/table/high',
}
]
},
{
title:'富文本',
key:'/admin/rich'
},
{
title:'城市管理',
key:'/admin/city'
},
{
title:'订单管理',
key:'/admin/order',
btnList:[
{
title:'订单详情',
key:'/admin/order/detail'
},
{
title:'结束订单',
key:'/admin/order/finish'
}
]
},
{
title:'员工管理',
key:'/admin/user'
},
{
title:'车辆地图',
key:'/admin/bikeMap'
},
{
title:'图标',
key:'/admin/charts',
children:[
{
title:'柱形图',
key:'/admin/charts/bar'
},
{
title:'饼图',
key:'/admin/charts/pie'
},
{
title:'折线图',
key:'/admin/charts/line'
},
]
},
{
title:'权限设置',
key:'/admin/permission'
},
];
export default menuList; - 渲染菜单(Menu)
- AntD Menu组件:官方文档
- 更改主题色:theme属性 -- light/dark
import { Menu, Icon } from 'antd';
import MenuConfig from './../../config/manuConfig' const SubMenu = Menu.SubMenu; <Menu theme="dark">
<SubMenu key="sub1" title={<span><Icon type="mail" /><span>Navigation One</span></span>}>
<Menu.Item key="1">Option 1</Menu.Item>
<Menu.Item key="2">Option 2</Menu.Item>
<Menu.Item key="3">Option 3</Menu.Item>
<Menu.Item key="4">Option 4</Menu.Item>
</SubMenu>
</Menu> - src->NevLeft->index.js :通过递归方法循环遍历manuConfig.js内容,渲染菜单
import React from 'react'
import { Menu, Icon } from 'antd';
import MenuConfig from './../../config/manuConfig'
import './index.less' const SubMenu = Menu.SubMenu; export default class NavLeft extends React.Component {
componentWillMount() {
const MenuTreeNode = this.renderMenu(MenuConfig);
this.setState({
MenuTreeNode
})
}
//菜单渲染 -- 递归
renderMenu = (data) => {
return data.map((item) => {
if(item.children) {
return (
<SubMenu title={item.title} key={item.key}>
{this.renderMenu(item.children)}
</SubMenu>
)
}
return <Menu.Item title={item.title} key={item.key}>{item.title}</Menu.Item>
})
}
render() {
return (
<div>
<div className="logo">
<img src="/assets/logo-ant.svg" alt=""/>
<h1>LJQ MS</h1>
</div>
<Menu theme="dark">
{this.state.MenuTreeNode}
</Menu>
</div>
)
}
}NevLeft->index.less:
.logo{
line-height: 90px;
padding-left: 20px;
background-color: #002140;
img {
height: 35px;
}
h1{
color: #ffffff;
font-size: 20px;
display: inline-block;
vertical-align: middle;
margin: 0 0 0 10px;
}
}
八、首页头部内容
- Axios不支持跨域,只支持Ajax相关get/post/put/delete请求
- Jsonp支持跨域(所谓跨域就是跨域名,跨端口,跨协议)web页面上调用js文件时则不受跨域影响(且凡是有src属性的标签都具有跨域能力,如
<\script> <\img> <\iframe>等)yarn add jsonp --save
- Promise最大好处:将回调函数的异步调用变成链式调用
- 函数返回的Promise对象参数接受一个函数
- 参数1为成功的resolve回调函数
- 参数2是失败的reject回调函数函数体中返回对应函数调用
- 调用该返回Promise对象的函数的then方法
- 参数:以resolve函数传入的属性值为参数的函数
- 在方法体内写入回调成功返回的内容
- Header->index.js:
- 利用setInterval函数实时刷新时间信息,并调用utils包中的formate方法格式化时间戳
- 调用axios包中的jsonp方法发送请求并根据promise进行回调
import React from 'react'
import { Row, Col } from 'antd'
import './index.less'
import Util from '../../utils/utils'
import axios from '../../axios'; export default class Header extends React.Component {
state = {}
componentWillMount() {
this.setState({
userName: '莱茵月牙'
})
setInterval(() => {
let sysTime = Util.formateDate(new Date().getTime());
this.setState({
sysTime
})
}, 1000)
//this.getWeatherAPIDate();由于百度API禁止了服务,故该功能暂时不使用
}
getWeatherAPIDate() {
let city = encodeURIComponent('杭州');
axios.jsonp({
url: 'http://api.map.baidu.com/telematics/v3/weather?location='+city+'&output=json&ak=kwQXPVDYPZIYArkpi3rQT7aZHTGTCCB2'
}).then((res) => {
if(res.status == 'success'){
let data = res.result[0].weather_data[0];
this.setState({
dayPictureUrl:data.dayPictureUrl,
weather:data.weather
})
}
})
}
render() {
return (
<div className="header">
<Row className="header-top">
<Col span={24}>
<span>欢迎,{this.state.userName}</span>
<a href='#'>退出</a>
</Col>
</Row>
<Row className="breadcrumb">
<Col span={4} className="breadcrumb-title">
首页
</Col>
<Col span={20} className="weather">
<span className="date">{this.state.sysTime}</span>
<span className="weather-detail">晴转多云</span>
</Col>
</Row>
</div>
)
}
} - utils->utils.js:
export default {
formateDate(time){
if(!time)return '';
let date = new Date(time);
return date.getFullYear()+'-'+(date.getMonth()+1)+'-'+date.getDate()
+' '+date.getHours()+':'+date.getMinutes()+':'+date.getSeconds()
}
} - axios->index.js:使用JsonP模块发送请求获得jsonp数据,解决跨域问题
import JsonP from 'jsonp' export default class Axios{
static jsonp(options){
new Promise((resolve, reject) => {
JsonP(options.url,{
param:'callback'
}, function (err, response) {
if(response.status === 'success'){
resolve(response);
}else{
reject(response.message);
}
})
})
}
}
九、底部组件开发
- Footer->index.js:
import React from 'react'
import './index.less'; export default class Footer extends React.Component {
render() {
return (
<div className="footer">
版权所有:柳洁琼Elena
</div>
)
}
} - less导入到其他less中
@import "文件路径";【注意用@import引入,用分号分割】 - less使用变量方式:
@变量名 - Footer->index.less:
@import "./../../style/default.less"; .footer{
height: 100px;
padding: 40px 0;
text-align: center;
color: @colorJ;
}
十、Home页面实现
- pages->Home->index.js:
import React from 'react'
import './index.less' export default class Home extends React.Component{
render() {
return (
<div className="home-wrap">
欢迎学习慕课后台管理系统课程
</div>
)
}
} pages->Home->index.less:
@import './../../style/default.less'; .home-wrap{
background-color: @colorM;
height: calc(62vh); //内容高度占右侧的62%
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
}flex弹性布局:实现水平垂直居中
display: flex;
align-items: center;//前提布局是flex,align-items表示垂直居中
justify-content: center;//前提布局是flex,align-items表示水平居中CSS实现箭头图标
注意:当内部元素使用绝对定位,父级需要使用相对定位,否则内部元素则会相对整个文档进行绝对定位
after伪类:元素后添加内容实现箭头图标
实现下三角样式:设定border-top为指定颜色,左右border为透明色(transparent)
.breadcrumb{
height: 40px;
line-height: 40px;
padding: 0 20px;
border-top: 1px solid #f9c700;
position: relative; //父级元素相对定位
.breadcrumb-title{
font-size: @fontC;
text-align: center;
&:after{
position: absolute; //绝对定位
content: ''; //设为空用于占位
left: 73px;
top: 39px;
border-top: 9px solid @colorM;
border-left: 12px solid transparent;
border-right: 12px solid transparent;
}
}
注:项目来自慕课网
【共享单车】—— React后台管理系统开发手记:主页面架构设计的更多相关文章
- 【共享单车】—— React后台管理系统开发手记:Router 4.0路由实战演练
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:Redux集成开发
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:城市管理和订单管理
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:AntD Form基础组件
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:权限设置和菜单调整(未完)
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:员工管理之增删改查
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:项目工程化开发
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:AntD Table高级表格
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:AntD Table基础表格
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
随机推荐
- [oldboy-django][4python面试]面试前需要熟练掌握的知识点(待更新)
python基础 - 生成器 - 装饰器 - 迭代器 - 列表生成式 - 引用,传参 - 面向对象,继承 前端Html: - 词法分析 - 作用域 - 语法分析 - this - Jsonp mysq ...
- [python][django学习篇][3]创建django web的数据库模型
推荐学习博客:http://pythonzh.cn/post/8/ 博客或者web界面向用户展示内容,它需要从某个地方获取博客内容或者web界面内容,才能够展示出来.通常来说:某个地方指的就是数据库 ...
- 树中两个结点的最低公共祖先--java
题目:对于任意一个树,不仅仅限于二叉树,求树中两个结点的最低公共祖先结点. 解析:对于任意一棵树,显然并不局限于二叉树,也就是说树的非叶子结点可能存在多个子节点.所以,我们可以定义两个链表结构,存储这 ...
- [cocos2dx UI] CCLabelAtlas 为什么不显示最后一个字
CClabelAtlas优点,基本用法等我就不说了,这里说一个和美术配合时的一个坑!就是图片的最后一位怎么也不显示,如下图中的冒号不会显示 查了ASCII码表,这个冒号的值为58,就是在9(57)的后 ...
- lsof命令查看端口关联的文件
lsof命令查看端口关联的文件 lsof(list open files)是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网 ...
- Ionic2 调用自定义插件之研究
cordova机制我在此就不提了,我们使用Typescript调用cordova plugin就如同调用第三方库是一个道理,那么这里就少不了书写declare文件,下面我就把几种封装调用的几种方式介绍 ...
- C++ Contest Code preprocessor
大概可以拿来方便拉模板 变量名.语法都是瞎整的你感觉有用随便用好了.. #include<bits/stdc++.h> using namespace std; map<string ...
- BZOJ 4491: 我也不知道题目名字是什么
4491: 我也不知道题目名字是什么 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 278 Solved: 154[Submit][Status][ ...
- 【CF1073C】Vasya and Robot(二分,构造)
题意:给定长为n的机器人行走路线,每个字符代表上下左右走,可以更改将一些字符改成另外三个字符,定义花费为更改的下标max-min+1, 问从(0,0)走到(X,Y)的最小花费,无解输出-1 n< ...
- LOJ#2084. 「NOI2016」网格
$n,m \leq 1e9$,$n*m$的网格中有$c \leq 1e5$个是黑的,其他是白的.问:使至少两个白的不连通,最少需要再把几个白的涂黑. 可以发现答案是-1,0,1,2啦.-1要么没白的, ...