1.0 vant组件库-介绍

目标: vant是一个轻量、可靠的移动端 Vue 组件库, 开箱即用

vant官网

特点:

  • 提供 60 多个高质量组件,覆盖移动端各类场景

  • 性能极佳,组件平均体积不到 1kb

  • 完善的中英文文档和示例

  • 支持 Vue 2 & Vue 3

  • 支持按需引入和主题定制

1.1  按需导入

  1. 安装插件

    yarn add babel-plugin-import -D
  2. 在babel配置文件里 (babel.config.js)

    module.exports = {plugins: [['import', {libraryName: 'vant',libraryDirectory: 'es',style: true}, 'vant']]
    };
  3. 全局注册 - 会自动按需引入

    // 方式1: 全局 - 自动按需引入vant组件
    // (1): 下载 babel-plugin-import
    // (2): babel.config.js - 添加官网说的配置 (一定要重启服务器)
    // (3): main.js 按需引入某个组件, Vue.use全局注册 - 某个.vue文件中直接使用vant组件
    import { Button } from 'vant';
    Vue.use(Button) // Button组件全局注册, 真正注册的组件名VanButton

2 前端项目初始化

目标: 初始化项目, 下载必备包, 引入初始文件, 配置按需自动引入vant, 创建页面组件

  1. 初始化工程

    vue create music-demo
    
  2. 下载需要的所有第三方依赖包

    yarn add axios vant vue-router 
  3. 引入笔记代码里准备好的reset.css和flexible.js - 实现样式初始化和适配问题 - 引入到main.js

    // 首先是一个立即执行函数,执行时传入的参数是window和document
    (function flexible (window, document) {var docEl = document.documentElement // 返回文档的root元素var dpr = window.devicePixelRatio || 1 // 获取设备的dpr,即当前设置下物理像素与虚拟像素的比值// 调整body标签的fontSize,fontSize = (12 * dpr) + 'px'// 设置默认字体大小,默认的字体大小继承自bodyfunction setBodyFontSize () {if (document.body) {document.body.style.fontSize = (12 * dpr) + 'px'} else {document.addEventListener('DOMContentLoaded', setBodyFontSize)}}setBodyFontSize();// set 1rem = viewWidth / 10// 设置root元素的fontSize = 其clientWidth / 10 + ‘px’function setRemUnit () {var rem = docEl.clientWidth / 10docEl.style.fontSize = rem + 'px'}// 移动端的适配如何做// (1): 所有的css单位, rem    (vscode可以自动把px转成rem, pxtorem插件设置基准值37.5) - 1rem等于37.5px//  原理: rem要根据html的font-size换算//  目标: 网页宽度变小, html的font-size也要变小, ...网页变大, html的font-size变大.// (2): flexible.js (专门负责当网页宽度改变, 会修改html的font-size)setRemUnit()// 当我们页面尺寸大小发生变化的时候,要重新设置下rem 的大小window.addEventListener('resize', setRemUnit)// pageshow 是我们重新加载页面触发的事件window.addEventListener('pageshow', function(e) {// e.persisted 返回的是true 就是说如果这个页面是从缓存取过来的页面,也需要从新计算一下rem 的大小if (e.persisted) {setRemUnit()}})// 检测0.5px的支持,支持则root元素的class中有hairlinesif (dpr >= 2) {var fakeBody = document.createElement('body')var testElement = document.createElement('div')testElement.style.border = '.5px solid transparent'fakeBody.appendChild(testElement)docEl.appendChild(fakeBody)if (testElement.offsetHeight === 1) {docEl.classList.add('hairlines')}docEl.removeChild(fakeBody)}}(window, document))
    body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, textarea, p, blockquote, th, td {padding: 0;margin: 0;
    }table {border-collapse: collapse;border-spacing: 0;
    }fieldset, img {border: 0;
    }address, caption, cite, code, dfn, em, strong, th, var {font-weight: normal;font-style: normal;
    }ol, ul {list-style: none;
    }caption, th {text-align: left;
    }h1, h2, h3, h4, h5, h6 {font-weight: normal;font-size: 100%;
    }q:before, q:after {content: '';
    }abbr, acronym {border: 0;
    }
  4. 本次vant使用自动按需引入的方式

    文档: Vant 4 - A lightweight, customizable Vue UI library for mobile web apps.

    yarn add babel-plugin-import  -D

    在babel.config.js - 添加插件配置

    plugins: [['import', {libraryName: 'vant',libraryDirectory: 'es',style: true}, 'vant']
    ]

5 新建postcss.config.js

# yarn add -D postcss-pxtorem
# -D 是 --save-dev 的简写
npm install postcss-pxtorem -D
module.exports = {plugins: {'postcss-pxtorem': {// 能够把所有元素的px单位转成Rem// rootValue: 转换px的基准值。// 例如一个元素宽是75px,则换成rem之后就是2rem。rootValue: 37.5,propList: ['*']}}}

以iphone6为基准,37.5px为基准换算rem 。有了插件,省去了我们换算的过程

参考:Error:Loading PostCSS Plugin failed: Cannot find module ‘postcss-pxtorem‘_屿-·的博客-CSDN博客

3路由文件配置

3.1 创建路由文件

3.2 创建路由

3.3 注入整个项目当中

3.4   编写出口 

4  页面中: 切换场景就是用路由

中间部分的改变就是路由,添加二级路由(在layout 里边写的)

4.1 添加挂载点

测试: 切换地址看是否发生变化

4.3  不光调到layout,还要调到二级路由的一个

5tabbar组件

目标: 点击底部导航, 切换路由页面显示

文档: Vant 4 - A lightweight, customizable Vue UI library for mobile web apps.

  1. 注册Tabbar组件, 在main.js中

    import { Tabbar, TabbarItem  } from 'vant';
    Vue.use(Tabbar);
    Vue.use(TabbarItem);
  2. 在Layout.vue中使用

5.1 切换TabBar 进行切换

<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>
  1. 开启路由模式 route属性, 和to属性指向要切换的路由路径

5NavBar导航组件

目标: 实现顶部标题展示

文档: Vant 4 - A lightweight, customizable Vue UI library for mobile web apps.

5.1  main.js - 注册NavBar组件

import { NavBar } from 'vant';
Vue.use(NavBar);

title控制标题,现在想不同的组件显示不同的标题: 使用路由元

5.2 复制文档里的, 然后删删只留标题

<van-nav-bar :title="activeTitle" fixed />
​
<script>export default {activeTitle: "首页"}
</script>

5.3  网易云音乐-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显示},},
    };

总结: 点击底部导航和刷新当前网页, 都能保证导航标题的正确显示

头部固定:fixed

<van-nav-bar :title="activeTitle" fixed />

因为固定高度,里边的东西被导航栏遮住了,所以给里边的内容添加padding

内容撑开, nav-bar ,tabBar 并没有固定住:

解决:添加 在main区域添加  overflow-y: scroll;

6网络封装

目标: 不想把网络请求散落在各个逻辑页面里, 不然以后找起来改起来很麻烦

  1. 封装utils/request.js - 基于axios进行二次封装 - 设置基础地址

    // 网络请求 - 二次封装
    import axios from 'axios'
    axios.defaults.baseURL = "http://localhost:3000"
    export default axios
  2. 封装src/api/Home.js

    统一封装网络请求方法

    // 文件名-尽量和模块页面文件名统一(方便查找)
    import request from '@/utils/request'
    ​
    // 首页 - 推荐歌单
    export const recommendMusic = params => request({url: '/personalized',params// 将来外面可能传入params的值 {limit: 20}
    })
  3. 在src/api/index.js - 统一导出接口供外部使用

    // api文件夹下 各个请求模块js, 都统一来到index.js再向外导出
    import {recommendMusic} from './Home'
    ​
    export const recommendMusicAPI = recommendMusic // 请求推荐歌单的方法导出
  4. 在main.js - 测试使用一下.

    import { recommendMusicAPI } from '@/api/index'
    async function myFn(){const res = await recommendMusicAPI({limit: 6});console.log(res);
    }
    myFn();

总结: 封装网络请求方法目的, 方便我们统一管理

7 推荐歌单

7.1 布局:

图片设置宽和高  只设置高会等比例变化,有可能高太大,需要设置一个具体高度, 使图片自适应

img {

width: 100%;

height:100px;

object-fit: cover;

}

字体超出两行 省略号:

 word-break: break-all;text-overflow: ellipsis;display: -webkit-box; /** 对象作为伸缩盒子模型显示 **/-webkit-box-orient: vertical; /** 设置或检索伸缩盒对象的子元素的排列方式 **/-webkit-line-clamp: 2; /** 显示的行数 **/overflow: hidden; /** 隐藏超出的内容 **/

7. 2调用接口, 并渲染

  1. 在api/index.js下定义推荐歌单的接口方法

    // 首页 - 推荐歌单
    export const recommendMusic = params => request({url: '/personalized',params// 将来外面可能传入params的值 {limit: 20}
    })
  2. 把数据请求回来, 用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>

8网易云音乐- 首页-最新音乐

目标: van-cell单元格使用

请求地址: /personalized/newsong

  1. 引入van-cell使用 - 注册组件main.js中

    import {Cell} from 'vant';
    Vue.use(Cell);
  2. 定义接口请求方法 - api/index.js

    // 首页 - 推荐最新音乐
    export const newMusic = params => request({url: "/personalized/newsong",params
    })
  3. 列表数据铺设 - 插入自定义标签

    <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>

修改样式不起作用没需要我们定制主题

8.1 定制vant组件样式

按步骤进行修改:

​​​​​​

8.2 切换图标

9 热门数据

========

搜索框 – van-search组件

api/Search.js – 热搜关键字 - 接口方法

Search/index.vue引入-获取热搜关键字 - 铺设页面

点击文字填充到输入框

9.1 展示热门搜索数据

  1. 准备搜索界面标签

<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>

span{
     display: inline-block;

padding: 5px 20px;

margin-right: 5px;

margin-bottom: 5px;

}

因为文字的个数不同,不能设置宽度, 设置padding是它水平居中对其

位置: 每一个添加 右边距, 下边距

span记得转成行内块元素,否则

  1. api/Search.js - 定义热门搜索接口方法和搜索结果方法

import request from '@/utils/request'
​
// 热搜关键字
export const hotSearch = () => request({url: '/search/hot'
})
​
// 搜索结果列表
export const searchResult = params => request({url: '/cloudsearch',params
})
  1. 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 // 搜索结果
  1. 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>

9.2点击热词填充到输入框

<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中

9.3 监听到数据变化,调用查询歌单列表

1 渲染列表数据

 <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>
  1. 互斥显示, 热搜关键词和搜索结果列表

9.4 防抖-对于搜索框的使用

输入一个字就调用一次接口,用户体验效果不好, 我们这需要防抖,在用户停止操作的时候触发接口(最后一次)

9.5 点击按钮马上处理函数

9.6 封装歌曲组件

首页和搜索页都有这些样式,则抽取封装成组件进行使用

使用:

10 路由缓存

切换路由被释放了,页面重新加载了一遍,所有代码走了一遍

解决:路由缓存

11 歌曲播放

整个页面切换,应该和layout 平级

点击按钮,跳转到下一页(路由跳转 传参数)

12 评论页面

12.1 配置路由

12.2 跳转到评论页

12.3 返回上一级

12.4 下拉刷新

12.5 上拉加载更多

走到底部的时候进行调用接口

01 网易云音乐 vant -黑相关推荐

  1. Vue2 - 网易云音乐项目笔记(基于Vant UI组件库)

    目录 一.项目技术 二.准备工作 1.初始化Vue项目 2.配置Vant UI组件库 3.下载并使用vue-router库 4.接口API 5.postcss插件 三.分析页面实现功能 1.路由页面准 ...

  2. vue2中vant实现网易云音乐案例-附带所有源码

    vue2中vant实现网易云音乐案例-附带所有源码 前言 学习笔记以及源码下载gitee: https://gitee.com/xingyueqianduan/vantmsicdemo 下载下来的内容 ...

  3. Vue2使用vant实现_网易云音乐案例(可跟做练手项目)

    文章目录 知识点自测 铺垫(自学) 本地接口项目部署 今日学习目标 1. 案例-网易云音乐 1.0 网易云音乐-本地接口 1.1 网易云音乐-本地接口启动 1.2 网易云音乐-前端项目初始化 1.3 ...

  4. Day08_vant实现_网易云音乐案例

    Day08_vant实现_网易云音乐案例 文章目录 Day08_vant实现_网易云音乐案例 知识点自测 铺垫(自学) 本地接口项目部署 今日学习目标 1. 案例-网易云音乐 1.0 网易云音乐-本地 ...

  5. 【Vue知识点- No8.】网易云音乐案例(vant组件库的使用)

    No8.网易云音乐案例 知识点自测 知道reset.css和flexible.js的作用. 什么是组件库-例如bootstrap的作用. yarn命令的使用. 组件名字用name属性方式注册. 如何自 ...

  6. vue3 + TypeScript + vant +pinia 实现网易云音乐播放器

    vue3 + TypeScript + vant +pinia 实现网易云音乐播放器 实现功能 每日推荐 私人FM 歌单广场 排行榜 歌手 歌曲播放 mv播放 上下滑动切换 云盘上传 用户登录 歌单创 ...

  7. 揭秘网易云音乐的个性化推荐算法【黑科技】

    在"精准推荐者得民心"的今天,推荐系统已成为各大互联网公司的标配.但由于现实中很多数据是非欧氏空间生成的(例如,社交网络.信息网络等),一些复杂场景下的业务需求很难通过协同过滤等基 ...

  8. uniapp 仿网易云音乐播放器 微信小程序

    效果视频: uniapp 仿照网易云播放器功能 效果截图: 上代码: <template><view class=""><scroll-view :s ...

  9. Vue3+node.js网易云音乐实战项目(三)

    页面 一.头部导航栏布局 二.轮播图的实现 三.请求网易的banner图 四 链接 一.头部导航栏布局 首先我们看最上面这里的布局,大致可分为三个模块,顶部左边,顶部中间,顶部右边 那么我们在comp ...

最新文章

  1. 使用Azure人脸API对图片进行人脸识别
  2. 前端学习(2404):表单验证总结
  3. 在struts2中push方法的使用_【干货】网版印刷中水墨使用注意事项及助剂使用方法...
  4. ICMP (互联网控制消息协议 )是什么
  5. java 反射 类名_java – 从反射中获取字段的类名
  6. java 如何捕获线程中的异常处理_如何捕获Java中另一个线程抛出的异常?
  7. Project: 项目经理新建资源预订
  8. r语言算巢式设计方差分析_R语言入门之效力分析(Power Analysis)
  9. 第1讲:软件测试背景
  10. Vue H5 项目模板
  11. HTML页面基本结构代码,网页基本代码结构
  12. 信息论复习四:信源编码
  13. IPFS为什么被学者称为数据的“黄金保险柜”?
  14. SUBMAIL群发邮件API接口-Mail/send
  15. 远程服务器挂机好吗,什么服务器挂机好
  16. windows系统电脑间互传文件
  17. 2022QS世界大学排名:全球全日制MBA、商科硕士榜单公布
  18. Java-SpringBoot-使用Sigar采集设备信息
  19. city.json 城市区域数据
  20. dell服务器sas2.5英寸1t硬盘10k,0XTH17 ST900MP0026 900GB 15K SAS 2.5寸DELL服务器硬盘

热门文章

  1. 网站资源文件下载不了怎么办?一个方法教你如何轻松扒下
  2. Android记录5--关于Android云测试的小思考
  3. 深职计算机学院官网,深圳职业中专
  4. 通过JAVA代码,将文字生成图片
  5. 基于JSP的电影院售票系统
  6. 135编辑器html点击图片播放音乐,135微信编辑器怎样添加音乐 135编辑器添加音乐图文教程...
  7. 千年鸿蒙盼尔来兮,古言爱情誓言
  8. 这三款小巧好用的APP,请务必收下
  9. 华为Mate40 Pro/Pro+正式发布 价格曝光
  10. 乔治·布尔二百周年:数理逻辑奠基者其人其事