Day08_vant实现_网易云音乐案例
Day08_vant實現_網易云音樂案例
文章目錄
- Day08_vant實現_網易云音樂案例
-
- 知識點自測
- 鋪墊(自學)
-
-
- 本地接口項目部署
-
- 今日學習目標
- 1. 案例-網易云音樂
-
- 1.0 網易云音樂-本地接口
- 1.1 網易云音樂-本地接口啟動
- 1.2 網易云音樂-前端項目初始化
- 1.3 網易云音樂-需求分析
- 1.4 網易云音樂-路由準備
- 1.5 網易云音樂-Tabbar組件
- 1.6 網易云音樂-NavBar導航組件
- 1.7 網易云音樂-NavBar標題切換
- 1.8 網易云音樂-網絡請求封裝
- 1.9 網易云音樂-首頁-推薦歌單
- 1.10 網易云音樂- 首頁-最新音樂
- 1.11 網易云音樂-搜索-熱搜關鍵字
- 1.12 網易云音樂-搜索-點擊熱詞-搜索結果
- 1.13 網易云音樂-輸入框-搜索結果
- 1.14 網易云音樂-搜索結果-加載更多
- 1.15 網易云音樂-加載更多-bug修復
- 1.16 網易云音樂-輸入框-防抖
- 1.17 網易云音樂-頁碼bug修復
- 1.18 網易云音樂-Layout邊距優化
- 1.19 網易云音樂-SongItem封裝
- 1.20 網易云音樂-播放音樂
- 1.21 網易云音樂-vant適配
- 今日總結
- 今日作業
-
- 1.21 網易云音樂-vant適配
- 今日總結
- 今日作業
知識點自測
- 知道reset.css和flexible.js的作用
- 什么是組件庫-例如bootstrap作用
- yarn命令的使用
- 組件名字用name屬性方式注冊
- 如何自定義組件庫樣式
鋪墊(自學)
本地接口項目部署
下載網易云音樂node接口項目, 在本地啟動, 為我們vue項目提供數據支持
[項目地址] https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=%e5%ae%89%e8%a3%85
[備用地址] : https://github.com/Binaryify/NeteaseCloudMusicApi/tree/master/docs
下載后, 安裝所有依賴, 在本地啟動起來, 測試訪問此地址是否有數據
http://localhost:3000, 看到如下頁面就成功了 - 等著明天上課啟動即可
總結: 前端請求本地的node項目, node服務器偽裝請求去拿網易云音樂服務器數據轉發回給自己前端
今日學習目標
- 能夠掌握vant組件庫的使用
- 能夠掌握vant組件自定義樣式能力
- 能夠掌握組件庫使用和文檔使用能力
- 能夠完成網易云音樂案例
1. 案例-網易云音樂
1.0 網易云音樂-本地接口
目的: 請求網易云音樂服務器API接口-獲取數據
總結: 反向代理就是用本地開啟cors的服務器去轉發請求拿到數據
1.1 網易云音樂-本地接口啟動
目的: 啟動本地網易云音樂API服務
在今天的筆記鋪墊中, 大家自學下載了一個項目啟動即可
1.2 網易云音樂-前端項目初始化
目標: 初始化項目, 下載必備包, 引入初始文件, 配置按需自動引入vant, 創建頁面組件
-
初始化工程
vue create music-demo -
下載需要的所有第三方依賴包
yarn add axios vant vue-router -
引入筆記代碼里準備好的reset.css和flexible.js - 實現樣式初始化和適配問題 - 引入到main.js
-
本次vant使用自動按需引入的方式
文檔: https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart
yarn add babel-plugin-import -D
在babel.config.js - 添加插件配置```js
plugins: [['import', {libraryName: 'vant',libraryDirectory: 'es',style: true}, 'vant']
]
1.3 網易云音樂-需求分析
根據需求, 創建路由所需要的5個頁面的組件
Layout(布局, 頂部導航和底部導航) > 二級路由 Home 和 Search
Play
創建需要的views下的頁面組件4個
views/Layout/index.vue - 負責布局(上下導航 - 中間二級路由切換首頁和搜索頁面)
/* 中間內容區域 - 容器樣式(留好上下導航所占位置) */
.main {padding-top: 46px;padding-bottom: 50px;
}
views/Home/index.vue - 標題和歌名樣式
/* 標題 */
.title {padding: 0.266667rem 0.24rem;margin: 0 0 0.24rem 0;background-color: #eee;color: #333;font-size: 15px;
}
/* 推薦歌單 - 歌名 */
.song_name {font-size: 0.346667rem;padding: 0 0.08rem;margin-bottom: 0.266667rem;word-break: break-all;text-overflow: ellipsis;display: -webkit-box; /** 對象作為伸縮盒子模型顯示 **/-webkit-box-orient: vertical; /** 設置或檢索伸縮盒對象的子元素的排列方式 **/-webkit-line-clamp: 2; /** 顯示的行數 **/overflow: hidden; /** 隱藏超出的內容 **/
}
views/Search/index.vue
/* 搜索容器的樣式 */
.search_wrap {padding: 0.266667rem;
}/*熱門搜索文字標題樣式 */
.hot_title {font-size: 0.32rem;color: #666;
}/* 熱搜詞_容器 */
.hot_name_wrap {margin: 0.266667rem 0;
}/* 熱搜詞_樣式 */
.hot_item {display: inline-block;height: 0.853333rem;margin-right: 0.213333rem;margin-bottom: 0.213333rem;padding: 0 0.373333rem;font-size: 0.373333rem;line-height: 0.853333rem;color: #333;border-color: #d3d4da;border-radius: 0.853333rem;border: 1px solid #d3d4da;
}
views/Play/index.vue - 直接從預習資料里復制(節省時間) - 可自己擴展閱讀代碼
1.4 網易云音樂-路由準備
目標: 準備路由配置, 顯示不同路由頁面
router/index.js - 準備路由 - 以及默認顯示Layout, 然后Layout默認顯示二級路由的首頁
// 路由-相關模塊
import Vue from 'vue'
import VueRouter from 'vue-router'
import Layout from '@/views/Layout'
import Home from '@/views/Home'
import Search from '@/views/Search'
import Play from '@/views/Play'Vue.use(VueRouter)
const routes = [{path: '/',redirect: '/layout'},{path: '/layout',component: Layout,redirect: '/layout/home',children: [{path: 'home',component: Home,meta: { // meta保存路由對象額外信息的title: "首頁"}},{path: 'search',component: Search,meta: {title: "搜索"}}]},{path: '/play',component: Play}
]const router = new VueRouter({routes
})export default router
main.js - 引入路由對象, 注冊到new Vue中
import router from '@/router'new Vue({render: h => h(App),router
}).$mount('#app')
App.vue中留好router-view顯示路由頁面
<template><div><router-view></router-view></div>
</template>
總結: 把項目的框搭好, 逐個攻破
1.5 網易云音樂-Tabbar組件
目標: 點擊底部導航, 切換路由頁面顯示
文檔: https://vant-contrib.gitee.io/vant/#/zh-CN/tabbar
-
注冊Tabbar組件, 在main.js中
import { Tabbar, TabbarItem } from 'vant'; Vue.use(Tabbar); Vue.use(TabbarItem); -
在Layout.vue中使用
<template><div><div class="main"><!-- 二級路由-掛載點 --><router-view></router-view></div><van-tabbar route><van-tabbar-item replace to="/layout/home" icon="home-o">首頁</van-tabbar-item><van-tabbar-item replace to="/layout/search" icon="search">搜索</van-tabbar-item></van-tabbar></div> </template><script> export default { } </script><style scoped> /* 中間內容區域 - 容器樣式(留好上下導航所占位置) */ .main {padding-top: 46px;padding-bottom: 50px; } </style> -
開啟路由模式 route屬性, 和to屬性指向要切換的路由路徑
<van-tabbar route><van-tabbar-item icon="home-o" to="/layout/home">首頁</van-tabbar-item><van-tabbar-item icon="search" to="/layout/search">搜索</van-tabbar-item> </van-tabbar>
總結: van-tabbar開啟route
1.6 網易云音樂-NavBar導航組件
目標: 實現頂部標題展示
文檔: https://vant-contrib.gitee.io/vant/#/zh-CN/nav-bar
-
main.js - 注冊NavBar組件
import { NavBar } from 'vant'; Vue.use(NavBar); -
復制文檔里的, 然后刪刪只留標題
<van-nav-bar :title="activeTitle" fixed /><script>export default {activeTitle: "首頁"} </script>
1.7 網易云音樂-NavBar標題切換
目標: 實現點擊底部導航/刷新非第一頁面頁面, 導航標題正確顯示
-
在router/index.js - 給$route里需要導航標題的添加meta元信息屬性
{path: '/layout',component: Layout,redirect: '/layout/home',children: [{path: 'home',component: Home,meta: { // meta保存路由對象額外信息的title: "首頁"}},{path: 'search',component: Search,meta: {title: "搜索"}}]},Layout.vue中監聽$route改變:
給導航active的值設置$route里的元信息的標題
export default {data() {return {activeTitle: this.$route.meta.title, // "默認"頂部導航要顯示的標題 (默認獲取當前路由對象里的meta中title值)};},// 路由切換 - 偵聽$route對象改變watch: {$route() {this.activeTitle = this.$route.meta.title; // 提取切換后路由信息對象里的title顯示},}, };
總結: 點擊底部導航和刷新當前網頁, 都能保證導航標題的正確顯示
1.8 網易云音樂-網絡請求封裝
目標: 不想把網絡請求散落在各個邏輯頁面里, 不然以后找起來改起來很麻煩
-
封裝utils/request.js - 基于axios進行二次封裝 - 設置基礎地址
// 網絡請求 - 二次封裝 import axios from 'axios' axios.defaults.baseURL = "http://localhost:3000" export default axios -
封裝src/api/Home.js
統一封裝網絡請求方法
// 文件名-盡量和模塊頁面文件名統一(方便查找) import request from '@/utils/request'// 首頁 - 推薦歌單 export const recommendMusic = params => request({url: '/personalized',params// 將來外面可能傳入params的值 {limit: 20} }) -
在src/api/index.js - 統一導出接口供外部使用
// api文件夾下 各個請求模塊js, 都統一來到index.js再向外導出 import {recommendMusic} from './Home'export const recommendMusicAPI = recommendMusic // 請求推薦歌單的方法導出 -
在main.js - 測試使用一下.
import { recommendMusicAPI } from '@/api/index' async function myFn(){const res = await recommendMusicAPI({limit: 6});console.log(res); } myFn();
總結: 封裝網絡請求方法目的, 方便我們統一管理
1.9 網易云音樂-首頁-推薦歌單
接口地址: /personalized
-
布局采用van-row和van-col
布局文檔https://vant-contrib.gitee.io/vant/#/zh-CN/col
-
使用vant內置的圖片組件來顯示圖片
-
在main.js注冊使用的組件
import { Col, Row, Image as VanImage } from 'vant';Vue.use(Col); Vue.use(Row); Vue.use(VanImage); -
在api/index.js下定義推薦歌單的接口方法
// 首頁 - 推薦歌單 export const recommendMusic = params => request({url: '/personalized',params// 將來外面可能傳入params的值 {limit: 20} }) -
把數據請求回來, 用van-image和p標簽展示推薦歌單和歌單名字
<template><div><p class="title">推薦歌單</p><van-row gutter="6"><van-col span="8" v-for="obj in reList" :key="obj.id"><van-image width="100%" height="3rem" fit="cover" :src="obj.picUrl" /><p class="song_name">{{ obj.name }}</p></van-col></van-row></div> </template><script> import { recommendMusicAPI } from "@/api"; export default {data() {return {reList: [], // 推薦歌單數據};},async created() {const res = await recommendMusicAPI({limit: 6,});console.log(res);this.reList = res.data.result;}, }; </script>
1.10 網易云音樂- 首頁-最新音樂
目標: van-cell單元格使用
請求地址: /personalized/newsong
-
引入van-cell使用 - 注冊組件main.js中
import {Cell} from 'vant'; Vue.use(Cell); -
定義接口請求方法 - api/index.js
// 首頁 - 推薦最新音樂 export const newMusic = params => request({url: "/personalized/newsong",params }) -
列表數據鋪設 - 插入自定義標簽
<template><div><p class="title">推薦歌單</p><div><van-row gutter="5"><van-col span="8" v-for="obj in recommendList" :key="obj.id"><van-image fit="cover" :src="obj.picUrl" /><p class="song_name">{{ obj.name }}</p></van-col></van-row></div><p class="title">最新音樂</p><van-cell center v-for="obj in songList" :key="obj.id" :title="obj.name" :label="obj.song.artists[0].name + ' - ' + obj.name"><template #right-icon><van-icon name="play-circle-o" size="0.6rem"/></template></van-cell></div> </template><script> import { recommendMusicAPI, newMusicAPI } from "@/api"; export default {data() {return {reList: [], // 推薦歌單數據songList: [], // 最新音樂數據};},async created() {const res = await recommendMusicAPI({limit: 6,});console.log(res);this.reList = res.data.result;const res2 = await newMusicAPI({limit: 20})console.log(res2);this.songList = res2.data.result}, }; </script>
1.11 網易云音樂-搜索-熱搜關鍵字
目標: 完成熱搜關鍵字鋪設
搜索框 – van-search組件
api/Search.js – 熱搜關鍵字 - 接口方法
Search/index.vue引入-獲取熱搜關鍵字 - 鋪設頁面
點擊文字填充到輸入框
- 準備搜索界面標簽
<template><div><van-searchshape="round"placeholder="請輸入搜索關鍵詞"/><!-- 搜索下容器 --><div class="search_wrap"><!-- 標題 --><p class="hot_title">熱門搜索</p><!-- 熱搜關鍵詞容器 --><div class="hot_name_wrap"><!-- 每個搜索關鍵詞 --><spanclass="hot_item">熱搜關鍵字</span></div></div></div>
</template>
<script>
export default {}
</script><style scoped>
/* 搜索容器的樣式 */
.search_wrap {padding: 0.266667rem;
}/*熱門搜索文字標題樣式 */
.hot_title {font-size: 0.32rem;color: #666;
}/* 熱搜詞_容器 */
.hot_name_wrap {margin: 0.266667rem 0;
}/* 熱搜詞_樣式 */
.hot_item {display: inline-block;height: 0.853333rem;margin-right: 0.213333rem;margin-bottom: 0.213333rem;padding: 0 0.373333rem;font-size: 0.373333rem;line-height: 0.853333rem;color: #333;border-color: #d3d4da;border-radius: 0.853333rem;border: 1px solid #d3d4da;
}/* 給單元格設置底部邊框 */
.van-cell {border-bottom: 1px solid lightgray;
}
</style>
- api/Search.js - 定義熱門搜索接口方法和搜索結果方法
import request from '@/utils/request'// 熱搜關鍵字
export const hotSearch = () => request({url: '/search/hot'
})// 搜索結果列表
export const searchResult = params => request({url: '/cloudsearch',params
})
- api/index.js - 導入使用并統一導出
// 統一出口
// 你也可以在邏輯頁面里.vue中直接引入@/api/Home下的網絡請求工具方法
// 為什么: 我們可以把api所有的方法都統一到一處. import {recommendMusic, hotMusic} from '@/api/Home'
import {hotSearch, searchResult} from '@/api/Search'export const recommendMusicAPI = recommendMusic // 把網絡請求方法拿過來 導出
export const hotMusicAPI = hotMusic // 把獲取最新音樂的, 網絡請求方法導出export const hotSearchAPI = hotSearch // 熱搜
export const searchResultAPI = searchResult // 搜索結果
- created中請求接口-拿到熱搜關鍵詞列表
<!-- 每個搜索關鍵詞 -->
<spanclass="hot_item"v-for="(obj, index) in hotArr":key="index">{{ obj.first }}</span><script>// 目標: 鋪設熱搜關鍵字// 1. 搜索框van-search組件, 關鍵詞標簽和樣式// 2. 找接口, api/Search.js里定義獲取搜索關鍵詞的請求方法// 3. 引入到當前頁面, 調用接口拿到數據循環鋪設頁面// 4. 點擊關鍵詞把值賦予給van-search的v-model變量import { hotSearchAPI } from "@/api";export default {data(){return {hotArr: [], // 熱搜關鍵字}},async created() {const res = await hotSearchAPI();console.log(res);this.hotArr = res.data.result.hots;},}
</script>
- 點擊熱詞填充到輸入框
<van-searchshape="round"v-model="value"placeholder="請輸入搜索關鍵詞"/>
<!-- 每個搜索關鍵詞 -->
<spanclass="hot_item"v-for="(obj, index) in hotArr":key="index"@click="fn(obj.first)">{{ obj.first }}</span>
</div><script>export default {data(){return {value: "",hotArr: [], // 熱搜關鍵字}},// ...省略了createdmethods: {async fn(val) {// 點擊熱搜關鍵詞this.value = val; // 選中的關鍵詞顯示到搜索框},}}
</script>
總結: 寫好標簽和樣式, 拿到數據循環鋪設, 點擊關鍵詞填入到van-search中
1.12 網易云音樂-搜索-點擊熱詞-搜索結果
目標: 點擊熱詞填充到輸入框-出搜索結果
api/Search.js - 搜索結果, 接口方法
Search/index.vue引入-獲取搜索結果 - 鋪設頁面
和熱搜關鍵字容器 – 互斥顯示
點擊文字填充到輸入框, 請求搜索結果鋪設
- 搜索結果顯示區域標簽+樣式(直接復制/vant文檔找)
<!-- 搜索結果 --><div class="search_wrap"><!-- 標題 --><p class="hot_title">最佳匹配</p><van-cellcentertitle='結果名字'><template #right-icon><van-icon name="play-circle-o" size="0.6rem"/></template></van-cell></div>
- 點擊 - 獲取搜索結果 - 循環鋪設頁面
<template><div><van-search shape="round" v-model="value" placeholder="請輸入搜索關鍵詞" /><!-- 搜索下容器 --><div class="search_wrap"><!-- 標題 --><p class="hot_title">熱門搜索</p><!-- 熱搜關鍵詞容器 --><div class="hot_name_wrap"><!-- 每個搜索關鍵詞 --><spanclass="hot_item"v-for="(obj, index) in hotArr":key="index"@click="fn(obj.first)">{{ obj.first }}</span></div></div><!-- 搜索結果 --><div class="search_wrap"><!-- 標題 --><p class="hot_title">最佳匹配</p><van-cellcenterv-for="obj in resultList":key="obj.id":title="obj.name":label="obj.ar[0].name + ' - ' + obj.name"><template #right-icon><van-icon name="play-circle-o" size="0.6rem"/></template></van-cell></div></div>
</template>
<script>
// 目標: 鋪設熱搜關鍵字
// 1. 搜索框van-search組件, 關鍵詞標簽和樣式
// 2. 找接口, api/Search.js里定義獲取搜索關鍵詞的請求方法
// 3. 引入到當前頁面, 調用接口拿到數據循環鋪設頁面
// 4. 點擊關鍵詞把值賦予給van-search的v-model變量// 目標: 鋪設搜索結果
// 1. 找到搜索結果的接口 - api/Search.js定義請求方法
// 2. 再定義methods里getListFn方法(獲取數據)
// 3. 在點擊事件方法里調用getListFn方法拿到搜索結果數據
// 4. 鋪設頁面(首頁van-cell標簽復制過來)
// 5. 把數據保存到data后, 循環van-cell使用即可(切換歌手字段)
// 6. 互斥顯示搜索結果和熱搜關鍵詞
import { hotSearchAPI, searchResultListAPI } from "@/api";
export default {data() {return {value: "",hotArr: [], // 熱搜關鍵字resultList: [], // 搜索結果};},async created() {const res = await hotSearchAPI();console.log(res);this.hotArr = res.data.result.hots;},methods: {async getListFn() {return await searchResultListAPI({keywords: this.value,limit: 20,}); // 把搜索結果return出去// (難點):// async修飾的函數 -> 默認返回一個全新Promise對象// 這個Promise對象的結果就是async函數內return的值// 拿到getListFn的返回值用await提取結果},async fn(val) {// 點擊熱搜關鍵詞this.value = val; // 選中的關鍵詞顯示到搜索框const res = await this.getListFn();console.log(res);this.resultList = res.data.result.songs;},},
};
</script>
- 互斥顯示, 熱搜關鍵詞和搜索結果列表
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PT6s4FOa-1666013240404)(images/image-20210512142504929.png)]
總結: 點擊熱詞后, 調用接口傳入關鍵詞, 返回數據鋪設
1.13 網易云音樂-輸入框-搜索結果
目標: 監測輸入框改變-拿到搜索結果
觀察van-search組件是否支持和實現input事件
綁定@input事件和方法
在事件處理方法中獲取對應的值使用
如果搜索不存在的數據-要注意接口返回字段不同
- 綁定@input事件在van-search上
<van-search shape="round" v-model="value" placeholder="請輸入搜索關鍵詞" @input="inputFn"/>
- 實現輸入框改變 - 獲取搜索結果鋪設
async inputFn() {// 輸入框值改變if (this.value.length === 0) {// 搜索關鍵詞如果沒有, 就把搜索結果清空阻止網絡請求發送(提前return)this.resultList = [];return;}const res = await this.getListFn();console.log(res);// 如果搜索結果響應數據沒有songs字段-無數據if (res.data.result.songs === undefined) {this.resultList = [];return;}this.resultList = res.data.result.songs;
},
總結: 監測輸入框改變-保存新的關鍵詞去請求結果回來鋪設
1.14 網易云音樂-搜索結果-加載更多
目標: 觸底后, 加載下一頁數據
觀察接口文檔: 發現需要傳入offset和分頁公式
van-list組件監測觸底執行onload事件
配合后臺接口, 傳遞下一頁的標識
拿到下一頁數據后追加到當前數組末尾即可
- 設置van-list組件實現相應的屬性和方法, 讓page++去請求下頁數據
<van-listv-model="loading":finished="finished"finished-text="沒有更多了"@load="onLoad"><van-cellcenterv-for="obj in resultList":key="obj.id":title="obj.name":label="obj.ar[0].name + ' - ' + obj.name"><template #right-icon><van-icon name="play-circle-o" size="0.6rem" /></template></van-cell></van-list>
<script>
// 目標: 加載更多
// 1. 集成list組件-定義相關的變量(搞懂變量的作用) -監測觸底事件
// 2. 一旦觸底, 自動執行onload方法
// 3. 對page++, 給后臺傳遞offset偏移量參數-請求下一頁的數據
// 4. 把當前數據和下一頁新來的數據拼接起來用在當前 頁面的數組里
// (切記) - 加載更多數據后,一定要把loading改成false, 保證下一次還能觸發onload方法
export default {data() {return {value: "",hotArr: [], // 熱搜關鍵字resultList: [], // 搜索結果loading: false, // 加載中 (狀態) - 只有為false, 才能觸底后自動觸發onload方法finished: false, // 未加載全部 (如果設置為true, 底部就不會再次執行onload, 代表全部加載完成)page: 1, // 當前搜索結果的頁碼};},// ...省略其他methods: {async getListFn() {return await searchResultListAPI({keywords: this.value,limit: 20,offset: (this.page - 1) * 20, // 固定公式}); // 把搜索結果return出去// (難點):// async修飾的函數 -> 默認返回一個全新Promise對象// 這個Promise對象的結果就是async函數內return的值// 拿到getListFn的返回值用await提取結果},async onLoad() {// 觸底事件(要加載下一頁的數據咯), 內部會自動把loading改為truethis.page++;const res = await this.getListFn();this.resultList = [...this.resultList, ...res.data.result.songs];this.loading = false; // 數據加載完畢-保證下一次還能觸發onload},},
};
</script>
總結: list組件負責UI層監測觸底, 執行onload函數, page++, 請求下頁數據, 和現在數據合并顯示更多, 設置loading為false, 確保下次觸底還能執行onLoad
1.15 網易云音樂-加載更多-bug修復
目標: 如果只有一頁數據/無數據判斷
無數據/只有一頁數據, finished為true
防止list組件觸底再加載更多
還要測試-按鈕點擊/輸入框有數據情況的加載更多
正確代碼
async fn(val) {// 點擊熱搜關鍵詞
+ this.finished = false; // 點擊新關鍵詞-可能有新的數據this.value = val; // 選中的關鍵詞顯示到搜索框const res = await this.getListFn();console.log(res);this.resultList = res.data.result.songs;
+ this.loading = false; // 本次數據加載完畢-才能讓list加載更多},async inputFn() {
+ this.finished = false // 輸入框關鍵字改變-可能有新數據(不一定加載完成了)// 輸入框值改變if (this.value.length === 0) {// 搜索關鍵詞如果沒有, 就把搜索結果清空阻止網絡請求發送(提前return)this.resultList = [];return;}const res = await this.getListFn();console.log(res);+ // 如果搜索結果響應數據沒有songs字段-無數據
+ if (res.data.result.songs === undefined) {
+ this.resultList = [];
+ return;
+ }this.resultList = res.data.result.songs;
+ this.loading = false;},async onLoad() {// 觸底事件(要加載下一頁的數據咯), 內部會自動把loading改為truethis.page++;const res = await this.getListFn();
+ if (res.data.result.songs === undefined) { // 沒有更多數據了
+ this.finished = true; // 全部加載完成(list不會在觸發onload方法)
+ this.loading = false; // 本次加載完成
+ return;
+ }this.resultList = [...this.resultList, ...res.data.result.songs];
+ this.loading = false; // 數據加載完畢-保證下一次還能觸發onload},
總結: 在3個函數 上和下, 設置finished還未完成, 最后要把loading改成false, 判斷songs字段, 對這里的值要非常熟悉才可以
1.16 網易云音樂-輸入框-防抖
目標: 輸入框觸發頻率過高
輸入框輸入"asdfghjkl"
? 接著快速的刪除
? 每次改變-馬上發送網絡請求
? 網絡請求異步耗時 – 數據回來后還是鋪設到頁面上
解決:
? 引入防抖功能
async inputFn() {// 目標: 輸入框改變-邏輯代碼-慢點執行// 解決: 防抖// 概念: 計時n秒, 最后執行一次, 如果再次觸發, 重新計時// 效果: 用戶在n秒內不觸發這個事件了, 才會開始執行邏輯代碼if (this.timer) clearTimeout(this.timer);this.timer = setTimeout(async () => {this.finished = false; // 輸入框關鍵字改變-可能有新數據(不一定加載完成了)// 輸入框值改變if (this.value.length === 0) {// 搜索關鍵詞如果沒有, 就把搜索結果清空阻止網絡請求發送(提前return)this.resultList = [];return;}const res = await this.getListFn();console.log(res);// 如果搜索結果響應數據沒有songs字段-無數據if (res.data.result.songs === undefined) {this.resultList = [];return;}this.resultList = res.data.result.songs;this.loading = false;}, 900);
},
總結: 降低函數執行頻率
1.17 網易云音樂-頁碼bug修復
目標: 第一個關鍵詞page已經+到了10, 再第二個關鍵詞應該從1開始
加載更多時, page已經往后計數了
重新獲取時, page不是從第一頁獲取的
點擊搜索/輸入框搜索時, 把page改回1
代碼如下:
async fn(val) {// 點擊熱搜關鍵詞
+ this.page = 1; // 點擊重新獲取第一頁數據this.finished = false; // 點擊新關鍵詞-可能有新的數據this.value = val; // 選中的關鍵詞顯示到搜索框const res = await this.getListFn();console.log(res);this.resultList = res.data.result.songs;this.loading = false; // 本次數據加載完畢-才能讓list加載更多},async inputFn() {// 目標: 輸入框改變-邏輯代碼-慢點執行// 解決: 防抖// 概念: 計時n秒, 最后執行一次, 如果再次觸發, 重新計時// 效果: 用戶在n秒內不觸發這個事件了, 才會開始執行邏輯代碼if (this.timer) clearTimeout(this.timer);this.timer = setTimeout(async () => {
+ this.page = 1; // 點擊重新獲取第一頁數據this.finished = false; // 輸入框關鍵字改變-可能有新數據(不一定加載完成了)// 輸入框值改變if (this.value.length === 0) {// 搜索關鍵詞如果沒有, 就把搜索結果清空阻止網絡請求發送(提前return)this.resultList = [];return;}const res = await this.getListFn();console.log(res);// 如果搜索結果響應數據沒有songs字段-無數據if (res.data.result.songs === undefined) {this.resultList = [];return;}this.resultList = res.data.result.songs;this.loading = false;}, 900);},
總結: 切換時, 讓page頁面回到1
1.18 網易云音樂-Layout邊距優化
目標: 上下導航會蓋住中間內容
我們的頭部導航和底部導航擋住了中間內容
給中間路由頁面設置上下內邊距即可
在Layout/index.vue中
/* 中間內容區域 - 容器樣式(留好上下導航所占位置) */
.main {padding-top: 46px;padding-bottom: 50px;
}
1.19 網易云音樂-SongItem封裝
目標: 把首頁和搜索結果的歌曲cell封裝起來
創建src/components/SongItem.vue
<template><van-cell center :title="name" :label="author + ' - ' + name"><template #right-icon><van-icon name="play-circle-o" size="0.6rem"/></template></van-cell>
</template><script>
export default {props: {name: String, // 歌名author: String, // 歌手id: Number, // 歌曲id (標記這首歌曲-為將來跳轉播放頁做準備)}
};
</script><style scoped>
/* 給單元格設置底部邊框 */
.van-cell {border-bottom: 1px solid lightgray;
}
</style>
Home/index.vue - 重構
注意: author字段不同
<SongItem v-for="obj in songList":key="obj.id":name="obj.name":author="obj.song.artists[0].name":id="obj.id"
></SongItem>
Search/index.vue - 重構
注意: author字段不同
<SongItemv-for="obj in resultList":key="obj.id":name="obj.name":author="obj.ar[0].name":id="obj.id"
></SongItem>
總結: 遇到重復標簽要封裝
1.20 網易云音樂-播放音樂
目標: 從預習資料拿到播放的api和頁面, 配置好路由規則
時間關系,這個頁面不用寫, 直接用, 注釋在備課代碼里寫好了
組件SongItem里 – 點擊事件
api/Play.js – 提前準備好 – 接口方法
跳轉到Play頁面 – 把歌曲id帶過進去
在SongItem.vue - 點擊播放字體圖標
methods: {playFn(){this.$router.push({path: '/play',query: {id: this.id // 歌曲id, 通過路由跳轉傳遞過去}})}
}
總結: 準備好播放頁, 點擊播放傳歌曲id過去, 到播放頁-再請求響應數據和歌曲地址用audio標簽播放
1.21 網易云音樂-vant適配
目標: 切換不同機型, 刷新后看看標簽大小適配嗎
- postcss – 配合webpack翻譯css代碼
- postcss-pxtorem – 配合webpack, 自動把px轉成rem
- 新建postcss.config.js – 設置相關配置
- 重啟服務器, 再次觀察Vant組件是否適配
-
下載postcss和postcss-pxtorem@5.1.1
postcss作用: 是對css代碼做降級處理
postcss-pxtorem: 自動把所有代碼里的css樣式的px, 自動轉rem
-
src/新建postcss.config.js
module.exports = {plugins: {'postcss-pxtorem': {// 能夠把所有元素的px單位轉成Rem// rootValue: 轉換px的基準值。// 例如一個元素寬是75px,則換成rem之后就是2rem。rootValue: 37.5,propList: ['*']}}
}
以iphone6為基準, 37.5px為基準值換算rem
今日總結
- 掌握vant組件庫的使用 - 找組件, 引組件, 用組件
- 能夠對vant組件自帶樣式進行覆蓋自定義
- 遇到重復的標簽, 自己也封裝了一個復用的組件
- 掌握查詢文檔和使用每個屬性的方式
今日作業
:id="obj.id"
> 總結: 遇到重復標簽要封裝### 1.20 網易云音樂-播放音樂> 目標: 從預習資料拿到播放的api和頁面, 配置好路由規則==時間關系,這個頁面不用寫, 直接用, 注釋在備課代碼里寫好了==組件SongItem里 – 點擊事件api/Play.js – 提前準備好 – 接口方法跳轉到Play頁面 – 把歌曲id帶過進去在SongItem.vue - 點擊播放字體圖標```js
methods: {playFn(){this.$router.push({path: '/play',query: {id: this.id // 歌曲id, 通過路由跳轉傳遞過去}})}
}
[外鏈圖片轉存中…(img-6Nfu2lIp-1666013240405)]
總結: 準備好播放頁, 點擊播放傳歌曲id過去, 到播放頁-再請求響應數據和歌曲地址用audio標簽播放
1.21 網易云音樂-vant適配
目標: 切換不同機型, 刷新后看看標簽大小適配嗎
- postcss – 配合webpack翻譯css代碼
- postcss-pxtorem – 配合webpack, 自動把px轉成rem
- 新建postcss.config.js – 設置相關配置
- 重啟服務器, 再次觀察Vant組件是否適配
-
下載postcss和postcss-pxtorem@5.1.1
postcss作用: 是對css代碼做降級處理
postcss-pxtorem: 自動把所有代碼里的css樣式的px, 自動轉rem
-
src/新建postcss.config.js
module.exports = {plugins: {'postcss-pxtorem': {// 能夠把所有元素的px單位轉成Rem// rootValue: 轉換px的基準值。// 例如一個元素寬是75px,則換成rem之后就是2rem。rootValue: 37.5,propList: ['*']}}
}
以iphone6為基準, 37.5px為基準值換算rem
今日總結
- 掌握vant組件庫的使用 - 找組件, 引組件, 用組件
- 能夠對vant組件自帶樣式進行覆蓋自定義
- 遇到重復的標簽, 自己也封裝了一個復用的組件
- 掌握查詢文檔和使用每個屬性的方式
今日作業
把課上的案例-從0再來一遍, 為下階段移動端項目鋪墊
總結
以上是生活随笔為你收集整理的Day08_vant实现_网易云音乐案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Educational Codeforc
- 下一篇: 二十四节气之大暑时节常识介绍