Vue3+node.js网易云音乐实战项目(八)

最后一个页面还没写完,由于我要去比赛,所以暂时先写到这,等放假了再写

其他页面可以看我页面专栏 Vue3实战项目-网易云APP 。
大家觉得有些地方可以写的更好写法可以给我留言私信,我会去修改
如果文章对你有帮助请点一个赞或收藏,谢谢

1、准备工作

然后我们来实现播放界面也就是下面这张图

image-20220701105646433

这是一个新的页面,我们还是利用路由进行跳转,先创建一个playerUi.vue

image-20220701111409741

然后,我们在router中设置路由

,{
    path: '/PlayerUi',
    name: 'PlayerUi',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/PlayerUi.vue')
  }

image-20220701111450421

然后我们设置路由跳转,根据手机App上的网易云,我们可以知道,歌单列表左边部分可以跳转到该页面还有下面播放按钮的左边部分

image-20220701111627289

那么我们就在这两个部分设置路由跳转,这两个位置分别在playlistView.vueplayController.vue

image-20220701111959470

image-20220701152507874

然后效果就是下面这样

354607423212114

然后我们开始找资源,找下面两张图片,接口我没有看见有图片。

image-20220701152717120

我们打开网易云音乐的官网,随便点击一首歌,用f12用手机的宽度去打开

https://music.163.com/

image-20220701152935005

然后我们点击network 选择Img

image-20220701153002512

找到这几张图片,双击会跳转到单独的页面右键保存即可

image-20220701153205493

然后给它拖到assets文件夹中的img文件夹下面就好了,然后我们来看看接口文档,我们需要的是歌曲的详情和歌词

image-20220701170906653

image-20220701170924253

然后我们在api这个文件夹的index.js下封装一下,

//  获取歌曲详细
function postSongDetail(id){
    return axios.post(`${baseUrl}/song/detail?ids=${id}`)
 }
 
 //  获取歌词
function postLyric(id){
    return axios.post(`${baseUrl}/lyric?id=${id}`)
 }

image-20220701171019976

然后我们在到 PlayerUi.vue 中测试一下

<script>
import palyerUiTop  from '@/components/playerUi/palyerUiTop.vue'


import { onMounted,reactive } from 'vue';
import {useRoute} from 'vue-router'
import {postLyric,postSongDetail} from '@/api/index';
export default {
    components:{
        palyerUiTop
    },
    setup(){
        const route = useRoute()
        let stateLyric = reactive({})
        let stateSongDetail = reactive({})
        onMounted(async()=>{
            // 接收传过来的歌曲ID
            let id = route.query.id
            // 请求
            let Lyric = await postLyric(id) 
            let SongDetail =  await postSongDetail(id)
            // 接收数据
            stateLyric = Lyric.data
            stateSongDetail = SongDetail.data

            console.log(Lyric.data);
            console.log(stateSongDetail);
        })
    }
}
</script>

image-20220701171723774

这样就算好了,然后数据我们等会在处理,先把框架搭好 ,然后我们在components下创建一个文件夹,取名叫playerUi,新建一个子组件 playerUiTop.vue 开始写顶部

image-20220701171845867

2、顶部布局

接下来我们实现顶部的布局

image-20220702152512746

先把图标引用进来,这里的歌名和作者,我们临时给它定一个,先调整样式,在接收数据进行处理。

<template>
  <div class="playUiTop">
    <!-- 左边返回键 -->
    <div class="left">
        <svg class="icon" aria-hidden="true">
          <use xlink:href="#icon-xiangxiajiantou"></use>
        </svg>
    </div>
    <!-- 中间歌名和作者名 -->
    <div class="middle">
      <div class="title">title</div>
      <div class="name">777</div>
    </div>
    <!-- 右边分享 -->
    <div class="right">
        <svg class="icon" aria-hidden="true">
          <use xlink:href="#icon-fenxiang"></use>
        </svg>
    </div>
  </div>
</template>

image-20220702152756813

然后我们来调整样式,同样利用flex布局使它平均分布,然后给上边距。

.playUiTop{
  display: flex;
  justify-content: space-between;
  padding-top: 10px;
}

image-20220702153050263

这里的左右边距,我是在playerUi.vue中给的

.palyerUi{
    width: 7.5rem;
    padding: 0 0.4rem;
}

接下来调整图标大小就可以了,然后给上一个白色的效果

  .icon{
    width: 0.5rem;
    height: 0.5rem;
    fill: #fff;
  }

image-20220702153244955

由于背景是白色的,所以有点看不清楚,等会我们接收数据渲染背景就好了。然后调整中间的字体,这里少了一个 >的图标,我们给它加上

      <div class="name">
        777
        <svg class="icon" aria-hidden="true">
          <use xlink:href="#icon-gengduo1"></use>
        </svg>
      </div>

image-20220702153628919

