用dvaJS实现todolist(增删改)

  效果图

  

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

要想学好dva你要对ES6有一些了解,对React有些了解,上手的时候就比较容易。

  写这个todolist首先得安装dva-cli

  通过npm安装dva-cli

    npm install dva-cli -g 

  安装完成后输入dva -v查看版本号

  创建新应用

  安装完dva-cli后,可以在命令行访问到dva命令

  通过dva new dva-quickstart创建新应用

  这会创建dva-quickstart目录,包含项目初始化目录和文件,并提供开发服务器、构建脚本、数据mock服务、代理服务器等功能。

  然后我们cd进入dva-quickstart目录,并启动开发服务器

  cd dva-quickstart

  npm start

  components模块

  add.js

import React, { Component } from 'react'
import { Form, Input, Button, Select } from 'antd'

import { connect } from 'dva'
import styles from './input.css'
const { Option } = Select;
class Add extends Component {
    render() {
        const { getFieldDecorator } = this.props.form
        return (
            <div>
                <Form onSubmit={this.handleAdd} className={styles.form}>
                    <Form.Item label="姓名" className={styles.formItem}>
                        {getFieldDecorator('name', {
                            rules: [
                                {
                                    required: true, 
                                    message: '不能为空'
                                },
                                {
                                    pattern: /^[\u4E00-\u9FA5\uf900-\ufa2d·s]{2,20}$/,
                                    message: '输入中文名字'
                                }
                            ]
                        })(<Input width='100' />)}

                    </Form.Item>
                    <Form.Item label="年龄" className={styles.formItem}>
                        {getFieldDecorator('age', {
                            rules: [
                                {
                                    required: true, message: '不能为空'
                                },
                                {
                                    pattern: /^(?:[1-9][0-9]?|1[01][0-9]|120)$/,
                                    message: '请输入年龄'
                                }
                            ]
                        })(<Input width='100' />)}

                    </Form.Item>
                    <Form.Item label="学历" className={styles.formItem}>
                        {getFieldDecorator('xl', {
                            rules: [
                                {
                                    required: true, message: '不能为空'
                                }
                            ]
                        })(
                            <Select style={{ width: 184 }}>
                                <Option value="本科">本科</Option>
                                <Option value="硕士">硕士</Option>
                                <Option value="博士">博士</Option>
                                <Option value="专科">专科</Option>
                            </Select>
                        )}

                    </Form.Item>
                    <Form.Item className={styles.formItem}>
                        <Button htmlType="submit" type="primary">添加</Button>
                    </Form.Item>
                </Form>

            </div>
        )
    }
    handleAdd = (e) => {
        e.preventDefault();
        this.props.form.validateFields((err, values) => {
            if (!err) {
                //与后台进行数据交互
                const list = {}
                list.name = values.name
                list.age = values.age
                list.xl = values.xl
                this.props.form.setFieldsValue({ name: '', age: '', xl: '' })//点击确定让input输入框中的值为空
                this.props.dispatch({
                    type: 'todo/add',
                    payload: list
                })

            }
        })
    }
}
const mapStateToProps = (state) => {
    return {
        list: state.todo.list
    }
}

export default connect(mapStateToProps)(Form.create()(Add))

modify.js

 

import React, { Component } from 'react'
import { Form, Input, Button,Select } from 'antd'
import { connect } from 'dva'
import styles from './input.css'
const {Option} = Select
class Add extends Component {
    render() {
        console.log(this.props)
        let { list, toIndex } = this.props
        const todoList = list[toIndex]
        const { getFieldDecorator} = this.props.form
       
        return (
            <div>
                <Form onSubmit={this.handleUpdate} className={styles.form}>
                    <Form.Item label="姓名" className={styles.formItem}>
                        {getFieldDecorator('name', {
                            initialValue:todoList.name,//设置初始的值
                            rules: [
                                {
                                    required: true,
                                    message: '不能为空'
                                },
                                {
                                    pattern: /^[\u4E00-\u9FA5\uf900-\ufa2d·s]{2,20}$/,
                                    message: '输入中文名字'
                                }
                            ]
                        })(<Input/>)}

                    </Form.Item>
                    <Form.Item label="年龄" className={styles.formItem}>
                        {getFieldDecorator('age', {
                            initialValue:todoList.age,
                            rules: [
                                {
                                    required: true, message: '不能为空'
                                },
                                {
                                    pattern: /^(?:[1-9][0-9]?|1[01][0-9]|120)$/,
                                    message: '请输入年龄'
                                }
                            ]
                        })(<Input/>)}

                    </Form.Item>
                    <Form.Item label="学历" className={styles.formItem}>
                        {getFieldDecorator('xl', {
                            initialValue:todoList.xl,
                            rules: [
                                {
                                    required: true, message: '不能为空'
                                }
                            ]
                        })(
                            <Select style={{ width: 184 }}>
                            <Option value="本科">本科</Option>
                            <Option value="硕士">硕士</Option>
                            <Option value="博士">博士</Option>
                            <Option value="专科">专科</Option>
                        </Select>
                        )}

                    </Form.Item>
                    <Form.Item className={styles.formItem}> 
                        <Button htmlType="submit" type="primary">修改</Button>
                    </Form.Item>
                </Form>

            </div>
        )
    }
   
