zoukankan      html  css  js  c++  java
  • 【react】react-bookManager

    作者可能是本意想要做一个图书管理系统,不过添加书籍的时候报错,所以简单的页面我们简单的看看
    先上github地址:https://github.com/hesisi/react-bookManager
    看package.json文件是有用到中间件的,心里多了点期待,也许帮它修复好bug也行呢
    先看页面

    很简单,可能只是框架的效果吧
    看看代码

    //srcindex.js
    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import registerServiceWorker from './registerServiceWorker';
    // 引入中间件
    import {Provider} from 'react-redux';
    // reducer
    import bookReducer from './reducers/bookReducer';
    // userreducer
    import userReducer from './reducers/userReducer';
    import { createStore ,applyMiddleware ,combineReducers } from 'redux';
    import thunk from 'redux-thunk';
    
    const rootReducer = combineReducers({
        bookReducer,
        userReducer
    });
    //store
    const store = createStore(rootReducer,applyMiddleware(thunk));
    
    ReactDOM.render(
        <Provider store={store}>
            <App />
        </Provider>,
        document.getElementById('root')
    );
    
    store.subscribe(() => {
        console.log("================监听store变化:"+JSON.stringify(store));
    });
    
    registerServiceWorker();
    
    //app.js中定义了几个去不同页面的路由
    import React from 'react'; 
    import ReactDOM from 'react-dom'; 
    import HomeLayout from './layouts/HomeLayout';
    
    import BookAdd from './components/BookAdd';
    import BookListContainer from './containers/BookList';
    import UserAdd from './components/UserAdd';
    import UserListContainer from './components/UserList';
    import FileAdd from './components/FileAdd';
    import FileList from './components/FileList';
    import { BrowserRouter as Router ,Route } from 'react-router-dom';
    import registerServiceWorker from './registerServiceWorker'; 
    
    {/*
        store的数据结构
    
        store = {
            bookReducer : {
                data : [{},{}]
            },
    
            userReducer : {
                data : [{},{}]
            }
        }
    
    */}
    
    class App extends React.Component{
        render (){
            return (
                <Router>
                    <HomeLayout>  
                        <div>
                            <Route path="/book/add" component={BookAdd}></Route>
                            <Route path="/book/list" component={BookListContainer}></Route>
                            <Route path="/user/add" component={UserAdd} ></Route>
                            <Route path="/user/list" component={UserListContainer}></Route>
                            <Route path="/file/add" component={FileAdd}></Route>
                            <Route path="/file/list" component={FileList}></Route>
                        </div>
                    </HomeLayout>
                </Router>
            );
        
        }
    }
    
    
    export default App;
    

    接下来我们根据路由看一下页面

    //user/list
    //应该是数据部分请求没有接口,所以没有数据渲染出来
    import React from 'react';
    import { Table ,Button ,Popconfirm ,Divider ,Modal} from 'antd';
    import {initUserAction} from "../actions/userActions";
    import PropTypes from 'prop-types';
    import FormLayout from './Form';
    import SearchInput from '../components/SearchInput';
    
    class UserList extends React.Component{
        constructor(props){
            super(props);
    
            this.state = {
                title : "",
                visible : false,
                confirmLoading : false,
                formData : {},
                operation : ""
            };
        }
    
        componentWillMount(){
            const {store} = this.context;
            fetch("http://localhost:3001/user")
            .then(res => res.json())
            .then(res => {
                store.dispatch(initUserAction(res));
            });
        }
    
        //点击编辑
        editHandle(record){
            //record:{"id":10002,"name":"PHP从入门到死亡","price":89,"owner_id":10002}
            this.setState({
                title : "修改",
                visible : true,
                formData : record,
                operation : "edit"   //编辑状态
            });
                 
        }
    
        //在子组件中点击添加需要调用的props函数
        addHandle(){
            this.setState({
                title : "添加",
                visible : true,
                operation : "add"
            });
        }
    
        //Form表单点击确定的时候要执行的props函数,动态获取Input组件的值
        comfirmHandle(data){
            this.setState({
                visible : false,
                formData : data
            })
    
            let { operation } = this.state;
            const { formData } = this.state;
    
            if(operation === "edit"){
                this.props.editBook(formData);
            }else{
                this.props.addBook(formData);
            }
            
        }
    
        //取消
        cancelHandle(){
            this.setState({
                visible : false,
                formData : {}   //点击取消置空record对象
            });
        }
    
        
    
        render(){
            const { userList, deleteUser } = this.props; //connect传递的props
            const { title,visible ,confirmLoading } = this.state;
            console.log("===================userlist props:"+JSON.stringify(this.props));
            
            const columns = [{
                title : '用户编号',
                dataIndex : 'id'
            },{
                title : '名称',
                dataIndex : 'name'
            },{
                title:'学号',
                dataIndex:'student_id'
            },{
                title:'性别',
                dataIndex:'gender'
            },{
                title:'操作',
                render : (text,record) => (
                    <span type="ghost">
                        <Button size="small" onClick={() => this.editHandle(record)}>编辑</Button>
                        <Divider type="vertical" />
                        <Popconfirm title="确定要删除吗?" onConfirm={() => deleteUser(record)}>
                            <Button size="small" >删除</Button>
                        </Popconfirm>
                    </span>
                )
            }];
    
            return (
                <div>
                    <div>
                        <SearchInput addHandle={this.addHandle.bind(this)}/>
                    </div>
                    <Table columns={columns} dataSource={userList}/>
                    <Modal 
                        title={title}
                        visible= {visible}
                        confirmLoading = {confirmLoading}
                        onCancel = {() => this.cancelHandle()}
                        footer = {null}
                    >
                        <FormLayout record={this.state.formData} comfirmHandle={this.comfirmHandle.bind(this)}/>
                    </Modal>
                </div>
            );
        }
    }
    
    UserList.contextTypes = {
        store: PropTypes.object.isRequired
    };
    
    export default UserList;
    
    //srcactionsuserActions.js
    const INIT_USER_ACTION = "INIT_USER_ACTION";
    const ADD_USER_ACTION = "ADD_USER_ACTION";
    const DELETE_USER_ACTION = "DELETE_USER_ACTION";
    const UPDATE_USER_ACTION = "UPDATE_USER_ACTION";
    
    export const initUserAction = (data) => {
        return {
            type : INIT_USER_ACTION,
            payload : data
        }
    }
    
    export  const addUserAction = (data) => {
        return {
            type : ADD_USER_ACTION,
            payload : data
        }
    }
    
    export const deleteUserAction = (id) => {
        return {
            type : DELETE_USER_ACTION,
            payload : id
        }
    }
    
    export const updateUserAction = (data) => {
        return {
            type : UPDATE_USER_ACTION,
            payload : data
        }
    }
    
    //srccomponentsSearchInput.js
    import React from 'react';
    import { Input ,Row ,Col ,Button } from 'antd'; 
    
    const Search = Input.Search;
    class SearchInput extends React.Component{
        render(){
            return (
                //利用栅格系统,使searchInput和button在同一行
                <div>
                    <Row>
                        <Col span={10}>
                            <Search
                                placeholder="输入编号查询..."
                                onSearch = {value => console.log(value)}
                                style={{ 400 ,marginBottom :20}}
                                enterButton = "搜索"
                            />
                        </Col>
                        <Col span={3}>
                            <Button type="primary" onClick={this.props.addHandle}>添加</Button>
                        </Col>
                    </Row>
                    
                </div>
            );
        }
    }
    
    export default SearchInput;
    
    //srccomponentsForm.js
    import React from 'react';
    import { Form , Input , Button } from 'antd';
    
    const FormItem = Form.Item;
    const formItemLayout = {
        labelCol : {span : 5},
        wrapperCol : {span : 15} 
    };
    class FormLayout extends React.Component{
        
        handleSubmit(e){
            e.preventDefault();
            const comfirmHandle =  this.props.comfirmHandle;
            const fieldsValue = this.props.form.getFieldsValue();
    
            //表单校验
            this.props.form.validateFields(function(errors,value){
                //校验通过
                if(!errors){
                    comfirmHandle(fieldsValue); //获取当前表单数据并当做回调函数的参数传递给父组件
                }
            });
           
        }
    
        render(){
            const { getFieldDecorator ,getFeildsValue } = this.props.form;
            const { record } = this.props;
    
            return (
                <Form onSubmit= {this.handleSubmit.bind(this)}>
                    <FormItem label="编号" {...formItemLayout} style={{display:'none'}}>
                        {getFieldDecorator('id', { 
                            initialValue : record ? record.id : ""
                        })(
                            <Input />
                        )}
                    </FormItem>
                    <FormItem label="名称" {...formItemLayout}>
                        {getFieldDecorator('name', { 
                            rules: [{ 
                                required: true, message: '请输入书籍名称!'
                            }],
                            initialValue : record ? record.name : ""
                        })(
                            <Input placeholder="请输入书籍名称"/>
                        )}
                    </FormItem>
                    <FormItem label="价格"  {...formItemLayout}>
                        {getFieldDecorator('price', {
                            rules: [{ 
                                required: true, message: '请输入价格!' 
                            },{
                                pattern : /(^[1-9](d+)?(.d{1,2})?$)|(^(0){1}$)|(^d.d{1,2}?$)/,message:'请输入正确的金额'
                            }],
                            initialValue : record ?  record.price : ""
                        })(
                            <Input placeholder="请输入价格" />
                        )}
                    </FormItem>
                    <FormItem label="借阅者编号"  {...formItemLayout}>
                        {getFieldDecorator('owner_id', { 
                            rules: [{ 
                                required: true, message: '请输入借阅者编号!' 
                            },{
                                pattern : /^(d{5})$/,message:'请输入5位数字'
                            }],
                            initialValue : record ? record.owner_id :""
                        })(
                            <Input placeholder="请输入借阅者编号"/>
                        )}
                    </FormItem>
                    <FormItem wrapperCol={{ span: 10, offset: 10 }}>
                        <Button type="primary" htmlType="submit">
                            确定
                        </Button>
                    </FormItem>
                </Form>
            );
        }
    }
    
    export default FormLayout = Form.create()(FormLayout);
    

    //srccomponentsUserAdd.js
    import React from 'react';
    
    class UserAdd extends React.Component{
        render(){
            return (
                <div>添加用户</div>
            );
        }
    }
    
    export default UserAdd;
    

    //srccomponentsBookList.js
    import React from 'react';
    import { Table, Button, Popconfirm, Divider, Modal, message} from 'antd';
    import {initBookAction} from "../actions/bookActions";
    import PropTypes from 'prop-types';
    import FormLayout from './Form';
    import SearchInput from '../components/SearchInput';
    
    class BookList extends React.Component{
        constructor(props){
            super(props);
    
            this.state = {
                title : "",
                visible : false,
                confirmLoading : false,
                formData : {},
                operation : ""
            };
        }
    
        componentWillMount(){
            const {store} = this.context;
            fetch("http://localhost:3001/book")
            .then(res => res.json())
            .then(res => {
                store.dispatch(initBookAction(res));
            });
        }
    
        //点击编辑
        editHandle(record){
            //record:{"id":10002,"name":"PHP从入门到死亡","price":89,"owner_id":10002}
            this.setState({
                title : "修改",
                visible : true,
                formData : record,
                operation : "edit"   //编辑状态
            });     
        }
    
        //在子组件中点击添加需要调用的props函数
        addHandle(){
            this.setState({
                title : "添加",
                visible : true,
                operation : "add"
            });
        }
    
        //Form表单点击确定的时候要执行的props函数,动态获取Input组件的值
        comfirmHandle(data){
            
            //这个地方要注意setState是异步的,
            //只有在重新render的时候state的值才会被重新修改
            //所以通过回调函数解决
    
            this.setState({
                visible : false,
                formData : data
            },() => {
                let { operation } = this.state;
                const { formData } = this.state;
        
                if(operation === "edit"){
                    this.props.editBook(formData);
                }else{
                    this.props.addBook(formData);
                    //this.props.history.push("/book/list");                        
                }
    
                //处理完之后再次置空
                this.setState({
                    formData : {}
                })
                
            })  
        }
    
        //取消
        cancelHandle(){
            this.setState({
                visible : false,
                formData : {}   //点击取消置空record对象
            });
        }
    
        render(){
            const { bookList, deleteBook } = this.props; //connect传递的props
            const { title,visible ,confirmLoading } = this.state;
            
            const columns = [{
                title : '图书编号',
                dataIndex : 'id',
                key : 'id'
            },{
                title : '名称',
                dataIndex : 'name',
                key : 'name'
            },{
                title:'价格',
                dataIndex:'price',
                key : 'price'
            },{
                title:'借阅人编号',
                dataIndex:'owner_id',
                key : 'owner_id'
            },{
                title:'操作',
                key : 'operation',
                render : (text,record) => (
                    <span type="ghost">
                        <Button size="small" onClick={() => this.editHandle(record)}>编辑</Button>
                        <Divider type="vertical" />
                        <Popconfirm title="确定要删除吗?" onConfirm={() => deleteBook(record.id)}>
                            <Button size="small" >删除</Button>
                        </Popconfirm>
                    </span>
                )
            }];
    
            return (
                <div>
                    <div>
                        <SearchInput addHandle={this.addHandle.bind(this)}/>
                    </div>
                    <Table columns={columns} dataSource={bookList} rowKey="id"/>
                    <Modal 
                        title={title}
                        visible= {visible}
                        confirmLoading = {confirmLoading}
                        onCancel = {this.cancelHandle.bind(this)}
                        footer = {null}
                        destroyOnClose
                    >
                        <FormLayout record={this.state.formData} comfirmHandle={this.comfirmHandle.bind(this)}/>
                    </Modal>
                </div>
            );
        }
    }
    
    BookList.contextTypes = {
        store: PropTypes.object.isRequired,
        router:PropTypes.object.isRequired
    };
    
    export default BookList;
    

    import React from 'react';
    import Form from './Form';
    class BookAdd extends React.Component{
        render(){
            return (
                <div>
                    <Form/>
                </div>
            );
        }
    }
    
    export default BookAdd;
    
    //srccomponentsForm.js
    import React from 'react';
    import { Form , Input , Button } from 'antd';
    
    const FormItem = Form.Item;
    const formItemLayout = {
        labelCol : {span : 5},
        wrapperCol : {span : 15} 
    };
    class FormLayout extends React.Component{
        
        handleSubmit(e){
            e.preventDefault();
            const comfirmHandle =  this.props.comfirmHandle;
            const fieldsValue = this.props.form.getFieldsValue();
    
            //表单校验
            this.props.form.validateFields(function(errors,value){
                //校验通过
                if(!errors){
                    comfirmHandle(fieldsValue); //获取当前表单数据并当做回调函数的参数传递给父组件
                }
            });
           
        }
    
        render(){
            const { getFieldDecorator ,getFeildsValue } = this.props.form;
            const { record } = this.props;
    
            return (
                <Form onSubmit= {this.handleSubmit.bind(this)}>
                    <FormItem label="编号" {...formItemLayout} style={{display:'none'}}>
                        {getFieldDecorator('id', { 
                            initialValue : record ? record.id : ""
                        })(
                            <Input />
                        )}
                    </FormItem>
                    <FormItem label="名称" {...formItemLayout}>
                        {getFieldDecorator('name', { 
                            rules: [{ 
                                required: true, message: '请输入书籍名称!'
                            }],
                            initialValue : record ? record.name : ""
                        })(
                            <Input placeholder="请输入书籍名称"/>
                        )}
                    </FormItem>
                    <FormItem label="价格"  {...formItemLayout}>
                        {getFieldDecorator('price', {
                            rules: [{ 
                                required: true, message: '请输入价格!' 
                            },{
                                pattern : /(^[1-9](d+)?(.d{1,2})?$)|(^(0){1}$)|(^d.d{1,2}?$)/,message:'请输入正确的金额'
                            }],
                            initialValue : record ?  record.price : ""
                        })(
                            <Input placeholder="请输入价格" />
                        )}
                    </FormItem>
                    <FormItem label="借阅者编号"  {...formItemLayout}>
                        {getFieldDecorator('owner_id', { 
                            rules: [{ 
                                required: true, message: '请输入借阅者编号!' 
                            },{
                                pattern : /^(d{5})$/,message:'请输入5位数字'
                            }],
                            initialValue : record ? record.owner_id :""
                        })(
                            <Input placeholder="请输入借阅者编号"/>
                        )}
                    </FormItem>
                    <FormItem wrapperCol={{ span: 10, offset: 10 }}>
                        <Button type="primary" htmlType="submit">
                            确定
                        </Button>
                    </FormItem>
                </Form>
            );
        }
    }
    
    export default FormLayout = Form.create()(FormLayout);
    
    //srccontainersBookList.js
    import { connect } from 'react-redux';
    import BookList from '../components/BookList';
    import { deleteBookAction , addBookAction ,updateBookAction } from '../actions/bookActions';
    import { message } from 'antd';
    
    const mapStateToProps = (state) => {
        return {
            bookList : state.bookReducer.data
        };
    }
    
    const mapDispatchToProps = (dispatch) => {
        return {
            deleteBook : (id) => {
                //dispatch(deleteBookAction(id))
                dispatch(dispatch => {
                    fetch('http://localhost:3001/book/'+id,{
                        method : 'delete'
                    })
                    .then(res => res.json())
                    .then(res => {
                        console.log("==============删除返回参数:"+JSON.stringify(res));
                        dispatch(deleteBookAction(id));
                        message.success("删除记录成功");
                    })
                    .catch(err => {
                        message.error("删除记录失败");
                    })
                })
            },
            addBook : (data) => {
                //dispatch(addBookAction(data))
    
                dispatch(dispatch => {
                    fetch('http://localhost:3001/book',{
                        method : 'post',
                        body : JSON.stringify({
                            name : data.name,
                            price : data.price,
                            owner_id : data.owner_id
                        }),
                        headers: {
                            'Content-Type': 'application/json'
                        }
                    })
                    .then(res => res.json)
                    .then(res => {
                        console.log("==============添加返回参数:"+JSON.stringify(res));
                        dispatch(addBookAction(data))
                        //message.success("添加记录成功");
                        window.location.reload();
                    })
                    .catch(error => {
                        message.error("添加记录失败")
                    })
                })
            },
            editBook : (data) => {
                //dispatch(updateBookAction(data))
                dispatch(dispatch => {
                    fetch('http://localhost:3001/book/'+data.id,{
                        method : 'put',
                        body : JSON.stringify({
                            name : data.name,
                            price : data.price,
                            owner_id : data.owner_id
                        }),
                        headers : {
                            'Content-Type' : 'application/json'
                        }
                    })
                    .then(res => res.json())
                    .then(res => {
                        console.log("==============修改返回参数:"+JSON.stringify(res));
                        dispatch(updateBookAction(data))
                        message.success("修改记录成功")
                    })
                    .catch(error => {
                        message.error("修改记录失败")
                    })
                })
            }
        }
    }
    const BookListContainer = connect(
        mapStateToProps,
        mapDispatchToProps
    )(BookList);
    
    export default BookListContainer;
    
    //srccontainersUserList.js
    import { connect } from 'react-redux';
    import UserList from '../components/UserList';
    import { deleteUserAction ,addUserAction ,updateUserAction } from '../actions/userActions';
    
    const mapStateToProps = (state) => {
        return {
            userList : state.userReducer.data
        };
    }
    
    const mapDispatchToProps = (dispatch) => {
        return {
            deleteUser : (id) => {
                dispatch(deleteUserAction(id))
            },
            addUser : (data) => {
                dispatch(addUserAction(data))
            },
            editUser : (data) => {
                dispatch(updateUserAction(data))
            }
        }
    }
    const UserListContainer = connect(
        mapStateToProps,
        mapDispatchToProps
    )(UserList);
    
    export default UserListContainer;
    
  • 相关阅读:
    spring自动注入--------
    Spring p 命名和c命名(不常用)
    反射笔记-----------------------------
    -----------------------spring 事务------------------------
    --------------------------------MaBatis动态sql--------------------------
    让 div中的div垂直居中的方法!!同样是抄袭来的(*^__^*)
    div中的img垂直居中的方法,最简单! 偷学来的,,,不要说我抄袭啊(*^__^*)
    关于transform-style:preserve-3d的些许明了
    转换 transform
    计数器counter
  • 原文地址:https://www.cnblogs.com/smart-girl/p/10974460.html
Copyright © 2011-2022 走看看