然后,我们看到这个图标也是受到影响的,我们也给它调整一下,顺便调整一下字体

  .middle{
    color: #fff;
    align-items: center;
    .title{
      font-size: 20px;
    }
    .name{
      opacity: 0.5;
    }
    .icon{
      width: 0.24rem;
      height: 0.24rem;
    }
  }

image-20220702154230837

然后整体居中一下

align-items:Center; 

image-20220702154300966

image-20220702154307039

然后,我们把数据传过来,渲染一下标题,背景的话我打算直接在PlayerUi.vue中渲染,这里修改一下接收参数

image-20220702154733238

它这里是这样的,我们也改成这样样子

        let stateSongDetail = reactive({
            songs:{

            }
        })
        stateSongDetail.songs = SongDetail.data.songs[0]

image-20220702164757191

然后把数据传给playerUiTop.vue

<palyerUiTop :songs = "stateSongDetail.songs"></palyerUiTop>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fBPs1rY8-1656895020777)image-20220702155018660

然后我们先做一下背景,不然看不出效果

image-20220702164416521

很显然这个背景又是加了滤镜的,我们只需要把这个图片请求下来然后加滤镜就好了,我们首先加个img

<img class="bg" :src="stateSongDetail.songs.al.picUrl" alt="">

z’zaimage-20220702164529231

这个样式,我们在歌单列表用过,所以直接拷过来就行

.bg{
    position:fixed;
    left:0;
    top: 0;
    width: 7.5rem;
    z-index: -1;
    filter: blur(100px);
    overflow: hidden;
    transform: scale(4);
}

image-20220702164623934

效果就是这样,然后我们回到playerUiTop.vue中,把歌名和作者渲染一下,这里接收一下数据

  props:['songs'],

image-20220702164855776

    <!-- 中间歌名和作者名 -->
    <div class="middle">
      <div class="title">{{songs.name}}</div>
      <!-- 作者名 -->
      <div class="name">
        <span v-for="(itemName,j) in songs.ar" :key = "j">
            <span v-if="j==songs.ar.length-1">{{itemName.name}}</span>
            <span v-else>{{itemName.name}}/</span>
        </span>
        <svg class="icon" aria-hidden="true">
          <use xlink:href="#icon-gengduo1"></use>
        </svg>
      </div>
    </div>

image-20220702165351133

这里的字体没有居中,然后应该你们的字体会大一点,我这里给它调小了,然后我们来修改一下字体

    .title{
      font-size: 15px;
      text-align: center;
    }
    .name{
      opacity: 0.5;
      text-align: center;
    }

image-20220702165712435

效果就出来了。然后这里的文字还有个走马灯效果,我这里就偷个懒借用vant3中的NoticeBar 通知栏,vant不会引用的看官方文档或者我的Vue3+node.js网易云音乐实战项目(三)这篇中的轮播图实现,这里我采用下面这种方式

image-20220702182041773

然后咱稍微修改一下代码

<van-notice-bar  :text= "songs.name" color="#fff" background="transparent"  />

image-20220702183953000

    .van-notice-bar{
      font-size: 15px;
        width: 3rem;
    }

效果

3546074232121147

