网易云音乐项目

一、根据命令搭建项目目录

1
2
3
4
5
6
7
8
9
10
11
vue init webpack my-demo (my-demo项目名称)

启动项目:
npm run dev
或者
npm start

启动成功之后,服务器地址: http://localhost:8080
如果你想要修改这个服务地址或者端口号,在config=>index.js
dev的对象中去修改地址以及端口号。这是一个配置文件,当你有修改一定要重启项目。
但是如果你只是修改视图。.vue文件,它属于视图非配置文件,那么不需要重启服务

二、清空并初始化目录结构

1
2
3
①、删除默认的helloworld.vue
②、删除路由文件夹下index.js中 helloworld相关内容
③、清空App.vue,搭建template视图,搭建script逻辑以及style样式

三、分析你的产品需求并创建出组件

1
2
3
4
经过产品需求分析得知:
我们需要创建6个组件,其中:
一级组件:index.vue play.vue list.vue
二级组件: recommend.vue rank.vue search.vue

四、搭建项目目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
src目录结构
assets 静态资源
js
css
images
components
共通的组件
router 路由
index.js 配置文件
App.vue
主组件
main.js
主的js文件
pages
一级组件
views
二级组件

五、根据产品需求搭建路由结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import Vue from "vue";
import Router from "vue-router";
//引入一级路由
import Index from "../pages/index";
import Play from "../pages/play";
import List from "../pages/list";
//引入二级路由
import Recommend from "../views/recommend";
import Rank from "../views/rank";
import Search from "../views/search";

Vue.use(Router);

export default new Router({
routes: [
{
path: "/index",
component: Index,
children: [
{
path: "/recommend",
component: Recommend
},
{
path: "/rank",
component: Rank
},
{
path: "/search",
component: Search
},
{
//二级路由的重定向
path: "",
redirect: "/recommend"
}
]
},
{
path: "/play",
component: Play
},
{
path: "/list",
component: List
},
{
//路由重定向 错误地址拦截
path: "*",
redirect: "/index"
}
]
});

六、引入共通的js文件以及css文件

main.js

1
2
3
4
5
6
7
8
9
10
11
12
//引入全局样式
import './assets/css/reset.css'
//引入全局js
import './assets/js/rem'


//移动端像素
如果你拿的UI设计师给PSD图稿,一比一的还原。一般都是750px宽度
如果你ps软件,量出来宽高是多少就直接 1100 去换算。width:100px 转rem应该是 1rem
如果你是参照官网的像素那么就会有一个二倍的关系,你要看官网参数是否以375为标准
量出来的高度是375*84 其实转rem.js, 84*2/100 =1.68rem

七、完成index.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
<div>
<!-- 路由导航 -->
<nav-bar></nav-bar>
<!-- 二级路由出口 -->
<router-view></router-view>
</div>
</template>

<script>
//引入要嵌套的navBar
import navBar from "../components/nvaBar";
export default {
data() {
return {};
},
components: {
navBar
}
};
</script>

<style lang="" scoped></style>

八、完成推荐音乐静态骨架搭建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<template>
<div>
<div class="title">
<span>推荐歌单</span>
</div>
<div class="recommend">
<!-- 整个v-for循环,采用vue底层机制,叫“就地复用”,基本数据有更新不会全面更新,它只对比谁变了,变了的更新,不变不更新它没有办法监测你的顺序发生变化。作者希望你在每一个元素上都加一个唯一标识,唯一标识需要采用唯一值去做标识 -->
<div class="recInfo" v-for="item in recList" :key="item.id">
<img :src="item.img" alt="" />
<p class="infoTitle">{{ item.info }}</p>
</div>
</div>
<div class="title">
<span>最新音乐</span>
</div>
<ul class="songlist">
<li class="content" v-for="item in songList" :key="item.id">
<div class="songInfo">
<span>{{ item.songName }}</span>
<img src="../assets/images/pause.png" alt="" id="image1" />
</div>
<div class="singgerInfo">
<img src="../assets/images/SQ.png" alt="" />
<p>{{ item.singger }}-{{ item.album }}</p>
</div>
</li>
</ul>
</div>
</template>

<script>
// import Img from '../assets/images/song1.png'
// vue脚手架中,引入静态图片,我们需要利用require引入
export default {
data() {
return {
recList: [
{
id: 1,
img: require("../assets/images/song1.png"),
// img:Img,
info: "[华语速爆新歌] 尤长靖全新单曲与自我和解"
},
{
id: 2,
img:
"http://p1.music.126.net/RpzIkeUOZ4V7WBecytqH0Q==/109951165515305859.jpg?imageView=1&type=webp&thumbnail=247x0",
info: "有些心动,一开始便覆水难收"
},
{
id: 3,
img:
"http://p1.music.126.net/zbZ2G3jre0Mi5EG1AolXgw==/109951165508314455.jpg?imageView=1&type=webp&thumbnail=247x0",
info: "生活在慢慢变甜变可爱,十二月一定会更好吧"
},
{
id: 4,
img:
"http://p1.music.126.net/A6fmNtdIEW_GNg1p4sV7bQ==/109951165519282981.jpg?imageView=1&type=webp&thumbnail=247x0",
info: "下次再遇到喜欢的记得做朋友"
},
{
id: 5,
img:
"http://p1.music.126.net/DtkzGaI2slpF26Jgdj-UsA==/109951165087958748.jpg?imageView=1&type=webp&thumbnail=247x0",
info: "「DJ中文歌曲」超好听弹鼓版dj"
},
{
id: 6,
img:
"http://p1.music.126.net/crW5CnbDDw7mBMmQ4GSI1A==/109951165459023259.jpg?imageView=1&type=webp&thumbnail=247x0",
info: "慵懒时光 | 冬日惬意兜风指南"
}
],
songList: [
{
id: 1,
songName: "雨过天晴",
singger: "吴大文",
album: "雨过天晴"
},
{
id: 2,
songName: "雨过天晴2",
singger: "吴大文2",
album: "雨过天晴2"
},
{
id: 3,
songName: "雨过天晴3",
singger: "吴大文3",
album: "雨过天晴3"
},
{
id: 4,
songName: "雨过天晴4",
singger: "吴大文4",
album: "雨过天晴4"
}
]
};
}
};
</script>

