用dvaJS實現todolist(增刪改)

  效果圖css

  

  這幾天在看dvaJS,dva 首先是一個基於 redux和 redux-saga的數據流方案,而後爲了簡化開發體驗,dva 還額外內置了 react-router和 fetch,因此也能夠理解爲一個輕量級的應用框架。html

要想學好dva你要對ES6有一些瞭解,對React有些瞭解,上手的時候就比較容易。react

  寫這個todolist首先得安裝dva-cligit

  經過npm安裝dva-cligithub

    npm install dva-cli -g npm

  安裝完成後輸入dva -v查看版本號redux

  建立新應用服務器

  安裝完dva-cli後,能夠在命令行訪問到dva命令antd

  經過dva new dva-quickstart建立新應用react-router

  這會建立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

相關文章
相關標籤/搜索