react 虚拟滚动

yarn add rc-virtual-list

import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import { PlayScreen } from './style'

import { PlayCircleFilled, DeleteOutlined } from '@ant-design/icons'

import {
	changeCurrentIndexAction,
	removeSongList,
	GetSongLyric,
	clearSongList,
} from '../store/createActionType'
// 时间格式化函数
import VirtualList from 'rc-virtual-list'
import 'react-virtualized/styles.css'; 
import { formatMinuteSecond } from '../../../assets/js/format-utils'
// 全局变量
import '../global'

class Index extends PureComponent {
	// 歌词所在的位置
	isPosition = React.createRef()
	// 歌词内容
	isContent = React.createRef()
	// 左边栏列表高度
	isSongs = React.createRef()

	state = {
		currentIndex: -1,
	}

	// 组件挂载函数
	componentDidMount() {
		// 初始化时确保滚动位置同步
		// 控制右侧歌词滚动位置

		this.isPosition.current &&
			this.isContent.current.scrollTo(0, this.isPosition.current.offsetTop)
		// 控制左侧歌曲列表滚动位置

		this.isSongs.current &&
			this.isSongs.current.scrollTo({
				index: this.props.currentIndex,
				offset: 150,
				align: 'auto',
			})
	}
	// 组件更新函数
	componentDidUpdate(preVal) {
		if (preVal.currentNumber !== this.props.currentNumber) {
			// 控制右侧歌词滚动位置

			this.isPosition.current &&
				this.isContent.current.scrollTo(0, this.isPosition.current.offsetTop)
			// 控制左侧歌曲列表	滚动位置
			// console.log(this.isSongs)
			if (this.props.currentNumber <= 1 && this.props.songList.length) {
				this.isSongs.current.scrollTo({
					index: this.props.currentIndex,
					offset: 150,
					align: 'auto',
				})
			}
		}
	}
	// 点击播放按钮,播放歌曲
	playSong = (index) => {
		console.log(index)
		this.props.playSong(index)
	}
	// 鼠标移入,添加类名效果
	mouseEnter = (index) => {
		this.setState({
			currentIndex: index,
		})
	}
	// 鼠标移出,移除类名效果
	mouseLeave = () => {
		this.setState({
			currentIndex: -1,
		})
	}
	removeSong = (index, song) => {
		if (this.props.songList.length === 1) {
			this.props.handlePause()
			global.lyricArray = []
			this.props.removeSongList(0, song.id)
		} else {
			if (this.props.currentIndex > index) {
				this.props.changeCurrentIndex(this.props.currentIndex - 1)
			} else if (this.props.currentIndex === index) {
				if (this.props.songList[index + 1]) {
					this.props.changeSongLyric(this.props.songList[index + 1].id)
					this.playSong(index)
				} else {
					this.playSong(0)
				}
			}
			this.props.removeSongList(index, song.id)
		}
	}

	clearSongList = () => {
		// 将播放按钮变成暂停态
		this.props.handlePause()
		// 执行action函数,清空列表
		this.props.clearSongList()
	}

