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

  • Post author:
  • Post category:vue

一、头部导航栏布局

image-20220613085300007

首先我们看最上面这里的布局,大致可分为三个模块,顶部左边,顶部中间,顶部右边

那么我们在component创建一下子组件,命名为topNav.vue

image-20220613091653753

为了让这个整体好看一点,我在 App.vue 这加了一点整体的样式

  *{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "微软雅黑";
  }

  // 渐变背景色
  html{
     background:linear-gradient(top,rgb(232,235,242),rgb(255,255,255)) no-repeat ;
     background:-webkit-linear-gradient(top,rgb(232,235,242),rgb(255,255,255)) no-repeat;
  }

先把基础的东西填进去然后在调整样式

image-20220613091746009

看看效果

image-20220613091803098

很明显现在的图标很大,我们先调整图片的大小

.icon{
      width: 0.4rem;
      height: 0.4rem ;
}

image-20220613092005496

然后我们在利用flex布局让它从两端对齐,并设置边距,让它看起来好看一点

    .topNav{
        width: 7.5rem;
        height: 0.8rem;
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 0 0.2rem;
	}

image-20220613092137723

最后调整一下中间的文字,平均分布

    .topCenter{
      width: 4.5rem;
      display: flex;
      justify-content: space-around;
    }

image-20220613092420073

然后我们在修它的选中状态 active 变粗

 <!-- 修改成active -->
<!-- 顶部中间 -->
    <div class="topCenter">
      <span class="navBtn">我的</span>
      <span class="navBtn active" >发现</span>
      <span class="navBtn">云村</span>
      <span class="navBtn">视频</span>
    </div>
    .topCenter{
      width: 4.5rem;
      display: flex;
      justify-content: space-around;
      .active{
        font-weight: 900;
      }
    }

image-20220613093318757

整体代码 topNav.vue

<template>
  <div class="topNav">
          <!-- 顶部左边 -->
    <div class="topLeft">
      <svg class="icon" aria-hidden="true">
        <use xlink:href="#icon-liebiao2"></use>
      </svg>
    </div>
    <!-- 顶部中间 -->
    <div class="topCenter">
      <span class="navBtn">我的</span>
      <span class="navBtn active" >发现</span>
      <span class="navBtn">云村</span>
      <span class="navBtn">视频</span>
    </div>
    <!-- 顶部右边 -->
    <div class="topRight">
         <svg class="icon search_img" aria-hidden="true">
          <use xlink:href="#icon-sousuo"></use>
      </svg>
    </div>
  </div>
</template>

<style lang="less" scoped>
    .topNav{
    width: 7.5rem;
    height: 1rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 0.2rem;
    .icon{
      width: 0.4rem;
      height: 0.4rem ;
    }
    
    .topCenter{
      width: 4.5rem;
      display: flex;
      justify-content: space-around;
      .active{
        font-weight: 900;
      }
    }
  }
</style>

二、轮播图的实现

实现了顶部之后,我们现在来实现轮播图,轮播图这里我就偷个懒,利用vant去实现。

vue3 npm 安装

# Vue 3 项目,安装最新版 Vant
npm i vant

文档地址:https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart


我们在main.js中引用vant

import { createApp } from 'vue'
import { Swipe, SwipeItem } from 'vant';
import 'vant/lib/index.css';

createApp(App).use(Swipe).use(SwipeItem).mount('#app')

我们同样在components创建一个swipe.vue子组件,然后在HomeView.vue中注册一下

image-20220613111700356

在swipe.vue,我们使用vant官方的例子,利用懒加载的方式做轮播图(这里的图片我放在了assets下,需要自己创建一个img文件夹放图片)

<template>
    <van-swipe :autoplay="3000" lazy-render>
        <van-swipe-item v-for="image in images" :key="image">
            <img :src="image" />
        </van-swipe-item>
    </van-swipe>
</template>

<script>

export default {
 setup() {
    const images = [
        require('@/assets/img/1.jpg'),
        require('@/assets/img/2.jpeg'),
        require('@/assets/img/3.jpeg'),
        require('@/assets/img/4.png'),
    ];
    return { images };
  },
}
</script>

效果

354633442

​ 现在来调整一下样式,使图片的宽度适中

