2 Star 10 Fork 1

李俊江 / 基于React+Ant Design实现的仿网易云音乐官网网站

加入 Gitee
与超过 1000 万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README.md

基于React+Ant Design实现的仿网易云音乐官网网站

1.项目简介

后端基于开源的 网易云音乐接口 ,前端基于React+Ant Design实现的web端应用

项目已经完成大部分页面展示与功能实现

项目预览地址: 点我点我

项目仅作学习与交流

1.1推荐页面

包含轮播图、热门推荐、榜单等

1输入图片说明 2输入图片说明
1.2歌曲播放功能
  • 顺序播放
  • 单曲循环
  • 随机播放
  • 动态歌词
  • 歌曲进度
  • 拖拉进度
  • 等等
输入图片说明 输入图片说明
1.3歌词详情页面

包含歌词展示、歌词展开收起等功能

1输入图片说明 2输入图片说明
1.4排行榜页面

包含排行榜数据展现、切换排行榜等功能

1输入图片说明 2输入图片说明
1.5歌单页面

包含分类选择、歌单卡片展示、分页等功能

1输入图片说明 2输入图片说明
1.6电台、歌手、新碟页面等等

由于页面较多涉及组件复用、数据展示等相同功能、展示,因此统一展示

1输入图片说明 2输入图片说明
1输入图片说明 2输入图片说明
1输入图片说明 2输入图片说明
1.7欠缺功能补充说明

页面内容展现较完善,但仍有一些功能没有实现,因此作出补充说明。搜索功能还没实现,登录功能还没实现,同时页面目前仅支持在 发现音乐-推荐 里的榜单处点击播放另外歌曲,这些功能仍待完善,欢迎大家进行补充完善。

2.项目难点

2.1技术栈
  • React 页面布局、组件封装、页面逻辑等
  • react-router 路由、路由跳转等
  • redux 保存数据、数据共享等
  • axios 发送Ajax请求等
  • Ant Design 轮播图、分页实现等
  • ImmutableJS 数据持久化,优化性能
  • styled-components 第三方库,写CSS代码
2.2项目难点

复杂数据页面展示

项目涉及比较多的页面布局和对请求到的数据进行处理展示,页面布局有些比较麻烦的地方和组件复用中的一些问题,这需要花费相当的时间进行样式布局和逻辑处理。

歌曲切换与添加歌曲功能

由于歌曲播放时允许设置三种模式:顺序播放、单曲循环、随机播放,当歌曲播放完时要进行播放判断从而进行不同处理,当手动添加新歌曲时,首先在歌曲播放列表中进行寻找,若没有则添加歌曲进入播放列表中,若歌曲播放列表中存在歌曲则切换歌曲播放的顺序,涉及比较多的逻辑处理和判断,这里给出部分代码,具体请参考完整项目所示

    const changeMusic = (tag) => {
        dispatch(changeCurrentIndexAndSongAction(tag))
    }

    const handleMusicEnded = () => {
        if(sequence === 2){ //单曲循环
            audioRef.current.current = 0
            audioRef.current.play()
        }else{
            dispatch(changeCurrentIndexAndSongAction(1))
        }
    }
export const changeCurrentIndexAndSongAction = (tag) => {
    return (dispatch, getState) => {
        const playList = getState().getIn(["player", "playList"])
        const sequence = getState().getIn(["player", "sequence"])
        let currentSongIndex = getState().getIn(["player", "currentSongIndex"])

        switch (sequence) {
            case 1: // 随机播放
                let randomIndex = Math.floor(Math.random() * playList.length)
                while (randomIndex === currentSongIndex) {
                    randomIndex = Math.floor(Math.random() * playList.length)
                }
                currentSongIndex = randomIndex
                break;
            default: //循序播放
                currentSongIndex = currentSongIndex + tag
                if (currentSongIndex >= playList.length) {
                    currentSongIndex = 0
                }
                if (currentSongIndex < 0) {
                    currentSongIndex = playList.length - 1
                }
        }

        const currentSong = playList[currentSongIndex]
        dispatch(changeCurrentSongAction(currentSong))
        dispatch(changeCurrentSongIndexAction(currentSongIndex))

        dispatch(getLyricAction(currentSong.id))
    }
}

拖拉歌曲进度条时关联的动态变化

由于是手动实现的歌曲播放控制面板,拖拉滑动条时歌曲播放进度(声音)、歌曲时间与歌词当然不会实现动态变化,歌曲播放进度(声音)的动态改变由audio元素的currentTime属性决定,歌曲时间的动态改变由滑动条回调时的value属性决定,歌词的动态变化由对歌词接口返回数据进行的逻辑判断决定,涉及比较多的逻辑处理和判断,这里给出部分代码,具体请参考完整项目所示

    // 滑动条拖动时发生的回调
    const slideChange = useCallback((value) => {
        setIsChanging(true)

        // 随着拖动,当前时间发生更改
        const currentTime = value / 100 * duration / 1000
        setCurrentTime(currentTime * 1000)
        setProgess(value)
    }, [duration])

    // 滑动条结束拖动时发生的回调
    const slideAfterChange = useCallback((value) => {
        const currentTime = value / 100 * duration / 1000
        audioRef.current.currentTime = currentTime
        setCurrentTime(currentTime * 1000)
        setIsChanging(false)

        if(!isPlaying){
            playMusic()
        }
    }, [duration, isPlaying, playMusic])
    const timeUpdate = (e) => {
        const currentTime = e.target.currentTime
        if (!isChanging) {
            setCurrentTime(currentTime * 1000)
            setProgess(currentTime * 1000 / duration * 100)
        }

        // 获取当前歌词
        let index = 0
        for (let i=0; i<lyricList.length; i++){
            let lyricItem = lyricList[i]
            if(lyricItem.time > currentTime * 1000){
                index = i - 1
                break
            }
        }
        // console.log();
        if (currentLyricIndex !== index) {
            dispatch(changeCurrentLyricIndexAction(index))
            let content = lyricList[index] && lyricList[index].content
            message.open({
                key: "lyric",
                content: content,
                duration: 0,
                className: "lyric-class"
            })
        }
    }

3.项目运行

clone项目:

git clone https://gitee.com/junjiangLi/ljmusic.git

安装项目依赖:

yarn

项目运行:

yarn start

简介

后端基于开源的网易云音乐接口,前端基于React+Ant Design实现的web端应用 展开 收起
JavaScript 等 3 种语言
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
JavaScript
1
https://gitee.com/junjiangLi/ljmusic.git
git@gitee.com:junjiangLi/ljmusic.git
junjiangLi
ljmusic
基于React+Ant Design实现的仿网易云音乐官网网站
master

搜索帮助