	// 渲染
	render() {
		const { songList, currentIndex, currentNumber } = this.props
		return (
			<PlayScreen>
				<div className="main_left">
					<div className="tital">
						<span>播放列表({songList.length})</span>
						<span className="clearSongList" onClick={this.clearSongList}>
							{songList.length ? '清除' : null}
						</span>
					</div>

					<VirtualList
						data={songList}
						height={308}
						itemHeight={28}
						itemKey="id"
						className="songs scroll"
						ref={this.isSongs}
						// onScroll={onScroll}
					>
						{(item, index) => (
							<div
								className={
									'songList' +
									' ' +
									(currentIndex === index
										? 'deepBlue'
										: this.state.currentIndex === index
										? 'shallowBlue'
										: '')
								}
								key={item.id}
								onDoubleClick={() => this.playSong(index)}
								onMouseEnter={() => this.mouseEnter(index)}
								onMouseLeave={() => this.mouseLeave(index)}
							>
								<div className="play_icon">
									{currentIndex === index ? (
										<PlayCircleFilled
											className="orange"
											onClick={() => this.playSong(index)}
										/>
									) : this.state.currentIndex === index ? (
										<PlayCircleFilled
											className="white"
											onClick={() => this.playSong(index)}
										/>
									) : null}
								</div>

								<span className="song">{item.name}</span>
								<span className="singer">{item.ar[0].name}</span>
								<span className="duration">{formatMinuteSecond(item.dt)}</span>
								<div className="removeBox">
									<DeleteOutlined
										className={
											'remove ' +
											(this.state.currentIndex === index ? 'isRemoveShow' : '')
										}
										onClick={() => this.removeSong(index, item)}
									></DeleteOutlined>
								</div>
							</div>
						)}
					</VirtualList>
				</div>
				<div className="main_right ">
					{/* 歌名区域 */}
					<div className="song_name ">
						{songList[currentIndex] && songList[currentIndex].name}
					</div>
					{/* 歌名区域  end*/}
					{/* 歌词区域 */}
					<div className="lyric scroll" ref={this.isContent}>
						<div className="content">
							{global.lyricArray.length ? (
								global.lyricArray.map((item, index) => {
									return (
										<p
											key={index}
											className={
												currentNumber === index + 1 ? 'isActive' : null
											}
											ref={currentNumber === index + 1 ? this.isPosition : null}
										>
											{item.content}
										</p>
									)
								})
							) : (
								<p className="isActive">网易云Music,用心做好音乐</p>
							)}
						</div>
					</div>
				</div>
				{/* 歌词区域 end*/}
			</PlayScreen>
		)
	}
}

const mapStateToProps = (state) => ({
	songList: state.songList.toJS(),
	currentIndex: state.songsDetail.getIn(['currentIndex']),
})

function mapDispatchToProps(dispatch) {
	return {
		changeCurrentIndex: (index) => dispatch(changeCurrentIndexAction(index)),
		removeSongList: (index, id) => dispatch(removeSongList(index, id)),
		changeSongLyric: (id) => dispatch(GetSongLyric(id)),
		clearSongList: () => dispatch(clearSongList()),
	}
}

export default connect(mapStateToProps, mapDispatchToProps)(Index)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React-virtualized是一个非常流行的React库,它可以帮助我们实现大数据量的虚拟滚动效果。下面是一个使用React-virtualized实现虚拟滚动的表格的示例代码: 首先,我们需要安装React-virtualized库: ``` npm install react-virtualized --save ``` 然后,我们需要引入Table和Column组件: ``` import { Table, Column } from 'react-virtualized'; ``` 接下来,我们可以定义一个数据源,例如: ``` const list = [ { name: '张三', age: '18', address: '北京市海淀区' }, { name: '李四', age: '20', address: '北京市朝阳区' }, { name: '王五', age: '22', address: '北京市西城区' }, // ... // 这里可以添加更多的数据 ]; ``` 然后,我们可以定义一个Table组件,指定它的rowCount和rowGetter属性: ``` <Table rowCount={list.length} rowGetter={({ index }) => list[index]} > ``` 接下来,我们可以添加一些Column组件,定义每一列的属性: ``` <Column label="姓名" dataKey="name" width={100} /> <Column label="年龄" dataKey="age" width={100} /> <Column label="地址" dataKey="address" width={200} /> ``` 最后,我们需要在Table组件中添加一些属性,以启用虚拟滚动: ``` <Table rowCount={list.length} rowGetter={({ index }) => list[index]} headerHeight={20} rowHeight={30} width={600} height={400} > ``` 在上面的代码中,我们设置了headerHeight和rowHeight属性来指定表头和每一行的高度,width和height属性用于指定表格的宽度和高度。React-virtualized会自动根据这些属性来计算出需要渲染的行数,并且只渲染当前可见的行,以实现虚拟滚动的效果。 完整的代码示例: ``` import React, { Component } from 'react'; import { Table, Column } from 'react-virtualized'; const list = [ { name: '张三', age: '18', address: '北京市海淀区' }, { name: '李四', age: '20', address: '北京市朝阳区' }, { name: '王五', age: '22', address: '北京市西城区' }, // ... // 这里可以添加更多的数据 ]; class VirtualTable extends Component { render() { return ( <Table rowCount={list.length} rowGetter={({ index }) => list[index]} headerHeight={20} rowHeight={30} width={600} height={400} > <Column label="姓名" dataKey="name" width={100} /> <Column label="年龄" dataKey="age" width={100} /> <Column label="地址" dataKey="address" width={200} /> </Table> ); } } export default VirtualTable; ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值