[React]优化滚动,分类页数据对接

773 阅读1分钟

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战

一、使用IScroll优化滚动效果及回弹

// 1. 引入 isscroll
import  IScroll from '../../../assets/js/libs/iscroll'
// 2. 初始化滚动容器
// 初始化分类栏滚动

componentDidMount(){
    this.initClassifyScroll()
}

initClassifyScroll(){
    document.getElementById("scroll-classify").addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
    this.myScroll= new IScroll('#scroll-classify', {
        scrollX : false,
        scrollY : true,
        preventDefault : false
    });
}

<div className="classify-name-list" id='scroll-classify'>
    <div>
        <div className="classify-name-item active">商品名称1</div>
        {this.state.classifyNames.map((item,index) => (<div className="classify-name-item" key={index}>商品名称{index+2}</div>
        ))}
    </div>
</div>

优化滚动和回弹成功

Kapture 2021-08-18 at 06.17.38.gif

二、分类栏接口数据渲染

2.1 数据获取

// 获取分类栏数据
    getClassifyData() {
        request('/api/home/category/menu')
            .then(res => {
                if(res.code === 200) {
                    this.setState({
                        classifyList: res.data
                    }, () => {
                       this.initClassifyScroll()
                    })
                }
            })
    }
    <div>
                            {this.state.classifyList.map((item,index) => (<div className={this.state.classifyActiveIndex === index ? 'classify-name-item active' : 'classify-name-item'}  key={index}>{item.title}</div>
                            ))}
                        </div>

image.png

2.2 点击分类菜单切换子路由

// 页面跳转
goPage(url) {
    this.props.history.replace(config.path + url)
}
 // 切换菜单
    changeClassifyMenu(index,cid) {
        this.setState({
            classifyActiveIndex: index
        },() => {
            this.goPage('goods/classify/items?cid=' + cid)
        })
    }

Kapture 2021-08-18 at 06.36.57.gif

2.3 点击菜单自适应屏幕滚动

 // 滚动方法
    classifyMenuScroll(index) {
        console.log(1111)
        // 获取最外层容器
        let containerElement = this.refs['scroll-classify']
        // 最外层容器的高度
        let containerElementHeight = containerElement.offsetHeight
        // 最外层容器的滚动高度
        let containerElementScrollHeight = containerElement.scrollHeight
        // 每一项分类的高度
        let itemHeight = this.refs['croll-classify-item' + index].offsetHeight
        // 要往上滚动的距离
        let needScrollTop = itemHeight * index
        // 需求大于1/3高度,并且,底部距离大于最外层容器才滚动
        if(needScrollTop > containerElementHeight / 3 && containerElementScrollHeight - needScrollTop > containerElementHeight) {
            this.myScroll.scrollTo(0,-needScrollTop,300,IScroll.utils.ease.elastic);
        }
    }
    
    
    // 切换菜单
    changeClassifyMenu(index,cid) {
        this.setState({
            classifyActiveIndex: index
        },() => {
            this.goPage('goods/classify/items?cid=' + cid)
            this.classifyMenuScroll(index)
        })
    }
    
    <div className="classify-name-list" id='scroll-classify' ref={'scroll-classify'}>
                        <div>
                            {this.state.classifyList.map((item,index) => (<div className={this.state.classifyActiveIndex === index ? 'classify-name-item active' : 'classify-name-item'}  key={index} onClick={this.changeClassifyMenu.bind(this,index,item.cid)} ref={'croll-classify-item' + index}>{item.title}</div>
                            ))}
                        </div>
                    </div>

效果

Kapture 2021-08-18 at 07.48.41.gif

三、子路由数据渲染

/*eslint-disable*/
import React from 'react';
import {Route, Switch} from "react-router-dom";
import asyncComponents from '../../../components/async/AsyncComponent';
import config from "../../../assets/js/conf/config";
import '../../../assets/css/home/goods/items.scss'
import {request} from "../../../assets/js/libs/request";
import  IScroll from '../../../assets/js/libs/iscroll'


export default class  HomeComponent extends React.Component{
    componentWillMount() {

    }

    componentDidMount(){
        this.getGoodsList()
    }
    constructor(props) {
        super(props);
        this.state = {
            goodsList: []
        }
    }
    // 页面跳转
    goPage(url) {
        this.props.history.push(config.path + url)
    }
    // 初始化分类栏滚动
    initClassifyScroll(){
        document.getElementById("classify-items").addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
        this.myScroll= new IScroll('#classify-items', {
            scrollX : false,
            scrollY : true,
            preventDefault : false
        });
    }
    // 获取商品列表
    getGoodsList() {
        request('/api/home/category/show')
            .then(res => {
                if(res.code === 200) {
                    this.setState({
                        goodsList: res.data
                    }, () => {
                        // this.initClassifyScroll()
                    })
                }
            })
    }

    render(){
        return(
            <div id='classify-items'>
                <div>
                    {this.state.goodsList.map((item,index) => (
                        <div className="card" key={index}>
                            <div className="card-header">
                                {item.title}
                            </div>
                            <div className="card-body">
                                {item.goods.map((item2,index2) => (
                                    <div className="card-goods-item" key={index2}>
                                        <img src={item2.image} alt={item2.title} />
                                        <div className="goods-title">{item2.title}</div>
                                    </div>
                                ))}
                            </div>
                        </div>
                    ))}

                </div>
            </div>
        );
    }
}

image.png