前置知识:ReactJS
- AntdesignPro搭建后台信息管理系统
 - Semantic-UI前台
 - nodejs模拟前台后端,用于前后端分离开发
 - 后端提供mock数据
 
AntDesignPro应用
1. 创建工程
2. 导入依赖
1  | tyarn install #安装相关依赖  | 
修改logo和footer

可见,布局是由layout常量定义
logo
可见,左侧的菜单是自定义组件
1  | {isTop && !isMobile ? null : (  | 
打开 /components/SideMenu 文件
1  | return (  | 
footer
在Footer.js文件中修改版权信息
1  | import React, { Fragment } from 'react';  | 
3. 左侧菜单
路由即菜单
修改默认页 router.config.js

修改国际化映射文件 locale locales=>zh-CN=>settings.js

只有在路由中的命名空间才会被注册 命名空间名唯一
4. 新增房源
房源表单字段
楼盘数据(estate)
| 字段 | 类型 | 备注 | 
|---|---|---|
| id | Long | 楼盘id | 
| name | String | 楼盘名称 | 
| province | String | 所在省 | 
| city | String | 所在市 | 
| area | String | 所在区 | 
| address | String | 具体地址 | 
| year | String | 建筑年代 | 
| type | String | 建筑类型 | 
| propertyCost | String | 物业费 | 
| propertyCompany | String | 物业公司 | 
| developers | String | 开发商 | 
| created | datetime | 创建时间 | 
| updated | datetime | 更新时间 | 
房源数据(houseResource)
| 字段 | 类型 | 备注 | 
|---|---|---|
| id | Long | 房源id | 
| title | String | 房源标题,如:南北通透,两室朝南,主卧带阳台 | 
| estateId | Long | 楼盘id | 
| buildingNum | String | 楼号(栋) | 
| buildingUnit | String | 单元号 | 
| buildingFloorNum | String | 门牌号 | 
| rent | int | 租金 | 
| rentMethod | int | 租赁方式,1-整租,2-合租 | 
| paymentMethod | int | 支付方式,1-付一押一,2-付三押一,3-付六押一,4-年付押一,5-其它 | 
| houseType | String | 户型,如:2室1厅1卫 | 
| coveredArea | String | 建筑面积 | 
| useArea | String | 使用面积 | 
| floor | String | 楼层,如:8/26 | 
| orientation | int | 朝向:东、南、西、北 | 
| decoration | String | 装修,1-精装,2-简装,3-毛坯 | 
| facilities | String | 配套设施, 如:1,2,3 | 
| pic | String | 图片,最多5张 | 
| desc | String | 房源描述,如:出小区门,门口有时代联华超市,餐饮有川菜馆,淮南牛肉汤,黄焖鸡沙县小吃等;可到达亲水湾城市生活广场,里面有儿童乐园,台球室和康桥健身等休闲娱乐;生活广场往北沿御水路往北步行一公里就是御桥路,旁边就是御桥地铁站,地铁站商场… | 
| contact | String | 联系人 | 
| mobile | String | 手机号 | 
| time | int | 看房时间,1-上午,2-中午,3-下午,4-晚上,5-全天 | 
| propertyCost | String | 物业费 | 
| created | datetime | 创建时间 | 
| updated | datetime | 更新时间 | 
antd表单组件
高性能表单控件,自带数据域管理。包含数据录入、校验 以及对应 样式 与 API 。
被设置了 name 属性的 Form.Item 包装的控件,表单控件会自动添加 value(或 valuePropName 指定的其他属性) onChange(或 trigger 指定的其他属性),数据同步将被 Form 接管,这会导致以下结果:
- 你不再需要也不应该用 
onChange来做数据收集同步(你可以使用 Form 的onValuesChange),但还是可以继续监听onChange事件。 - 你不能用控件的 
value或defaultValue等属性来设置表单域的值,默认值可以用 Form 里的initialValues来设置。注意initialValues不能被setState动态更新,你需要用setFieldsValue来更新。 - 你不应该用 
setState,可以使用form.setFieldsValue来动态改变表单值。 
在 rules的参数中,可以增加校验规则
1  | {  | 
表单提交
表单的提交通过submit按钮完成,通过onSubmit方法进行拦截处理
1  | <FormItem {...submitFormLayout} style={{ marginTop: 32 }}>  | 
1  | <Form onSubmit={this.handleSubmit} hideRequiredMark style={{ marginTop: 8 }}>  | 
1  | handleSubmit = e => {  | 

自动填充
效果


实现
1  | <AutoComplete  | 
5. 图片上传组件
图片上传通过自定义组件 PicturesWall 完成,在PictureWall中,通过 antd 的 Upload 组件实现
如何解决子组件的值传递到父组件

- bind方法可以将子组件(PicturesWall)中的this指向父组件(HousingAdd)的this
- 在子组件中调用父组件的方法相当于在父组件的上下文中调用该方法,所以该函数的参数在父组件的上下文中也可以获取到
 
 - 父组件通过属性的方式进行引用子组件 ,在子组件中,通过 
this.props获取传入的函数,进行调用,即可将数据传递到父组件中 
this——函数执行时上下文
this 的值是在执行的时候才能确认,定义的时候不能确认!
this 是执行上下文环境的一部分,而执行上下文需要在代码执行之前确定,而不是定义的时候
1  | var obj = {  | 

bind
绑定函数,使其无论怎么样调用都用相同的上下文环境
fun.bind(thisArgument, argument1, argument2, …)
- thisArgument:在 fun 函数运行时的 this 值,如果绑定函数时使用 new 运算符构造的,则该值将被忽略。
 
1  | var obj = {  | 

在 Window 上下文中,没有 num 值,num的值是在 obj 中定义的
所以引入 bind() 解决 this 不能够指向原来的问题
1  | var obj = {  | 

前台
前端是使用React+semantic-ui实现移动端web展示,后期可以将web打包成app进行发布
1. 搭建工程
1  | npm install # 安装依赖  | 

2. 搭建api工程
使用node.js开发服务端的方式进行了demo化开发,只是作为前端开发的api工程,并不是实际环境
创建数据库
将 myhome.sql 执行 ,创建数据库
修改配置文件——数据库配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/** 数据库配置 */
db: {
/** 模型文件路径 */
models*path: '/models',
/** 数据库主机IP */
host: '8.140.130.91',
/** 数据库的端口号 */
port: 3306,
/** 数据库类型 */
type: 'mysql',
/** 数据库登录用户名 */
username: 'root',
/** 数据库密码 */
password: 'root',
/** 数据库名称 */
database: 'myhome',
/** 是否显示数据库日志 */
logging: console.log,// false 为禁用日志
/** 配置数据库连接池 */
pool: {
max: 5,
min: 0,
charset: 'utf8',
idle: 30000
}
}输入命令进行初始化和启动服务
1
2
3
4
5
6
7
8
9npm install #安装依赖
npm run dev #启动dev脚本
脚本如下
"scripts": {
"test": "cross-env NODE*ENV=config-test node app.js",
"dev": "cross-env NODE*ENV=config-dev node app.js", #设置环境变量
"pro": "cross-env NODE*ENV=config-pro node app.js"
}登录系统测试
问题
Client does not support authentication protocol requested by server; conside
1
2
3
4
5
6
7
8
9
10use mysql;
flush privileges;
-- 加密算法为caching*sha2*password,而旧版加密算法为mysql*native*password
select user,host,plugin from user;
alter user 'root'@'%' identified with mysql*native*password by 'root';
select user,host,plugin from user;ERWRONGFIELDWITHGROUP
1
2
3
4
5use myhome;
SET sql*mode=(SELECT REPLACE(@@sql*mode, 'ONLY*FULL*GROUP*BY', ''));
select @@sql*mode;


3. 前台实现分析
React APP目录结构

加载数据流程

Promise.all()方法获取到所有的异步处理的结果,并且将结果保存到this.state中,然后再render中渲染
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19//设置全局的 axios baseUrl 配置
axios.defaults.baseURL = config.apiBaseUrl;
//设置拦截器
axios.interceptors.request.use(function (config) {
//在发送请求前获取mytoken的值
if(!config.url.endsWith('/login')){
config.headers.Authorization = localStorage.getItem('mytoken');
}
return config;
}, function (error) {
//获取数据失败处理
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
// 对响应的拦截——————返回response.data数据
return response.data;
}, function (error) {
return Promise.reject(error);
});
伪mock服务
目标:所有的数据通过自己实现的接口提供,不需要使用nodejs,便于后端开发
1. 构造数据
mock-data.properties
1  | mock.indexMenu={"data":{"list":[\  | 
2. 创建MockConfig
读取properties文件,映射为String
1  | package com.haoke.api.config;  | 
3. MockController
1  | package com.haoke.api.controller;  | 
4. 测试

5. 整合前端

axios
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
- 从浏览器中创建 XMLHttpRequests
 - 从 node.js 创建 http 请求
 - 支持 Promise API
 - 拦截请求和响应
 - 转换请求数据和响应数据
 - 取消请求
 - 自动转换 JSON 数据
 - 客户端支持防御