    handleUpdate = (e) => {
        e.preventDefault();
        this.props.form.validateFields((err, values) => {
            if (!err) {
                //与后台进行数据交互
                const list = {}
                list.name = values.name
                list.age = values.age
                list.xl = values.xl
                this.props.form.setFieldsValue({name:'',age:'',xl:''})//点击确定让input输入框中的值为空
                this.props.dispatch({
                    type:'todo/update',
                    payload:list
                })

            }
        })
    }
}
const mapStateToProps = (state) => {
    return {
        list: state.todo.list,
        toIndex: state.todo.toIndex
    }
}

export default connect(mapStateToProps)(Form.create()(Add))

list.js

import React, { Component } from 'react'
import { connect } from "dva"
import { Button } from 'antd'
import styles from './input.css'

class List extends Component {

    render() {
        let { list } = this.props
        return (
            <div>
                {
                    list ? list.map((item, index) => (
                        <li key={index}  className={styles.list}>
                            <div>
                            <span>姓名------{item.name}</span><br />
                            <span>年龄------{item.age}</span><br />
                            <span>学历------{item.xl}</span> <br />
                            </div>
                            
                            <div className={styles.btn}>
                            <Button htmlType='submit' type='primary' onClick={() => this.handleModify(index)}>修改</Button>
                            <Button htmlType='submit' type='danger' onClick={() => this.handleDelete(index)}>删除</Button>
                            </div>
                            
                        </li>
                    )) : ''
                }
            </div>
        )
    }
    handleModify(index) {
        this.props.dispatch({
            type: 'todo/modify',
            payload: index
        })
    }
    handleDelete(index) {
        this.props.dispatch({
            type: 'todo/delete',
            payload: index
        })
    }
}
const mapStateToProps = (state) => {
    return {
        list: state.todo.list
    }
}

export default connect(mapStateToProps)(List)

routes模块(相当于pages)

 input.js

import React, { Component } from 'react'
import Add from "../components/add"
import ListTo from './list'
import Modify from "../components/modify"
import {connect} from 'dva'

    class InputList extends Component {
        render() {
          let {flag} = this.props
            return (
                <div>
                   {
                      flag? <Add/>:<Modify/>
                   }
                        <ListTo/>
                </div>
            )
        }
    }
    const mapStateToProps=(state)=>{
        return {
            flag:state.todo.flag
        }
    }
export default connect(mapStateToProps)(InputList)

models模块

input.js

import queryString from 'query-string';
import { add } from '../services/todolist'


export default {
    namespace: 'todo',
    state: {
        list: [],
        flag:true,
        toIndex:''
    },

    subscriptions: {
        setup({ dispatch, history }) {
            history.listen(location => { })
        }
    },
    effects: {
        *add({ payload: value }, { call, put, select }) {
            const data = yield call(add, value)
            let templist = yield select(state => state.todo.list)
            let list = []
            list = list.concat(templist)
            const tempObj = {};
            tempObj.name = value.name
            tempObj.age = value.age
            tempObj.xl = value.xl
            list.push(tempObj)
            yield put({ type: 'updateState', payload: { list } })

        },
        *delete({ payload: index }, { call, put, select }) {
            const data = yield call(add, index)
            let templist = yield select(state => state.todo.list)
            let list = []
            list = list.concat(templist)
            list.splice(index, 1)
            yield put({ type: 'updateState', payload: { list } })
        },
        *modify({payload:index},{call,put,select}){
            const data = yield call(add,index)
            let templist = yield select(state => state.todo.list)
            let list = []
            list = list.concat(templist)
            yield put({ type: 'updateState', payload: { flag:false,list,toIndex:index } })
        },
        *update({payload:value},{call,put,select}){
            const data = yield call(add,value)
            let templist = yield select(state => state.todo.list)
            let toIndex = yield select(state => state.todo.toIndex)
            let list = []
            list = list.concat(templist)
            list.splice(toIndex,1,value)
            yield put({ type: 'updateState', payload: { flag:true,list } })
        },
        
    },
    reducers: {
        updateState(state, action) {
            return { ...state, ...action.payload }
        }
    },

}

在根目录下的index.js里注册一下models

 同样是在根目录下的router.js里注册路由

欢迎评论,共同交流,一起进步

源码链接:gitHub

posted @ 2019-10-24 17:15  SHY13  阅读(703)  评论(0编辑  收藏  举报