<style>
.van-swipe{
    width: 7rem;
    height: 2.7rem;
    margin:0 auto;
    border-radius: 0.3rem;
    border: red 1px solid;
        /* 使下面的点变成红色 */
     --van-swipe-indicator-active-background-color:rgb(255, 61, 61);
}
.van-swipe-item img{
    width: 100%;
}

效果

354633444

这里是红边框可以去掉,只是拿来做演示用

三、请求网易的banner图

完成了轮播图的效果,我们请求一下api,这里安装一下axios

npm install axios

然后我们在src创建一个专门api文件夹

image-20220614161740459

里面发送一下请求,由于接口文档已经说明了这一条,所以大家在编写axios请求时注意一下,文档所有接口都可以使用get请求,但为了真实一点,我使用了post请求

image-20220614161931603

import axios from 'axios'

// 请求banner
 function postBanner(type1){
   return  axios.post(`http://localhost:3000/banner?type=${type1}`).then((res)=>{
       return res.data.banners ;
    })
}

export {postBanner}

​ 然后我们来到我们的swipe.vue界面,请求一下数据并渲染到页面上

​ 这里说明一下banner接口请求出来的数据均为对象类型数据

image-20220614164643402

​ 这里有三种方法 1、ref存储数据 2、reactive([])存储数据(不太推荐) 3、reactive([])嵌套一个对象去存储(推荐

  1. ref存储数据

    <template>
        <van-swipe :autoplay="3000" lazy-render>
            <van-swipe-item v-for="(image,index) in images" :key="index">
                <img :src="image.pic" />
            </van-swipe-item>
        </van-swipe>
    </template>
    
    <script>
    import {onMounted,reactive,ref} from 'vue'
    import {postBanner} from '@/api/index'
    
    export default {
       setup() {
            let  images = ref([])
            onMounted(async()=>{
                getSwipeAPI()
            })
           async function getSwipeAPI(){
              images.value = await postBanner(1)
            }
            console.log(images);
        return { images };
      }, 
    }
    </script>
    
  2. reactive([])嵌套一个对象去存储(推荐)

<template>
    <van-swipe :autoplay="3000" lazy-render>
        <van-swipe-item v-for="(image,index) in images2.list" :key="index">
            <img :src="image.pic" />
        </van-swipe-item>
    </van-swipe>
</template>

<script>
import {onMounted,reactive,ref} from 'vue'
import {postBanner} from '@/api/index'

export default {
   setup() {
        let images2 = reactive({
            list:[]
        })
        onMounted(async()=>{
            getSwipeAPI()
        })
       async function getSwipeAPI(){
          images2.list = await postBanner(1)
        }
    return {images2};
  },
}
</script>
  1. reactive([])通过push存储(不推荐)
<template>
<div v-for="(image,index1) in images3" :key="index1">
    <van-swipe :autoplay="3000" lazy-render>
        <van-swipe-item v-for="(i,index) in image" :key="index">
            <img :src="i" />
        </van-swipe-item>
    </van-swipe>
</div>
</template>

<script>
import {onMounted,reactive,ref} from 'vue'
import {postBanner} from '@/api/index'

export default {
   setup() {
        let images3 = reactive([])
        onMounted(async()=>{
            getSwipeAPI()
        })
       async function getSwipeAPI(){
          let x = await postBanner(1)
            x = x.map(v=>v.pic)
          images3.push(x)
        }
        console.log(images3);
    return {images3};
  },
}
</script>

效果

3546334442

四 链接

Vue3+node.js网易云音乐实战项目(一): https://blog.csdn.net/NITIQ/article/details/125358363?spm=1001.2014.3001.5501
Vue3+node.js实战项目网易云音乐APP(二): https://blog.csdn.net/NITIQ/article/details/125358401?spm=1001.2014.3001.5502
Vue3+node.js网易云音乐实战项目(三): https://blog.csdn.net/NITIQ/article/details/125358446?spm=1001.2014.3001.5502
Vue3+node.js网易云音乐实战项目(四): https://blog.csdn.net/NITIQ/article/details/125358476?spm=1001.2014.3001.5502

未完…

未完…


版权声明:本文为NITIQ原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。