云音乐播放器项目总结
Posted Modern world
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了云音乐播放器项目总结相关的知识,希望对你有一定的参考价值。
1.创建项目
1.1引入Vue Cli脚手架
作用
Vue CLI 致力于将 Vue 生态中的工具基础标准化。它确保了各种构建工具能够基于智能的默认配置即可平稳衔接,这样你可以专注在撰写应用上,而不必花好几天去纠结配置的问题。与此同时,它也为每个工具提供了调整配置的灵活性,无需 eject
安装
npm install -g@vue/cli
确认方式
vue --version
创建项目
1.创建项目
生命新目录何文件结构,不嵌套在其他文件钟
2.输入命令
vue create 项目名
2.1注意事项不要使用中文
2.2cd切换项目目录
2.3执行命令
npm run serve
Git
1.初始化本地仓库 git init
2.创建之后会有一个.gitinore,会写入git忽略的文件
2.1.gitignore只能忽略原来没有被跟踪的文件,因此跟踪过的文件是无法被忽略的。因此在网页上可以看到target等目录的存在。
解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:
3.创建项目一般只有一次
1.2 创建的项目结构
1.2.1 目录结构
1.2.2 main.js结构
// 导入Vue构造函数
import Vue from \'vue\'
// 导入App.vue单文件组件
import App from \'./App.vue\'
// Vue.config设置,productionTip生产提示
Vue.config.productionTip = false
// 实例化对象
new Vue({
// 渲染, 把App.vue这个组件解析为Vue实例的内部结构
render:h=>h(App)
}).$mount(\'#app\')
Vue渲染机制
Vue响应式机制
1.2.3 注意
在项目复制时,可以不复制module文件,通过package.json就可以安装下载
npm i 会自动下载根据,//dependencies:依赖,依靠
用到的依赖
2.引入router管理器
Vue Router 是Vue.js官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得简单
路由概念:
路由是指路由器从一个接口上收到数据包,根据数据包的目的地址进行定向并转发到另一个接口的过程。路由通常与桥接来对比,在粗心的人看来,它们似乎完成的是同样的事。它们的主要区别在于桥接发生在OSI参考模型的第二层(数据链路层),而路由发生在第三层(网络层)。这一区别使二者在传递信息的过程中使用不同的信息,从而以不同的方式来完成其任务。
路由工作包含两个基本的动作:
1、确定最佳路径
2、通过网络传输信息
在路由的过程中,后者也称为(数据)交换。交换相对来说比较简单,而选择路径很复杂
2.0单页应用
多页应用 | 单页应用 |
---|---|
一个项目中有多个完整的的html文件 | 一个项目中只有一个完整的HTML页面(index.html) |
可以使用超链接、js实现页面间的跳转 | 可以使用改进后的超链接、js实现模板页面间的切换 |
传统的页面跳转是同步请求:在服务器生成响应内容时,客户端是一片空白 | 模板页面间的切换属于经典的异步请求:直到下一个模板页面来到,前一个模板页面到来,前一个模板页面才从当前DOM树上删除 |
页面跳转时,前一个DOM树无用了,需要从浏览器中全部删除,然后等待下一个DOM树的到来 | index.html到来时,浏览器创建一个DOM树。所有的请求都是xhr,到来时只需要作为一个片段挂载在当前DOM树——浏览器从始至终只有一个DOM树 |
当网速比较慢时(尤其是移动端应用中时),用户体验极为不好! | 不会出现一片惨白的情形,浏览体验好。 |
页面切换时,DOM被完整的删除,不可能有过场动画! | 页面切换的本质是DIV的轮换,可以很容易实现漂亮的过场动画。 |
2.1.使用
下包
npm install vue-router
导包
import Vue from \'vue\'
import VueRouter from \'vue-router\'
Vue.use(VueRouter)
使用
将所有的routes参数配置给router实例化对象,从而让整个应用都有路由的功能
//使用模块化的编程,导入Vue和VueRouter,之后必须调用Vue.use(VueRouter)
//创建和挂载根实例
//引入组件home
import home from \'../views/home.vue\'
const routes = [
{
//路径
path: \'/home\',
//名字
name: \'home\',
//注册对应路径的组件,在App的<router-view/>处渲染
component: home
},
]
const router = new VueRouter({
routes//routes:routes
}).$mount(\'#app\')
export default router
将暴露的router对象引入到main.js上
将引入的router添加到main.js页面的Vue构造函数上,挂载到app上,让整个app都可以使用router路由
注:render函数是vue通过js渲染dom结构的函数createElement,约定可以简写为h
$mount()手动挂载:
这里创建的vue实例没有el属性,而是在实例后面添加了一个$mount(’#app’)方法。$mount(’#app’) :手动挂载到id为app的dom中的意思.当Vue实例没有el属性时,则该实例就没有挂载到某个dom中. 假如需要延迟挂载,可以在之后手动调用vm.$mount()方法来挂载。
2.1组件的安装方式
一种是将这个插件的逻辑封装成一个对象最后将最后在install编写业务代码暴露给Vue对象。这样做的好处是可以添加任意参数在这个对象上方便将install函数封装得更加精简,可拓展性也比较高,比如Vue-Router。
还有一种则是将所有逻辑都编写成一个函数暴露给Vue,不需要使用Vue.use(),直接引入就可以比如axios。
其实两种方法原理都一样,无非第二种就是将这个插件直接当成install函数来处理。
2.2.router-link
1.对应关系
2.作用
超链接标签
实现跳转
2.3.router-view
1.作用
匹配到的注册的组件,直接传递到对应的渲染的位置
2.查看高亮类名
查看元素
3.通过$0可以复制审查元素
4.由路由管理的页面一般要放在views当中进行管理
那些是路由管理的页面?
//在router中import导入的组件都是被管理的页面,比如在router的index.js中
import home from \'../views/home.vue\'
import find from \'../views/find.vue\'
import play from \'../views/play.vue\'
2.4.路由传参的两种方式
1.1 url携带:get传参
路由地址?key=value&key2=value2
1.2 编程式导航,query对象传参
//分开写,编程 /地址?key=value
this.$router.push({path:\'路由地址\',query:{key:\'value\'} })
this.$router.push({path:\'路由地址?key=value&key2=value2\'})
注意:
this.$router,可以跳转
this.$route,可以获取参数
3.引入Vant组件
下包
# Vue 2 项目,安装 Vant 2:
npm i vant -S
# Vue 3 项目,安装 Vant 3:
npm i vant@next -S
导包
方式三. 导入所有组件
Vant 支持一次性导入所有组件,引入所有组件会增加代码包体积,因此不推荐这种做法。
import Vue from \'vue\';
import Vant from \'vant\';
import \'vant/lib/index.css\';
Vue.use(Vant);
注意事项
使用事项:
1.在文档拷贝HTML之外还要拷贝逻辑
结构中用到的东西再script
中得定义
2.通过基本实例找到需要的效果,整合进来
3.组件库的样式整合
4.引入axios组件
4.1什么是axios
`特征和作用`
制作的XMLHttpRequest从浏览器
让HTTP从node.js的请求
支持Promise API
拦截请求和响应
转换请求和响应数据
取消请求
JSON 数据的自动转换
客户端支持防止XSRF
4.2使用axios
设置默认的基地址
axios.defaults.baseURL = \'https://api.example.com\';
示例代码
<template>
<div></div>
</template>
<script>
import axios from \'axios\'
axios.defaults.baseURL = \'https://autumnfish.cn/api\'
export default {
created () {
//设置了基地址直接写后面就行
axios({
url: \'/joke/list\',
params: {
num: 3
},
method: \'get\'
}).then(res => {
console.log(\'笑话接口\')
console.log(\'res:\', res)
})
}
}
</script>
<style></style>
4.2.1-- axios挂载
为了方便多个页面使用axios,每个页面导入一次太繁琐,我们可以直接把axios丢到原型上
通过构造函数的prototype
访问,设置给原型的属性,方法,所有的实例化对象
为了区别与Vue上的原型,约定用$加以区分
注意点
1.常规访问原型是通过构造函数.prototype
1.实例化对象.__proto__也可以访问
2.原型让所有的实例化对象都公用对象上的属性和方法
4.3整合axios(与末尾整合不同,整合--1)
1.下包
npm i axios
2.导包
main.js文件导入
设置基地址
添加到原型
3.为什么建议用$
开头?
-
官方文档也是这么玩的
-
比如
$route
和$router
都是丢在了原型上 -
区别于Vue原型上的属性
5.首页
5.1首页底部导航区域
结构
<!-- 地址--组件渲染的位置 -->
<router-view/>
<!-- 底部的tabbar -->
//设置绑定的数据
<van-tabbar v-model = "active" route active-color = "#ee0a24" placeholder>
//跳转到home
<van-tabbar-item to = "/home" icon = "home-o">首页</van-tabbar-item>
//跳转到find
<van-tabbar-item to = "/find" icon = "search">搜索</van-tabbar-item>
</van-tabbar>
逻辑
export default {
data() {
return {
active: 0,
};
},
};
active是默认选中的导航标签的索引,这里只有0和1
设置了routes
参数(在router文件的index.js上)
在APP.vue页面内部需要设置to
属性才可以保证正常的切换效果
const routes = [
{
path: \'/home\',
name: \'home\',
component: home
}]
5.2整合三个组件页面和路由
页面:
find
:搜索home
:首页play
:播放
静态资源:assets
路由:vue add router
整理后的项目文件
路由和组件的关系--1
路由和组件的挂载渲染--2
5.2首页轮播图
vant - 轮播图组件
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item>1</van-swipe-item>
<van-swipe-item>2</van-swipe-item>
<van-swipe-item>3</van-swipe-item>
<van-swipe-item>4</van-swipe-item>
</van-swipe>
使用vant轮播图组件
1.使用v-for循环获取数据并添加
1.设置给遍历数据唯一的key
2.设置基地址在main.js
2.created钩子函数是在实例创建完成后被立即调用,方便键返回数据的banners在渲染之前添加到轮播数据的数组banners当中,播放页面所有的数据请求都放在created钩子函数当中!!!
实现逻辑
1.在data函数声明一个存放轮播图数据的空数组
2.通过挂载的$axios发起banner请求
3.请求成功之后通过then方法添加到banners数组
实现结构
1.v-for遍历存放数据的每个元素item
中有唯一的id设置给 :key
2.v-for遍历存放数据的每个元素item
的picURL绑定给对应的img属性
5.3首页推荐歌单
实现逻辑
1.在data函数声明一个推荐歌单的songList空数组
2.通过挂载的$axios发起请求
3.请求成功的数据res添加到songList数组中
实现结构
1.v-for循环遍历songList数组
2.将遍历元素的唯一id设置给key
3.将遍历元素的唯一图片地址bind到img标签
4.将遍历元素的name添加到p标签
注意事项:
1.冒号不能露
2.返回的数据名,设置的属性名
5.4首页推荐新音乐
实现逻辑
1.在data函数声明一个hotList空数组
2.通过原型挂载$axios发起请求
3.请求成功以后将返回的数据保存到数组
实现结构
1.通过cell组件设置多行的效果如下
1.注意自定的结构一般都是插槽
具名插槽:有名字的插槽
2.在van-cell组件的标签上循环遍历数组hotList
3.遍历到的唯一id设置给key
4.遍历到的name绑定给title,同时在name之外返回的数据可能还有别名,放在alias数组当中通过三元表达式进行判断添加
标题的数据渲染逻辑
5.将遍历的元素item中的歌手名数据渲染给lable属性
代码整合
5.5首页跳转--play
跳转携带歌曲的参数
代码跳转通过编程式导航
1.携带歌曲的id
2.通过编程式导航跳转
1.给跳转的按钮添加点击事件,在点击事件触发的时候调用方法
<div class = "song-list">
<van-cell
//推荐新歌的数组循环,van-cell之内
v-for = "item in hotSongs"
:key = "item.id"
:title = "
item.name +
(item.song.alias.length === 0 ? \'\' : `(${item.song.alias[0]})`)
"
size = "large"
:label = "item.song.artists[0].name"
>
<template #right-icon>
<!-- 播放按钮 -->
<van-icon
name = "play-circle-o"
class = "play-icon"
@click = "toPlay(item.id)"
/>
</template>
</van-cell>
</div>
2.定义toplay方法跳转页面携带id
toPlay (id) {
// console.log(\'id:\', id)
//通过router的push方法添加跳转的路径和携带的数据,ES6对象的简写{id:id}
this.$router.push({
path: \'/play\',
query: { id }
})
}
6.播放页
6.1接收数据
1.接受首页推荐新音乐跳转过来携带的参数
data () {
return {
// 定义一个数据保存歌曲的id
id: 0,
}
},
created () {
// 通过 this.$route.query获取到跳转携带的数据
this.id = this.$route.query.id
},
query查询到的数据
$route.query
-
类型:
Object
一个 key/value 对象,表示 URL 查询参数。例如,对于路径
/foo?user=1
,则有$route.query.user == 1
,如果没有查询参数,则是个空对象。
6.2播放歌曲
1.点击播放歌曲
1.将获取的参数通过模板字符串传递给src属性对应的位置
2.将src绑定data中的数据
2.播放状态的切换
1.定义一个播放状态isPlay
2.定义一个切换播放状态的方法togglePlay
<div class = "start-box">
<span class = "song-start" @click = "togglePlay">
</span>
</div>
3.点击时
togglePlay () {
// 暂停->播放
if (this.isPlay === false) {
//通过$refs获取到audio标签,调用自带的play方法播放
this.$refs.audio.play()
} else {
// 播放->暂停
//通过$refs获取到audio标签,调用自带的pause方法播放
this.$refs.audio.pause()
}
// 取反
this.isPlay = !this.isPlay
}
//$refs取到所有的ref属性的标签再点一下具体的标签
6.3播放器动画效果
CSS代码
.song-wrapper {
position: fixed;
width: 247px;
height: 247px;
left: 50%;
top: 50px;
transform: translateX(-50%);
z-index: 10001;
&.play {
.needle {
transform: rotate(-7deg);
}
.song-turn {
animation-play-state: running;
}
}
}
.song-turn {
width: 100%;
height: 100%;
background: url(\'../assets/bg.png\') no-repeat;
background-size: 100%;
}
.start-box {
position: absolute;
width: 156px;
height: 156px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: flex;
justify-content: center;
align-items: center;
}
.song-start {
width: 56px;
height: 56px;
background: url(\'../assets/start.png\');
background-size: 100%;
}
.needle {
position: absolute;
transform-origin: left top;
background: url(\'../assets/needle-ab.png\') no-repeat;
background-size: contain;
width: 73px;
height: 118px;
top: -40px;
left: 112px;
transition: all 0.6s;
transform: rotate(-38deg);
}
.song-img {
width: 154px;
height: 154px;
position: absolute;
left: 50%;
top: 50%;
overflow: hidden;
border-radius: 50%;
transform: translate(-50%, -50%);
}
动画实现结构
<!-- 播放页内容容器 -->
<div class = "song-wrapper" :class = "{ play: isPlay }">
<div class = "song-turn ani">
<div class = "song-img">
<!-- 封面 -->
<img
style = "width: 100%"
:src = "songInfo.al && songInfo.al.picUrl"
alt = ""
/>
</div>
</div>
<!-- 播放盒子 -->
<div class = "start-box">
<span class = "song-start" @click = "togglePlay"></span>
</div>
<!-- 操作杆css容器 -->
<div class = "needle"></div>
</div>
动画实现效果
6.4 router.go
返回上一页
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似
1.给返回上一页的箭头添加点击事件
<van-icon
name = "arrow-left"
size = "20"
class = "left-incon"
@click = "goBack"
/>
2.调用返回上一页的方法
goBack () {
// 从哪来 回哪去
this.$router.go(-1)
}
7.搜索页
7.1搜索页搜索
引入search组件
<van-search
shape="round"
v-model="value"
show-action
@search="onSearch"
@cancel="onCancel"
placeholder="请输入搜索关键词"
/>
组件的说明
v-model
数据绑定show-action
显示右侧的取消@search:
点击回车或者小键盘右下角,触发的逻辑@cancel
,点击取消触发
实现效果
7.2显示搜索结果(清空热词)和取消搜索结果(保留热词)
实现逻辑
搜索的逻辑
1.在data中定义一个数组保存搜索的结果,如果有搜索结果就取消热词的显示
2.定义一个serach方法,在组建的search事件调用
1.发起请求,添加搜索的参数
2.在参数内添加一个戳避免缓存
3.在参数内将请求的关键字value赋值给keywords,这个键名是后台命名的
4.请求成功后在then方法中将数组的数组添加给定义的空数组
3.定义一个跳转的方法,toPlay接受遍历到的id
4.定义一个取消方法onCancel()
实现结构
5.将search组件通过v-model双向绑定value搜索关键词,关联第三条
6.绑定搜索事件的方法,和取消事件的方法
7.绑定跳转事件,在点击右侧之后携带id跳转到播放页面
8.遍历van-cell,将获得元素item.id绑定到:key上
9.图片中少写了携带id跳转播放,对应的是toPlay方法其接受了来自searchRes循环元素的id值
![img](C:/Users/ENG.J/Desktop/Vue%20origin/image.namedq.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg
7.3点击热词
需求
- 渲染热词
- 点击热词,搜索对应内容
- 搜索出结果
显示
热词,反之隐藏
热词
显示搜索结果(清空热词)和取消搜索结果(保留热词)
步骤:
created
中调用热词接口,获取并渲染- 为热词绑定点击事件
- 设置输入框的内容,并搜索
v-if
判断数组的长度- 0:显示热词
- 不为0:显示搜索结果
- 取消的事件中清空数组即可
实现逻辑
image-20210607100803217
热词方法接受model传来的参数hot = item.first
,并且将item.first渲染到对应的搜索框内{{item.first}}
实现结构
通过hots数组将返回的数据添加到指定位置,
注意
要对搜索的数据长度进行判断,如果没有数据也就是说数组为空的情况下
8.整合优化
8.1抽取api
以上是关于云音乐播放器项目总结的主要内容,如果未能解决你的问题,请参考以下文章