美文网首页
13.项目实战:Header组件开发(五)

13.项目实战:Header组件开发(五)

作者: 小二的学习日记 | 来源:发表于2020-07-20 16:18 被阅读0次

    热门搜索换页功能实现

    这次,我们想实现一个,点击“换一批”按钮,下面的数据就会分组刷新的功能。

    image.png
    我们修改了模拟接口,把数据改成了20个,然后增加了totalPage(总页数字段)和page(当前页字段),一边数组数据是个一组的分包。
    这一节改动的地方比较多,比较零散,但是围绕着redux进行的,没有什么难度。所以我仅仅贴出了代码。
    1.增加要用到的action的type常量
    //===>src/common/header/store/constants.js
    ...
    export const MOUSE_ENTER = 'header/MOUSE_ENTER'
    export const MOUSE_LEAVE = 'header/MOUSE_LEAVE'
    export const CHANGE_PAGE = 'header/CHANGE_PAGE'
    

    2.编写相关功能的actionCreators.js

    //===>src/common/header/store/actionCreators.js
    import *  as constants from './constants'
    import axios from 'axios'
    import { fromJS } from 'immutable'
    ...
    export const mouseEnter = () => ({
        type: constants.MOUSE_ENTER
    })
    
    export const mouseLeave = () => ({
        type: constants.MOUSE_LEAVE
    })
    
    export const changePage = (page) => ({
        type: constants.CHANGE_PAGE,
        page
    })
    
    const changeList = (data) => ({
        type: constants.CHANGE_LIST,
        data: fromJS(data),
        totalPage: Math.ceil(data.length / 10)
    })
    ...
    

    3.在reducer里改变数据
    state.merge({})可以实现多个数据一起改。

    //===>src/common/header/store/reducer.js
    import *  as constants from './constants'
    import { fromJS } from 'immutable'
    
    const defaultState = fromJS({
        focused: false,
        mouseIn: false,
        list: [],
        page: 1,
        totalPage: 1
    })
    
    export default (state = defaultState, action) => {
    
        switch (action.type) {
            case constants.SEARCH_FOCUS:
                return state.set('focused', true)
            case constants.SEARCH_BLUR:
                return state.set('focused', false)
            case constants.CHANGE_LIST:
                return state.merge({
                    list: action.data,
                    totalPage: action.totalPage
                })
            case constants.MOUSE_ENTER:
                return state.set('mouseIn', true)
            case constants.MOUSE_LEAVE:
                return state.set('mouseIn', false)
            case constants.CHANGE_PAGE:
                return state.set('page', action.page)
            default:
                return state
        }
    }
    

    4.最后,还是要贴出Header组件的全代码

    //===>src/common/header/index.js
    import React, { Component, Fragment } from 'react'
    import { CSSTransition } from 'react-transition-group'
    import {
        HeaderWrapper,
        Logo,
        Nav,
        NavItem,
        SearchWrapper,
        NavSearch,
        SearchInfo,
        SearchInfoTitle,
        SearchInfoSwitch,
        SearchInfoList,
        SearchInfoItem,
        Addition,
        Button
    } from './style'
    import { IconFontStyle } from '../../statics/iconfont/iconfont';
    import { connect } from 'react-redux';
    import { actionCreators } from './store';
    
    class Header extends Component {
    
        getListArea() {
            const { focused, list, page, totalPage, mouseIn, handleMouseEnter, handleMouseLeave, handleChangePage } = this.props
            const newList = list.toJS()
            const pageList = []
            if (newList.length) {
                for (let i = ((page - 1) * 10); i < page * 10; i++) {
                    pageList.push(
                        <SearchInfoItem key={newList[i]}>{newList[i]}</SearchInfoItem>
                    )
                }
            }
            if (focused || mouseIn) {
                return (
                    <SearchInfo onMouseEnter={handleMouseEnter}
                        onMouseLeave={handleMouseLeave}>
                        <SearchInfoTitle>
                            热门搜索
                            <SearchInfoSwitch onClick={() => handleChangePage(page, totalPage)}>换一批</SearchInfoSwitch>
                        </SearchInfoTitle>
                        <SearchInfoList>
                            {pageList}
                        </SearchInfoList>
                    </SearchInfo>
                )
            } else {
                return null;
            }
        }
    
        render() {
            const { focused, handleInputFocus, handleInputBlur } = this.props
            return (
                <Fragment>
                    <IconFontStyle />
                    <HeaderWrapper>
                        <Logo />
                        <Nav>
                            <NavItem className='left'>首页</NavItem>
                            <NavItem className='left'>下载App</NavItem>
                            <NavItem className='right'>登录</NavItem>
                            <NavItem className='right'>
                                <span className="iconfont">&#xe636;</span>
                            </NavItem>
                            <SearchWrapper>
                                <CSSTransition
                                    in={focused}
                                    timeout={200}
                                    classNames="slide">
                                    <NavSearch
                                        className={focused ? 'focused' : ''}
                                        onFocus={handleInputFocus}
                                        onBlur={handleInputBlur}>
                                    </NavSearch>
                                </CSSTransition>
                                <span className={focused ? 'focused iconfont' : 'iconfont'}>&#xe662;</span>
                                {this.getListArea()}
                            </SearchWrapper>
                            <Addition>
                                <Button className='writting'>
                                    <span className="iconfont">&#xe6e5;</span>写文章
                                </Button>
                                <Button className='reg'>注册</Button>
                            </Addition>
                        </Nav>
                    </HeaderWrapper>
                </Fragment>
            )
        }
    }
    
    const mapStateToProps = (state) => {
        return {
            // focused: state.get('header').get('focused')
            focused: state.getIn(['header', 'focused']),
            list: state.getIn(['header', 'list']),
            page: state.getIn(['header', 'page']),
            totalPage: state.getIn(['header', 'totalPage']),
            mouseIn: state.getIn(['header', 'mouseIn'])
        }
    }
    
    const mapDispatchToProps = (dispatch) => {
        return {
            handleInputFocus() {
                dispatch(actionCreators.getList())
                dispatch(actionCreators.searchFocus())
            },
            handleInputBlur() {
                dispatch(actionCreators.searchBlur())
            },
            handleMouseEnter() {
                dispatch(actionCreators.mouseEnter())
            },
            handleMouseLeave() {
                dispatch(actionCreators.mouseLeave())
            },
            handleChangePage(page, totalPage) {
                if (page < totalPage) {
                    dispatch(actionCreators.changePage(page + 1))
                } else {
                    dispatch(actionCreators.changePage(1))
                }
            }
        }
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(Header)
    

    相关文章

      网友评论

          本文标题:13.项目实战:Header组件开发(五)

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