然后这里需要给个宽度,让它不超出款的时候不动

    .van-notice-bar{
      font-size: 15px;
      width: 4rem;
        /deep/
    .van-notice-bar__wrap{
      .van-notice-bar__content{
        padding-left: 35px;
      }
    }

然后这里要给个/deep/ 不然设置不了,然后居中属性我一直没调好,就只能给个内边距,这里有其他方法可以给我留个言

image-20220702200050888

最后给加个返回事件

<div class="left" @click="$router.back()" >
</div>

image-20220703151014886

3、中部唱片部分布局

我们开始做唱片部分,也就是下面这个部分,

image-20220702165840597

之前准备工作那里,我们已经下载好了放在了assetsimg下面,现在我们把它引用进来,先创建好一个子组件palerUiDisc.vue组件,然后在PlayerUI.vue中引用

<template>
  <div class="playerUiDisc">
      <div class="img">
        <img class="needle" src="@/assets/img/needle-ab.png" alt="">
        <img class="circle" src="@/assets/img/circle.png" alt="">
        <img class="playImg" :src="songs.al.picUrl" alt="">
      </div>
      <div class="bottonIcon">

      </div>
</template>

image-20220703100947683

然后我们来调整大小和宽度,这里利用定位去做

.img{
    position: absolute;
    width: 7.5rem;
    height: 7.5rem;
    left: 0;
    top: 1.5rem;
    .needle{
        width: 2.5rem;
        height: auto;
        position: absolute;
        left: 3.3rem;
        // 旋转
        transform-origin: 0.3rem 0;
        //旋转多少
        transform: rotate(-20deg);
        z-index: 10;
    }
    .circle{
        width: 5.5rem;
        height: auto;
        position: absolute;
        left:calc(50% - 2.75rem) ;
        top: 2.5rem;
    }
}

image-20220703102327226

然后这样摆臂是个活动的,那我们在给它加一个active状态,这里我们可以用浏览器去先调整一下样式,看看要到多少合适

image-20220703102902931

很显然到3的时候,效果最好,那我我们就摆动到3

    .needle.active{
        width: 2.5rem;
        height: auto;
        position: absolute;
        left: 3.3rem;
        // 旋转多少度
        transform-origin: 0.3rem 0;
        transform: rotate(3deg);
        z-index: 10;
    }

然后我们来给个图片试试效果,这里先从PlayerUi.vue传数据过来

image-20220703104422985

这边接收一下

//template
<img class="playImg" :src="songs.al.picUrl" alt="">
//script
props:['songs']

image-20220703103333415

image-20220703103343322

调整一下大小和位置

    .playImg{
        width: 3.4rem;
        height: 3.4rem;
        border-radius: 100%;
        position: absolute;
        left:calc(50% - 1.7rem) ;
        top: 3.55rem;
    }

image-20220703103816918

接下来实现这个部分

image-20220703105741106

找好图标把图标放进去

      <div class="bottonIcon">
        <svg class="icon" aria-hidden="true">
            <use xlink:href="#icon-xihuan"></use>
        </svg> 
        <svg class="icon" aria-hidden="true">
            <use xlink:href="#icon-xiazai"></use>
        </svg> 
        <svg class="icon" aria-hidden="true">
            <use xlink:href="#icon-changpian"></use>
        </svg> 
        <svg class="icon" aria-hidden="true">
            <use xlink:href="#icon-pinglun-"></use>
        </svg> 
        <svg class="icon" aria-hidden="true">
            <use xlink:href="#icon-gengduo-shuxiang"></use>
        </svg> 
      </div>

image-20220703160225061

调整一下边距和位置还有大小

     .bottonIcon{
            width: 7.5rem;
            display: flex;
            justify-content: space-evenly;
            position: absolute;
            bottom: 3rem;
            left:calc(50% - 3.7rem) ;
            .icon{
                width: 0.5rem;
                height: 0.5rem;
                fill: #fff;
            }
    }

image-20220703160313125

然后这里还有个问题,如果有些时候没有请求到图片,我们需要把唱片改成红色的底片。我们利用v-if来进行判断

        <img class="playImg" v-if="songs.al.picUrl"  :src="songs.al.picUrl" alt="">
        <img class="playImg" v-else="songs.al.picUrl"  src="@/assets/img/disc.png" alt="">

image-20220703160640621

然后大的背景也是一样的,我们也做一下修改

      <img class="bg" v-if="stateSongDetail.songs.al.picUrl" :src="stateSongDetail.songs.al.picUrl" alt="">
      <img class="bg" v-else="stateSongDetail.songs.al.picUrl" src="@/assets/img/disc.png" alt="">

image-20220703160824379

4、底部部分布局

接下来,我们来实现底部部分的布局

image-20220703105756765

先把大的框架搭好

<template>
  <div class="playUiButton">
      <div class="top">
      </div>
      <div class="button">
        <svg class="icon" aria-hidden="true">
            <use xlink:href="#icon-xihuan"></use>
        </svg> 
      </div>
  </div>
</template>

首先是上面的一部分,一个进度条,我们还是采用vant的进度条来弄

image-20220703165742920

先把它插入进来,设置一下颜色和字,具体参数可以看vant

      <div class="top">
            <van-progress :percentage="5" pivot-text=" "  color="#fff" stroke-width="1px" />
      </div>

然后给它变成圆角,设置一下长度

.top{
	/deep/
        .van-progress{
        color:#fff;
        width: 6rem;
        .van-progress__pivot{
            font-size: 1px;
            width: 0.2rem;
            height: 0.2rem;
            border-radius: 100%;
        }
    }
}

image-20220703170042717

然后我们利用定位调整一下位置

    .top{
        display: flex;
        position: absolute;
        left: 0;
        bottom: 2rem;
        /deep/
        .van-progress{
            color:#fff;
            width: 5rem;
            position: absolute;
            left:58px ;
            .van-progress__pivot{
                font-size: 1px;
                width: 0.2rem;
                height: 0.2rem;
                border-radius: 100%;
            }
        }
}

左右两边价格时间戳,先占个位置。

          <p class="p1">00:00</p>
            <van-progress :percentage="5" pivot-text=" "  color="#fff" stroke-width="1px" />
          <p class="p2">00:00</p>
        .p1{
            position: absolute;
            left: 0.1rem;
            top: -10px;
        }
        .p2{
            position: absolute;
            left: 6.4rem;
            top: -10px;
        }

image-20220703192131358

然后接下来调整下面这部分的按钮,在这个之前我们先把播放组件取消显示

image-20220703192223568

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周粥粥ya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值