vue day13 网易云项目(歌词)

网易云音乐项目步骤
1、启动网易云音乐后台接口

要求我们使用接口的时候,服务器不能不能关闭
每次调取接口的时候,要先在浏览器url,先进行测试,链接通了之后再写到代码中
启动方式 npm start 或者 node app.js
如果没有看node_modules文件夹,你要优先安装依赖 npm install(i)

2、创建一个Vue的项目

vue init webpack mydemo(项目名称)

3、创建项目结构(src)
assets(静态资源管理)
 js
  remScale.js(移动端rem.js转换)
 css
  reset.css(清除默认样式)
common(共通的工具类的模块)
 ajax.js (ajax相关模块)
 jsonp.js(封装jsonp的模块)
 api.js(全局所有接口封装的模块)
 reg.js (封装正则的模块)
components(组件文件夹)
 common (公共组件文件夹)
 pages(其他组件一级组件)
 views(二级组件)
 index.vue(伪组件)
filter(全局过滤器文件夹)
 index.js(过滤器暴露出的文件)
router(路由)
stylus(css预处理器)
4、创建项目组件
//设置一级路由(router中的index.js)
import Vue from 'vue'
import Router from 'vue-router'
//引入一级路由
import Index from '@/components/index'
import List from '@/components/pages/list'
import Play from '@/components/pages/play'
import loginTel from '@/components/pages/loginTel'
import loginName from '@/components/pages/loginName'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path:'/list',
      component:List
    },
    {
      path:'/play',
      component:Play
    },
    {
      path:'/loginName',
      component:loginName
    },
    {
      path:'/loginTel',
      component:loginTel
    },
    {
      path:'/index',
      component:Index
    },
  ]
})
5、下载需要的插件和依赖包
npm install animate.css //动画库
npm install axios //axios http库
//css预处理器(less或者stylus,当前项目以stylus为案例)
npm install stylus stylus-loader
官网地址:https://stylus.bootcss.com/
//stylus预处理器引入vue脚手架中,并不需要配置
//如果你想使用less,那么主要在vue脚手架中webpack中进行配置
npm install less less-loader
//在webpack中进行配置(webpack.base.conf.js) 修改之后记得**重启**
6、引入公共文件
//stylus 引入方式
<style lang="stylus" scoped>
@import '../../stylus/index.styl'; 
</style>
//引入axios库
import axios from 'axios'
//引入rem.js
import './assets/js/remScale'
//引入动画库
import 'animate.css'
//引入清除默认样式
import './assets/css/reset.css'
//把axios挂载到vue实例上
Vue.prototype.http = axios
7、登录页之用户名密码
//绘制静态页
    <div>
      请输入用户名:
      <input type="text" v-model="userInfo.phone" placeholder="请输入用户名" />
    </div>
    <div>
      请输入密码:
      <input type="password" v-model="userInfo.password" placeholder="请输入密码" />
    </div>
    <button @click="login">登录</button>
    <router-link to='/loginTel'>通过验证码的方式进行登录</router-link>
//登录事件
    login() {
      console.log(this, "触发");
      //调取登录接口 this.http 就是axios
      this.http({
        url: url.loginName,
        method: "get", //get方法可以省略
        //    params:{
        //        phone:this.userInfo.phone,
        //        password:this.userInfo.password
        //    }
        params: this.userInfo
      })
        .then(res => {
          console.log(res, "数据响应");
          //如果登录成功 把用户信息和token存储起来,跳转首页
          if (res.data.code == 200) {
            //把个人信息进行存储
            sessionStorage.setItem("profile", JSON.stringify(res.data.profile));
            sessionStorage.setItem("token", JSON.stringify(res.data.token));
            //利用编程式导航
            this.$router.push("/index");
          }
        })
        .catch(err => {
          //拦截非200的状态
          console.log(err, "错误内容");
        });
    }
