知识点自测
- 知道reset.css和flexible.js的作用
- 什么是组件库-例如bootstrap作用
- yarn命令的使用
- 组件名字用name属性方式注册
- 如何自定义组件库样式
铺垫(自学)
本地接口项目部署
下载网易云音乐node接口项目, 在本地启动, 为我们vue项目提供数据支持
下载后, 安装所有依赖, 在本地启动起来, 测试访问此地址是否有数据
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 - 添加插件配置
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>