美文网首页
使用React+AntD+Dva+Umi构建CRUD(增删改查)

使用React+AntD+Dva+Umi构建CRUD(增删改查)

作者: 南荣相如谈编程 | 来源:发表于2020-04-13 21:24 被阅读0次

概览

React 是什么?

React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。

antd 是什么?

antd 是基于 Ant Design 设计体系的 React UI 组件库,主要用于研发企业级中后台产品。

umi 是什么?

umi,中文可发音为乌米,是可扩展的企业级前端应用框架。Umi 以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。然后配以生命周期完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能扩展和业务需求。

dva 是什么?

dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。

目标

使用React+AntD+Dva+Umi构建一个非常简单CRUD应用程序,以便您更好地了解它的工作方式。

完整的 demo 代码请访问 https://github.com/zcqiand/crud

演示

列表页面

QQ20200402145823.png

添加页面

QQ20200402150132.png

编辑页面

QQ20200402150153.png

构建

脚手架创建React应用

先找个地方建个空目录,通过官方工具创建项目

mkdir demo1 && cd demo1
yarn create @umijs/umi-app

安装依赖

yarn

启动项目

yarn start

一旦运行此命令,http://localhost:8000新的React应用程序将弹出一个新窗口。

QQ20200402151735.png

构建路由

修改.umirc.js代码

export default {
routes: [
    {
    path: '/',
    component: '../layouts/index',
    routes: [
        { path: '/', component: '../pages/goods/index' },
        { path: '/goods/add', component: '../pages/goods/add' },
        { path: '/goods/:id/edit', component: '../pages/goods/edit' }
    ]
    }
],
dva: {},
antd: {},
proxy: {
    "/api": {
    target: "http://localhost:59367/",
    changeOrigin: true,
    pathRewrite: {
        '^/api': '',
    },
    },
},
}

构建列表页面

import React, { Component } from "react";
import { Table, Popconfirm, Button } from 'antd';
import { connect } from 'umi';


@connect(state => ({
items: state.goods.items,
}))
export default class GoodsIndex extends Component {
constructor(props) {
    super(props)
}

componentDidMount() {
    this.queryGoods()
}

queryGoods() {
    console.log('queryGoods');
    this.props.dispatch({
    type: 'goods/query',
    })
}

addGoods = () => {
    console.log('addGoods');
    window.location.pathname = "/goods/add";
}

editGoods = (id) => {
    console.log('editGoods');
    window.location.pathname = `/goods/${id}/edit`;
}

deleteGoods = (id) => {
    console.log('deleteGoods:' + id);
    this.props.dispatch({
    type: 'goods/delete',
    payload: id
    })
}

render() {
    const items = this.props.items || []
    console.log(items)

    const columns = [
    {
        title: '名称',
        dataIndex: 'Name',
        key: 'Name',
    },
    {
        title: '描述',
        dataIndex: 'Describe',
        key: 'Describe',
    },
    {
        title: '操作',
        key: 'action',
        render: (record) => (
        <div>
            <Button type="link" onClick={() => this.editGoods(record.Id)}>编辑</Button>
            <Popconfirm title="是否删除记录?" onConfirm={() => this.deleteGoods(record.Id)}>
            <Button type="link">删除</Button>
            </Popconfirm>
        </div >
        ),
    },
    ];

    return (
    <div>
        <Button type="primary" onClick={this.addGoods}>添加</Button>
        <Table columns={columns} dataSource={items} />
    </div >
    )
}
}

构建添加页面

import React, { Component } from "react";
import { Form, Input, Button } from 'antd';
import { connect } from 'umi';

const { TextArea } = Input;

@connect()
export default class GoodsAdd extends Component {
render() {
    const onFinish = values => {
    console.log('onFinish:', values);      
    this.props.dispatch({
        type: 'goods/create',
        payload: values
    })
    };

    const onFinishFailed = errorInfo => {
    console.log('onFinishFailed:', errorInfo);
    };

    return (
    <Form
        name="basic"
        onFinish={onFinish}
        onFinishFailed={onFinishFailed}
    >
        <Form.Item
        label="名称"
        name="Name"
        rules={[{ required: true, message: '请填写名称!' }]}
        >
        <Input />
        </Form.Item>

        <Form.Item
        label="描述"
        name="Describe"
        rules={[{ required: true, message: '请填写你描述!' }]}
        >
        <TextArea rows={4} />
        </Form.Item>

        <Form.Item>
        <Button type="primary" htmlType="submit" onClick={this.createGoods}>
            新增
        </Button>
        </Form.Item>
    </Form>
    )
}
}