8、登录页之发送验证码
//绘制静态页
    <div>
      请输入手机号:
      <input type="text" v-model="phone" />
    </div>
    <button @click="sent">发送验证码</button>
    //发送验证码
    sent() {
      //调取发送验证码接口
      this.http({
        url: url.sentCode,
        params: {
          phone: this.phone
        }
      })
        .then(res => {
          console.log(res, "数据响应");
        })
        .catch(err => {
          console.log(err, "错误信息");
        });
    },
9、登录页之验证验证证码
//绘制静态页
    <div>
      请输入手机号:
      <input type="text" v-model="phone" />
    </div>
    <button @click="sent">发送验证码</button>
    <div>
      填写验证码:
      <input type="text" v-model="sendCode" />
    </div>
    <button @click="login">登录</button>
    //登录事件
    login() {
      //调取验证验证码接口
      this.http({
        url: url.checkCode,
        params: {
          phone: this.phone,
          captcha:this.sendCode
        }
      })
        .then(res => {
          console.log(res, "数据响应验证码");
           //如果登录成功
          if (res.data.code == 200) {
            //利用编程式导航
            this.$router.push("/index");
          }
        })
        .catch(err => {
          console.log(err, "错误信息");
        });
    }
10、创建二级路由(推荐音乐、热歌榜、搜索)
      children:[
        {
          path:'/recommend',
          component:Recommend
        },
        {
          path:'/hotSong',
          component:hotSong
        },
        {
          path:'/search',
          component:Search
        },
        {
          path:'',
          redirect:'/recommend'
        }
      ]
11、推荐音乐
//在vue中引入轮播图
//swiper下载 npm install swiper
//main.js
//引入swipe.js文件
import 'swiper/js/swiper.min'
//引入swiper.css文件
import 'swiper/css/swiper.min.css'
//swiper在组件中的应用
import Swiper from "swiper";
  //封装一个实例化的swiper函数
      getSwiper(){
              let swiper = new Swiper(".swiper-container", {
                loop: true,
                // autoplay:true
                autoplay: {
                  delay: 1000
                },
                pagination: {
                  el: ".swiper-pagination"
                }
              });
      }
   //封装推荐音乐的函数
    getRecSong() {
      //调取推荐歌单接口
      this.http({
        url: url.recSong,
        params: {
          limit: 6 //可选参数,取出数量
        }
      })
        .then(res => {
          if (res.data.code == 200) {
            this.songList = res.data.result;
          }
        })
        .catch(err => {});
    },
        //封装推荐新音乐的函数
    getNewSong() {
      //调取推荐新音乐的接口
      this.http({
        url: url.recNewSong
      })
        .then(res => {
          if (res.data.code == 200) {
            this.latestSong = res.data.result;
            //   console.log(this.latestSong)
          }
        })
        .catch(err => {});
    }
        //封装banner函数
    getBanner() {
      //调取banner接口
      this.http({
        url: url.banner
      })
        .then(res => {
          console.log(res, "res");
          if (res.data.code == 200) {
            this.bannerList = res.data.banners;
            console.log(this, "实例");
            //调用延迟加载 $nextTick 下一次加载dom的时候再执行
            this.$nextTick(() => {
                this.getSwiper()
            });
          }
        })
        .catch(err => {});
    },
  mounted() {
    //页面一加载调取推荐歌单接口
    this.getRecSong();
    //页面一加载调取推荐新音乐的接口
    this.getNewSong();
    //页面一加载就出现轮播
    this.getBanner();
  },
12、热歌榜
  mounted() {
    //组件一就调取热歌榜单函数
    this.getHotTop()
  },
  methods:{
    getHotTop(){
      //调取热门排行榜单
      this.http({
        url:url.topList,
        params:{
          idx:1//云音乐热歌榜
        }
      })
      .then(res=>{
        console.log(res,'云音乐热歌榜')
        if(res.data.code==200){
          this.latestSong = res.data.playlist.tracks
        }
      })
      .catch(err=>{})
    }
  }
