一、Vant组件的使用(注意版本号)
1、yarn add axios vant@2.12.24 vue-router@3.5.3
2、自动按需引入
yarn add babel-plugin-import -D
3、babel.config.js
plugins: [
['import', {
libraryName: 'vant',
libraryDirectory: 'es',
style: true
}, 'vant']
]
4、main.js里引入需要使用的组件
5、重启后即可使用并看到效果
二、初始化项目
三、配置路由
1. 安装 : yarn add vue-router@3.5.3
2. 准备工作 3 个 创建router/index.vue
//1. 引入
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
//2.创建路由实例
const router = new VueRouter()
//3. 挂载
export default router
3. 具体步骤 3 个
//1.入口
//2.规则
routes: [
{ path: '/', redirect: '/layout' },
{
path: '/layout',
component: Layout,
children: [
{ path: 'home', component: Home },
{ path: 'search', component: Search },
],
},
{ path: '/play', component: Play },
],
//3.出口
<router-view> <router-view/>
四、引入导航栏和tabbar
1、navbar
-main.js
import { NavBar } from 'vant';
Vue.use(NavBar);
-layout引入样式
<van-nav-bar title="标题" />
2、tabbar
-main.js
import { Tabbar, TabbarItem } from 'vant';
Vue.use(Tabbar);
Vue.use(TabbarItem);
-layout引入样式
<van-tabbar>
<van-tabbar-item icon="home-o">首页</van-tabbar-item>
<van-tabbar-item icon="search">搜索</van-tabbar-item>
</van-tabbar>
五、设置路由模式
<van-tabbar router>
<van-tabbar-item to="/layout/home" icon="home-o">首页</van-tabbar-item>
<van-tabbar-item to="/layout/search" icon="search">搜索</van-tabbar-item>
</van-tabbar>
修改重定向
{ path: '/', redirect:'/layout/home' },
使用meta储存源代码修改标题
{
path: 'search', meta: {
title: '搜索'
}, component: Search
},
<van-nav-bar :title="$route.meta.title" />
六、首页推荐歌单
布局
1、yarn add less less-loader@5.0.0
2、渲染ui页面
import { Cell, Grid, GridItem, Image } from 'vant'
Vue.use(Cell)
Vue.use(Grid)
Vue.use(Image)
Vue.use(GridItem)
<!-- 推荐歌单 -->
<van-cell class="title" title="推荐歌单" />
<van-grid :border="false" :column-num="3">
<van-grid-item>
<van-image
width="111"
height="100"
src=""
/>
<p class="music-name van-multi-ellipsis--l2">
12312312
</p>
</van-grid-item>
</van-grid>
<style scoped lang="less">
.home-container {
.title {
background-color: #c71d24;
color: #fff;
}
.music-name {
font-size: 12px;
text-align: left;
line-height: 20px;
width: 100%;
padding: 0 5px;
box-sizing: border-box;
height: 37px;
}
/deep/.van-grid-item__content {
padding: 10px 0px;
}
}
</style>
获取歌单
request.js
import axios from "axios";
const request=axios.create({
baseURL:'http://localhost:3000'
})
export default request
api/music.js//按需导出
import request from "@/utils/request";
export const recommendMusic=(params)=>{
return request({
method:'GET',
url:'/personalized',
params
})
}
Home\index.vue
import { recommendMusic } from "@/api/music";
export default {
async created() {
// request({
// url: "/personalized",
// }).then((res) => {
// console.log(res.data);
// });
// recommendMusic().then(res=>{
// console.log(res.data);
// })
let res = await recommendMusic({
limit:6//限制获取的数据条数为6
});
console.log(res.data);
},
};
获取新音乐
main.js引入icon
import { Icon } from 'vant';
Vue.use(Icon);
api/music.js
export const newMusic=(params)=>{
return request({
method:'GET',
url:'/personalized/newsong',
params,
})
}
Home\index.vue
import { recommendMusic, newMusic } from "@/api/music";
let res1 = await newMusic();
this.newMusicList = res1.data.result;
遍历渲染
七、搜索
import { Search, Tag, Icon } from 'vant'
Vue.use(Icon)
Vue.use(Tag)
Vue.use(Search)
<template>
<div>
<van-search
shape="round"
placeholder="请输入搜索关键词"
/>
<!-- 热门搜索 -->
<van-cell title="热门搜索" />
<div style="padding: 10px 16px;">
<van-tag color="red" size="large" plain round type="primary">
123
</van-tag>
</div>
</div>
</template>
<script>
export default {}
</script>
热搜列表
import { Search, Tag } from 'vant'
Vue.use(Tag)
Vue.use(Search)
<van-cell class="title" title="最佳匹配" />
<van-cell label="12" title="1221">
<template>
<van-icon color="#000" name="play-circle-o" size="28" />
</template>
</van-cell>
api/search.js
import request from "@/utils/request";
export const hotSearch = (params) => {
return request({
method: 'GET',
url: '/search/hot',
params
})
}
import { hotSearch, requestCloud } from "@/api/search";
async created() {
let res = await hotSearch();
this.hotSearchList = res.data.result.hots;
},
遍历渲染
最佳匹配
api/search.js
export const requestCloud=(params)=>{
return request({
method:'GET',
url:'/cloudsearch',
params
})
}
Search.vue
import { List } from 'vant'
Vue.use(List)
data() {
return {
value: "vueeeeee",
hotSearchList: [],
list: [],
loading: false, // 是否在加载中 n次
finished: false, // 是否加载完成 1次
page:0,
};
},
改造methods
--将定时器改造
methods: {
async onLoad() {
this.page++;
// 异步更新数据
// setTimeout 仅做示例,真实场景中一般为 ajax 请求
let res = await bestMatch({
keywords: this.value,
limit: 20,
offset: (this.page - 1) * 20,
});
if (res.data.result.songs == undefined) {
this.finished = true;
this.loading = false;
return;
}
this.list = [...this.list, ...res.data.result.songs];
console.log(this.list);
this.loading = false;
},
},
封装函数
async getCloudList() {
return await requestCloud({
keywords: this.value,
limit: 20,
offset: (this.page - 1) * 20,
});
},
Search/onload函数
let res = await this.getCloudList();
八、点击热歌标签(可复用)
@click="hotTag(item.first)"
// 点击热歌标签
async hotTag(val) {
// 给输入框赋值
this.value=val
// 处理小细节
this.page=1
this.finished=true
// 请求数据
let res= await this.getCloudList()
// 覆盖之前的数据
this.list=res.data.result.songs
// loading=>false
this.loading=false
},
热门搜索和最佳匹配交替显示
v-if="list.length==0"
v-else
设置点击事件
async inputFn() {
console.log(this.value);
this.page=1
this.finished=false
if(this.value.trim()==''){
this.list=[]
return
}
let res=await this.getCloudList()
if(res.data.result.songs==undefined){
this.list=[]
return
}
this.list = res.data.result.songs;
this.loading=false
},
九、防抖
方案一:
inputFn() {
clearTimeout(this.setTimeId)
this.setTimeId = setTimeout(() => {
this.inputFn1();
}, 500);
},
方案二:lodash
yarn add lodash
import _ from 'lodash'
async created() {
let res = await hotSearch();
this.hotSearchList = res.data.result.hots;
this.inputFn=_.debounce(this.inputFn,500)
},
十、设置layout布局
<van-nav-bar fixed :title="$route.meta.title" />
<!-- 二级出口 -->
<div class="mian">
<router-view></router-view>
</div>
.mian{
padding-top: 45px;
}
十一、songItem 设置播放
<SongItem
v-for="item in list"
:key="item.id"
:name="item.name"
:id='item.id'
:author='item.ar[0].name'
></SongItem>
<template>
<div>
<van-cell :label="author + ' ' + name" :title="name" />
<div>
<van-icon @click="playFn" color="#000" name="play-circle-o" size="28" />
</div>
</div>
</template>
methods: {
playFn() {
this.$router.push({
path:'/play',
query:{
id:this.id
}
})
},
},
};
十二、移动适配
yarn add postcss postcss-pxtorem@5.1.1
postcss.config.js
module.exports = {
plugins: {
'postcss-pxtorem': {
// 能够把所有元素的px单位转成Rem
// rootValue: 转换px的基准值。
// 例如一个元素宽是75px,则换成rem之后就是2rem。
rootValue: 37.5,
propList: ['*']
}
}
}
import '@/mobile/flexible'