1 新建页面
1.1 在 src -> pages ->『新建文件夹』NewPage -> 『新建js文件』NewPage.js 和 『新建less文件』NewPage.
1.2 在 NewPage.js 填入如下代码
/* * @Description: 新添加页面,pages/NewPage/NewPage.js */ // 必须引入 import React, { PureComponent } from "react"; // 引入阿里dva框架,不然不能和服务端交互,必须引入 import { connect } from "dva"; import { List, Avatar, Card } from 'antd'; // 面包屑 import PageHeaderWrapper from "@/components/PageHeaderWrapper"; // 这个注解解释起来有点麻烦,但要注意以下几点 // 1.@connect必须放在export default class前面 // 2.这个不写,你在这个页面里面获取不到服务器返回给你的数据 // 3.采用解构赋值的方式,第一个参数 newPage 是命名空间,我们数据就是从这里拿到的 @connect(({ newPage, loading }) => ({ data: newPage.data, // 将data赋值给 loading })) class NewPage extends PureComponent { // componentWillMount 渲染之前调用,一般处理 ajax 异步回来的数据, // 等下面 render 渲染的时候好绑定 componentWillMount() { console.log("渲染之前调用"); console.log("之调用一次"); } // 每次调用 render 之前渲染 componentDidMount(){ // 分发器,用 dispatch 一定要写 @connect 注解 const { dispatch } = this.props; // 分发器调用 models 发起请求,具体流程是 dispatch => models => services dispatch({ // newPage 命名空间,fetch 是该文件中的方法,对应 src/models/newPage.js,因为 newPage 的 namespace 的值 newPage type: "NewPage/fetch", // 参数,一般采用json格式, 无参,不需要 payload, }); } render() { const { data } = this.props; return ( <PageHeaderWrapper title="新加页面" content="新家页面常见于系统用户维护和系统功能授权。" > <List itemLayout="horizontal" dataSource={data} renderItem={item => ( <Card> <List.Item> <List.Item.Meta avatar={<Avatar src={item.logo} />} title={<a href="https://ant.design">{item.title}</a>} description={item.description} /> </List.Item> </Card> )} /> </PageHeaderWrapper> ); } } export default UserManagement;
1.3 在 NewPage.less 填入如下代码
//样式文件默认使用 CSS Modules,如果需要,你可以在样式文件的头部引入 antd 样式变量文件: //这样可以很方便地获取 antd 样式变量并在你的文件里使用,有利于保持页面的一致性,也方便实现定制主题。 @import "~antd/lib/style/themes/default.less";
2 创建Models
2.1 在 src -> models ->『新建js文件』NewPage.js
新建该文件,啥都不写的时候,会看到页面上出现如下报错:
不要慌,原因如下:
每个传入 combineReducers 的 reducer 都需满足以下规则: 所有未匹配到的 action,必须把它接收到的第一个参数也就是那个 state 原封不动返回。 永远不能返回 undefined。当过早 return 时非常容易犯这个错误,为了避免错误扩散,遇到这种情况时 combineReducers 会抛异常。 如果传入的 state 就是 undefined,一定要返回对应 reducer 的初始 state。根据上一条规则,初始 state 禁止使用 undefined。使用 ES6 的默认参数值语法来设置初始 state 很容易,但你也可以手动检查第一个参数是否为 undefined。 虽然 combineReducers 自动帮你检查 reducer 是否符合以上规则,但你也应该牢记,并尽量遵守。
2.2 填入以下代码
/* * @Description:新添加页面的 models, src/models/NewPage.js */ // 导入接口文件,并采用解构的方式, // 声明取用 services/api 服务的 queryProjectNotice 方法,用原有 mock 接口进行测试 import { queryProjectNotice } from '@/services/api'; export default { namespace: "newPage", // State 是储存数据的地方,收到 Action 以后,会更新数据。 state: { data: [] }, effects: { /** * @param payload 参数,一般在 * @param call 执行异步函数调用接口 * @param put 发出一个 Action,类似于 dispatch 将服务端返回的数据传递给上面的state * @returns {IterableIterator<*>} */ *fetch(_, { call, put }){ // 访问之前可以做一些操作 const response = yield call(queryProjectNotice); // 拿到数据之后可以做一些操作 yield put({ // 这行对应下面的 reducers 处理函数名字 type: "save", // 这是将最后的处理数据传递给下面的 reducers 函数 payload: response }) // * fetch2({ payload }, { call, put }) { // const response = yield call(queryCurrent, payload); // yield put({ // type: "saveCurrentUser", // payload: response // }); // } } }, reducers: { /** * @param state * @param action * @returns {{[ p: string ]: *}} */ save(state, action){ // 结果:将 state 中的数据有更新的,将更新后的结果返回,没有更新的直接返回 // action = yield put() 传过来的对象 console.log(action); return { ...state, // es6三点运算符合,对象解析 data: action.payload // 上面与服务器交互完的数据赋值给data,这里的data 对应最上面 state 里面的 data }; } } }
3 创建services (使用已有的services可略过此步骤)
3.1 在 src -> services ->『新建js文件』NewPage.js
3.2 填入以下代码
// json序列化的工具 import { stringify } from "qs"; // ant 自己封装好的发送ajax请求的工具 import request from "@/utils/request"; // get请求 注意 ` 这个符号 不是这种 ’号 export async function queryUser1(params) { // stringify这个将json序列化 比如 {"a":1,"b":2} 转换成 a=1&b=2 return request(`/server/api/test/user?${stringify(params)}`); } // post请求 注意 ` 这个符号 不是这种 ’号 export async function queryUser2(params) { return request(`/server/api//test/user?${params}`, { method: "POST" }); }
4 修改代理文件(使用已有接口,可略过此步骤)
4.1 由于前面有介绍,这里详细介绍,只贴出代码
4.2 具体代码
proxy: { // 代理以访问 /server/api 开头的所有路由 '/server/api/': { // 代理的目标地址 target: 'http://localhost:8080', // 开启跨域访问 changeOrigin: true, // 发送请求的时候,去掉server pathRewrite: { '^/server': '' }, }, },
5 创建后端应用(使用已有接口,可略过此步骤)
5.1 我这里采用springboot创建的一个简单应用,由于怕跑题创建步骤不在详细,贴出关键代码
5.2 具体代码
package com.example.demo.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("api/test") public class TestController { @RequestMapping("user") public Map<String, Object> user(String a, String b) { Map<String, Object> map = new HashMap<>(); map.put("userName", "张三"); map.put("age", 18); map.put("studentNo", "02563575178158"); map.put("sex", "男"); return map; } }
// 其生成结果(即 返回的 map):
{
"userName": "张三",
"age": 18,
"studentNo": "02563575178158",
"sex": "男",
}
6 访问效果
7 大概流程
7.1 引用pro官网的话
1.UI 组件交互操作;
2.调用 model 的 effect;
3.调用统一管理的 service 请求函数;
4.使用封装的 request.js 发送请求;
5.获取服务端返回;
6.然后调用 reducer 改变 state;
7.更新 model。
7.2 我的理解
7.3 其实是支付宝的 Dva 框架
上篇:antd pro2.0 使用记录五:设置代理
自建服务:antd pro2.0 使用记录六:与服务端交互(自建服务)