13、搜索
//通过input内容调取的搜索建议接口
  //利用watch监听 实时调取接口
  watch:{
    content(newVal){
      //判断搜索框是否有内容
      if(newVal){
      //在这里面实时调取搜索建议接口
      this.getSearchSuggest(newVal)
      }else{
        this.resultList=[]
        return
      }

    }
  }
  //在methods中
    //封装一个搜索建议函数
    getSearchSuggest(word){
      this.http({
        url:url.searchSuggest,
        params:{
          keywords:word
        }
      })
      .then(res=>{
        //当搜索建议有值的时候,完善搜索建议列表
        if(res.data.code==200){
          this.searchResults= res.data.result.songs
        }
      })
      .catch(err=>{})
    },
    //点击搜索建议或者热门搜索都是这一个方法,给input框赋值
    suggestInfo(val){
      //给input框赋值
      this.content = val
      //调取搜索函数
      this.getSearch(this.content)
    },
      //封装一个搜索函数
    getSearch(word){
      this.http({
        url:url.search,
        params:{
          keywords:word
        }
      })
      .then(res=>{
        console.log(res,'搜索结果')
        //当搜索有数据的时候
        if(res.data.code==200){
          this.resultList = res.data.result.songs
        }
      })
      .catch(err=>{})
    },
        //封装一个热门搜索
    getSearchHot(){
        this.http({
        url:url.searcHot,
      })
      .then(res=>{
        console.log(res,'热门搜索结果')
        //当搜索建议有值的时候,完善搜索建议列表
        if(res.data.code==200){
          this.latestSong= res.data.result.hots
        }
      })
      .catch(err=>{})
    }
14、图片懒加载
//下载命名 npm install vue-lazyload
//引入图片懒加载插件
import VueLazyLoad from 'vue-lazyload'

//使用图片懒加载
Vue.use(VueLazyLoad,{
  loading:'../static/default.jpg'
})
//使用的时候(把:src替换成v-lazy)
<img v-lazy='imgUrl'>
15、歌曲列表跳转播放页
//播放页面有哪些内容
//歌曲详情信息-歌手、歌曲、歌词、播放地址
//调取三个各接口
//获取歌曲详情
    getSongDetail(){
      this.http({
        url:url.songDetail,
        params:{
          ids:this.$router.query.传递的数据
        }
      })
      .then(res=>{
        console.log(res,'获取歌曲详情的响应')
        if(res.data.code==200){
          //获取歌手
          this.singer = res.data.songs[0].ar[0].name
          //获取歌名
          this.songName = res.data.songs[0].name
          //获取歌曲封面
          this.imgUrl = res.data.songs[0].al.picUrl
        }
      })
    },
    //获取歌词
      getLyric(){
      this.http({
        url:url.lyric,
        params:{
          id:this.$router.query.传递的数据
        }
      })
      .then(res=>{
        console.log(res,'获取歌词')
        if(res.data.code==200){
          this.lyric = res.data.lrc.lyric
        }
      })
    },
    //获取音乐url
      getSongUrl(){
      this.http({
        url:url.songUrl,
        params:{
          id:this.$router.query.传递的数据
        }
      })
      .then(res=>{
        console.log(res,'获取音乐url')
        if(res.data.code==200){
          this.songUrl = res.data.data[0].url
        }
      })
    }