<style lang="" scoped>
.title {
height: 40px;
}
.title span {
position: absolute;
border-style: none none none solid;
border-width: 2px;
border-color: #dd001b;
font-size: 16px;
height: 20px;
line-height: 18px;
color: #333;
padding-left: 7px;
margin: 15px 0;
}
.recommend {
width: 100%;
/* 弹性盒子 */
display: flex;
/* 排序的状态 */
justify-content: space-around;
/* 是否折行 */
flex-wrap: wrap;
}
.recommend .recInfo {
width: 31%;
}
.recInfo img {
width: 120px;
height: 120px;
}
.infoTitle {
font-size: 13px;
color: #333;
}

.songlist .content {
height: 1.1rem;
padding-top: 12px;
border-style: none none solid;
border-width: 2px;
border-color: #eeeeee;
}

.songlist .content span {
font-size: 17px;
padding-left: 8px;
padding-bottom: 2px;
}

.songlist .content div {
margin-top: 5px;
margin-bottom: 5px;
}

.songlist .content div p {
font-size: 12px;
color: #888;
display: inline;
}

.songlist .content div img {
margin-left: 8px;
}

.songlist .content #image1 {
position: relative;
top: 5px;
right: 25px;
float: right;
}
.songInfo {
height: 25px;
}
.songInfo span {
float: left;
}
.singgerInfo {
height: 20px;
}
.singgerInfo p,
.singgerInfo img {
float: left;
}
</style>

九、组件拆分

把你认为可能会公用的组件,进行重新封装,哪里需要哪里引入

components=>navBar.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<template>
<div class="top">
<div class="header">
<div>
<img src="../assets/images/2.png" alt="" />
<button>下载APP</button>
</div>
</div>
<div class="navBar">
<div>
<router-link tag="div" active-class="select" to="/recommend"
>推荐音乐</router-link
>
</div>
<div>
<router-link tag="div" active-class="select" to="/rank"
>热歌榜</router-link
>
</div>
<div>
<router-link tag="div" active-class="select" to="/search"
>搜索</router-link
>
</div>
</div>
</div>
</template>

<script>
export default {
data() {
return {};
}
};
</script>

<style lang="" scoped>
.header {
width: 100%;
height: 1.68rem;
background-color: #d43c33;
}

.header div img {
padding: 2.5px;
}

.header div button {
margin: 20px;
float: right;
height: 36px;
width: 100px;
border: 1px solid white;
border-radius: 37.5%/100%;
font-size: 16px;
color: #d43c33;
background-color: #fff;
text-align: center;
}
.top {
width: 100%;
z-index: 1;
}
.navBar {
width: 100%;
height: 40px;
display: flex;
border-bottom: 1px solid #cccc;
}
.navBar div {
flex: 1;
text-align: center;
line-height: 40px;
font-size: 17px;
color: #333;
}

#content {
position: relative;
top: 19vh;
}
.select {
color: red !important;
}
</style>


Axios http库

一、axios概念
1
2
3
4
5
6
7
8
9
axios 是基于promise的http状态库

易用、简洁且高效的http库

官网概念:Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中

之前前后端交互:
原生的ajax调取接口
jquery库中的ajax()方法去调取接口
二、官网
1
http://www.axios-js.com/
三、安装
1
npm install(简写成i) axios
四、axios的特性
1
2
3
4
5
6
7
8
从浏览器中创建 XMLHttpRequests
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应 (这个是axios特有的属性,含有拦截器,可以全局拦截请求和响应)
转换请求数据和响应数据
取消请求
自动转换 JSON 数据
客户端支持防御 XSRF(可以放置跨站伪造请求)
五、兼容性
1
它是基于promise原理,所以只支持IE9及其以上
六、语法
①get请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
直接调用axios()

axios({
url:'你要访问的地址(后端提供前端的地址)',
method:'get',//请求方法,如果是get可以省略,post不行
params:{//根据后端的需求传入的必传参数

}
})
.then((res)=>{
//res 是response 响应
//res是通过调取接口之后,得到的响应数据
})
.catch((err)=>{
//err 错误响应
})

=============================================
调取axios的get方法
axios.get('url地址',{
params:{}
})
.then((res)=>{
//res 是response 响应
//res是通过调取接口之后,得到的响应数据
})
.catch((err)=>{
//err 错误响应
})
②post请求
七、局部应用
1、get请求接口
八、全局应用