美文网首页码农的世界
dva开发一个cnode网站(2)

dva开发一个cnode网站(2)

作者: 独见晓焉 | 来源:发表于2018-12-16 11:13 被阅读0次

    今天来学习第二节课程,完成列表数据的展示

    效果:


    首页列表

    1. 新建ListData组件

    import React , { Component }from 'react';
    import { List, Avatar, Icon, Spin } from 'antd';
    import PropTypes from 'prop-types';
    import { connect } from 'dva';
    
    class ListData extends Component{
    
     render() {
        const IconText = ({ type, text }) => (
      <span>
        <Icon type={type} style={{ marginRight: 8 }} />
        {text}
      </span>
    );
    console.log(this.props)
      return (
        <Spin spinning={this.props.loading.global} 
        size='large'
        tip="数据正在加载中">
      <List
        itemLayout="vertical"
        size="large"
        pagination={{
          onChange: (page) => {
            console.log(page);
                    this.props.dispatch({ type: 'listdata/query', payload: { page:page,pageSize:this.props.pageSize,type:'all'} })
          },
          pageSize: this.props.pageSize,
                total:500
        }}
        dataSource={this.props.pageData}
        renderItem={item => (
          <List.Item
            key={item.title}
            actions={[<IconText type="star-o" text={item.visit_count} />, <IconText type="like-o" text={item.visit_count} />, <IconText type="message" text={item.reply_count} />]}
          >
            <List.Item.Meta
              avatar={<Avatar src={item.author.avatar_url} />}
              title={<a>{item.author.loginname}</a>}
              description={item.create_at}
            />
            {item.title}
          </List.Item>
        )}
            
      />
        </Spin>
      );
        }
        
         componentWillMount () {
             const { dispatch, type, pageSize,page} = this.props
              dispatch({ type: 'listdata/query', payload: { page,pageSize,type} })
        }
    };
    
    ListData.propTypes = {
        type: PropTypes.string.isRequired,
        pageSize: PropTypes.number.isRequired,
    };
    
    function mapStateToProps(state) {
        const {pageSize,type,page,pageData} = state.listdata;
      return {
          pageSize,
          type,
            page,
            pageData,
            loading:state.loading
      };
    }
    
    // export default ListData;
    export default connect(mapStateToProps)(ListData);
    

    用到了antd中的List, Avatar, Icon, Spin 四个ui组件。

    • List 列表
    • Avatar 头像
    • Icon 图标
    • Spin 数据加载
    • pagination 分页
      componentWillMount 周期中获取列表数据,mapStateToProps 将model中的state数据和组件的props绑定,利用connect将两者连接。这样只要state中的数据发生变化,props就会发生变化,view视图就会重新渲染。

    2. 创建组件的model listdata.js

    import * as listService from '../services/list';
    export default {
      namespace: 'listdata',
      state:{
          pageSize:20,
          page:1,
          pageData: [],
          type: 'all'
      },
        effects: {
            *query({ payload: { page,pageSize,type } }, { call, put }) {
                const result = yield call(listService.query, { page,pageSize,type })
                            yield put({
                    type: 'updateData',
                    payload: {
                        result,
                                            page,
                                            pageSize,
                                            type
                    }
                })
            }
        },
      reducers: {
        'updateData'(state, { payload: data }) {
                let r = data.result.data.data
                let {pageSize,page,type} = data
            return {...state,pageSize,page,pageData:r,type}
        }
      },
        subscriptions : {
            setup({ dispatch, history }) {
    //       return history.listen(({ pathname, query }) => {
    //         if (pathname === '/') {
    //           dispatch({ type: 'query', payload: { page:1,pageSize:10,type:'all' } });
    //         }
    //       });
        }
    },
    }; 
    

    注意申明了listdata的命名空间,在组件中绑定时要注明


    命名

    3. 创建组件的service list.js

    这里面主要写获取数据的方法,就是请求api。有点像java里的dao层,route像java里的controller层

    import request from '../utils/request';
    
    export function query({ page,pageSize,type }) {
      return request(`/api/v1/topics?page=${page}&limit=${pageSize}&tab=${type}`);
    }
    

    service会在model中的effects 中调用,effects中处理异步请求,之后action去reducers中更新state。

    4. 开启代理

    我们在本地访问cnode的api接口会有跨域,所以要进行代理。修改.webpackrc:

    {
      "extraBabelPlugins": [
        ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }]
      ],
      "proxy": {
            "/api": {
                "target": "https://cnodejs.org/",
                "changeOrigin": true,
                "pathRewrite": { "^/api": "/api" }
            }
        }
    }
    

    cnode api说明:https://cnodejs.org/api

    5. 在首页使用组件

    import React from 'react';
    import { connect } from 'dva';
    import MyHeader from '../components/MyHeader';
    import ListData from '../components/ListData';
    
    
    function IndexPage() {
      return (
        <div>
          <MyHeader keys={['index']}/>
                <div style={{paddingTop:20,paddingLeft:100,paddingRight:100,paddingBottom:50}}>
          <ListData type='all' pageSize='10'/>
                </div>
        </div>
      );
    }
    
    IndexPage.propTypes = {
    };
    
    export default connect()(IndexPage);
    

    好了现在你就可以看到效果了。
    没解决的坑:
    分页组件的使用,因为他是按总的数据记录以及每页数据量来自动分页的,而cnode的api是按页码和每页数据量来直接返回数据,所以没法知道total。因此我默认写了total=“500”.
    欢迎关注我的公众号mike啥都想搞,学习更多内容。

    mike啥都想搞

    下期预告:

    详情功能组件完成

    相关文章

      网友评论

        本文标题:dva开发一个cnode网站(2)

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