//路由之间跳转2种,第一种 router-link 第二种编程式导航
16、歌词拆分加滚动
mounted() {
    //挂载 组件一进来就加载接口
    this.getSongDetail();
   // this.getLyric();
    //this.getSongUrl();
    //执行强制的函数
    this.getSelect()
    console.log(this.$refs.audio, "播放器11111");
  },
  methods: {
    //封装一个播放函数
    toPlay(){
      this.flag = !this.flag
      if(this.flag){
        //让音乐暂停
        this.$refs.audio.pause()
        //让图标显示
        this.$refs.playIcon.style.display= 'block'
      }else{
        //让音乐播放
        this.$refs.audio.play()
        //让图标消失
        this.$refs.playIcon.style.display = 'none'
      }
    },
    //封装一个歌词滚动的函数
    lyricMove(){
      //获取含有active的标签
      let active = document.getElementsByClassName('active')[0]
      //寻找含有active的索引
      let index = $('.geci_box').children().index(active)
      //根据是否有active 是否这个向上距离大于等于this.offset(31),发生位移
      if(active){
        if(active.offsetTop>=this.offset){
          //y轴的位移 改变translateY
          $('.geci_box').css('transform',`translateY(-${index*this.offset}px)`)
        }
      }
    },
    //封装一个时间转化函数
    //4.142687s => 转化成分钟4.142687/60 分钟 4.142687%60 秒 00:00
    transTime(time) {
      //转换分钟
      let minute = Math.floor(time / 60);
      minute < 10 ? (minute = "0" + minute) : minute;
      let second = Math.floor(time % 60);
      second < 10 ? (second = "0" + second) : second;
      return `${minute}:${second}`;
    },
    //获取歌曲详情
    getSongDetail() {
      this.http({
        url: url.songDetail,
        params: {
          ids: this.$route.query.id
        }
      }).then(res => {
        console.log(res, "获取歌曲详情的响应");
        if (res.data.code == 200) {
          //获取歌手
          this.singer = res.data.songs[0].ar[0].name;
          //获取歌名
          this.songName = res.data.songs[0].name;
          //获取歌曲封面
          this.imgUrl = res.data.songs[0].al.picUrl;
        }
      });
    },
    //获取歌词
    getLyric() {
      this.http({
        url: url.lyric,
        params: {
          id: this.$route.query.id
        }
      }).then(res => {
        console.log(res, "获取歌词");
        if (res.data.code == 200) {
          //this.lyric = res.data.lrc.lyric
          //把歌词获取字符串赋值给一个变量,去拆分这个变量
          let lyric = res.data.lrc.lyric;
          //设置一个空对象
          let obj = {}; //obj.a obj[a]=当前key值所在的value值

          //设置一个正则 把数组[]去掉
          let reg = /\[(.*?)](.*)/g;
          lyric.replace(reg, (a, b, c) => {
            b = b.slice(0, 5);
            obj[b] = c;
          });
          //console.log(obj,'对象内容')
          //给歌词赋值
          this.lyric = obj;//{00:00 : '你好'}
          console.log( this.lyric,'歌词')
          //监控播放器的播放进度
          let audio = this.$refs.audio;
          audio.ontimeupdate = () => {
            console.log(audio.currentTime,'当前时间以秒')
            let timer = this.transTime(audio.currentTime);
            //剔除空时间
            if(timer in this.lyric ){
              this.rightTime = timer
            }
            console.log(this.rightTime,'this.rightTime')
            //让歌词滚动
            this.lyricMove()
            //累加你的旋转角度
            this.rNum += 2
            //让封面旋转
            this.$refs.playImg.style.transform = `rotate(${this.rNum}deg)`
          };
        }
      });
    },
    //获取音乐url
   async getSongUrl() {
    return this.http({
        url: url.songUrl,
        params: {
          id: this.$route.query.id
        }
      }).then(res => {
        console.log(res, "获取音乐url");
        if (res.data.code == 200) {
          this.songUrl = res.data.data[0].url;
        }
      });
    },
   async getSelect(){
     await this.getSongUrl()
     this.getLyric()
    }
  }
17、UI框架
17.1elementUI (PC端,去开发后台管理项目)

官网地址:https://element.eleme.cn/#/zh-CN
完全为Vue开发
下载方法:npm install element-ui
CDN下载方式:

<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
  • 全局引入
//main.js 
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';

Vue.use(ElementUI);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值