构建编辑页面

import React, { Component } from "react";
import { Form, Input, Button } from 'antd';
import { connect } from 'umi';

const { TextArea } = Input;

@connect(state => ({
item: state.goods.item,
}))
export default class GoodsEdit extends Component {
formRef = React.createRef();
constructor(props) {
    super(props)
}

componentDidMount() {
    this.getGoods(this.props.match.params.id)
}

componentDidUpdate() {
    const item = this.props.item
    this.formRef.current.setFieldsValue({
    Name: item.Name,
    Describe: item.Describe,
    });
}

getGoods(id) {
    this.props.dispatch({
    type: 'goods/get',
    payload: id
    })    
}

render() {    
    const onFinish = values => {
    console.log('onFinish:', values);
    let param = values
    param.Id = this.props.match.params.id
    this.props.dispatch({
        type: 'goods/update',
        payload: param
    })
    };

    const onFinishFailed = errorInfo => {
    console.log('onFinishFailed:', errorInfo);
    };

    return (      
    <Form
        name="basic"
        ref={this.formRef}
        onFinish={onFinish}
        onFinishFailed={onFinishFailed}
    >
        <Form.Item
        label="名称"
        name="Name"
        rules={[{ required: true, message: '请填写名称!' }]}
        >
        <Input />
        </Form.Item>

        <Form.Item
        label="描述"
        name="Describe"
        rules={[{ required: true, message: '请填写你描述!' }]}
        >
        <TextArea rows={4} />
        </Form.Item>

        <Form.Item>
        <Button type="primary" htmlType="submit" onClick={this.createGoods}>
        更新
        </Button>
        </Form.Item>
    </Form>
    )
}
}

构建Model

import { queryGoods, getGoods, createGoods, updateGoods, deleteGoods } from '../services/goods';
import { history } from 'umi';

export default {
namespace: 'goods',
state: {
    items: [], //列表记录
    item: {}, //当前记录
},
effects: {
    *query(_, { call, put }) {
    const ret = yield call(queryGoods);
    console.log(ret)
    if (ret && ret.Code === 0) {
        yield put({
        type: 'querySuccess',
        payload: {
            items: ret.Result
        },
        });
    }
    },
    *get({ payload }, { call, put }) {
    console.log(payload)
    const ret = yield call(getGoods, payload);
    console.log(ret)
    if (ret && ret.Code === 0) {
        yield put({
        type: 'getSuccess',
        payload: {
            item: ret.Result
        },
        });
    }
    },
    *create({ payload }, { call, put }) {
    console.log(payload)
    const ret = yield call(createGoods, payload);
    if (ret && ret.Code === 0) {
        history.push('/');
    }
    },
    *update({ payload }, { call, put }) {
    console.log(payload)
    const ret = yield call(updateGoods, payload.Id, payload);
    if (ret && ret.Code === 0) {
        history.push('/');
    }
    },
    *delete({ payload }, { call, put }) {
    console.log(payload)
    const ret = yield call(deleteGoods, payload);
    if (ret && ret.Code === 0) {
        yield put({
        type: 'deleteSuccess',
        payload: {
            Id: payload
        },
        });
    }
    },
},
reducers: {
    querySuccess(state, action) {
    return { ...state, ...action.payload };
    },
    getSuccess(state, action) {
    return { ...state, ...action.payload };
    },
    deleteSuccess(state, { payload: o }) {
    const items =  state.items.filter(item => item.Id !== o.Id);
    return { ...state, items };
    },
},
};

构建Service

import request from '../../../utils/request';
import qs from 'qs';

export function queryGoods() {
return request(`/api/examplemodule/goods`);
}

export function getGoods(id) {
return request(`/api/examplemodule/goods/${id}`);
}
export function createGoods(param) {
return request(`/api/examplemodule/goods/create`, {
    method: 'post',
    body: qs.stringify(param),
    headers: {
    "Content-Type": "application/x-www-form-urlencoded"
    }
});
}

export function updateGoods(id, param) {
return request(`/api/examplemodule/goods/${id}/update`, {
    method: 'post',
    body: qs.stringify(param),
    headers: {
    "Content-Type": "application/x-www-form-urlencoded"
    }
});
}

export function deleteGoods(id) {
return request(`/api/examplemodule/goods/${id}/delete`, {
    method: 'post',
});
}

参考

相关文章

网友评论

      本文标题:使用React+AntD+Dva+Umi构建CRUD(增删改查)

      本文链接:https://www.haomeiwen.com/subject/npdomhtx.html