用Vue来实现音乐播放器(10):Scroll组件的抽象和应用
了解better-scroll什么时候是需要refresh计算的??通常我们遇到的better-scroll不能滚动的问题的根源是什么??better-scroll的渲染原理是:根据初始化的时机 或者调用refresh()的时机的那个时候的scroll的父元素的高度和子元素的高度之差去做一个计算 计算出他可以滚动的位置 所以我们去实例化或者refresh这个scroll的时候 一定要保证 这个dom是已经渲染好的 我们能正确计算到高度的
如果我们有数据变化以及dom变化的场景的时候 我们一定要去让better-scroll重新refresh() 然后我们封装了scroll组件之后 我们就不用在外部掉获取到数据之后 再this.$refs.scroll.refresh() 我们只需要把数据传递给scroll scroll就能监听到数据变化 scroll组件就能自己计算高度
<template>
<div class="recommend">
<scroll class="recommend-content">
<!-- //scroll插件作用于他的第一个子元素 -->
<!-- 局部轮播的父级 -->
<div> <div class="slider-wrapper" v-if="recommend.length"> //这里也是为了在初始化实例和refresh()之前确保dom已经渲染好了
<slider>
<!-- 填写插槽 -->
<div v-for="(item,index) in recommend" :key="index">
<a :href="item.linkUrl">
<img :src="item.picUrl">
</a>
</div>
</slider>
</div>
<div class="recommend-list">
<h1 class="list-title">热门歌单推荐</h1>
<div class="mod-playlist">
<ul class="playlist-list">
<li v-for="(item,index) in discList" :key="index" class="playlist-item">
<div class="playlist-item-box">
<div class="playlist-cover mod-cover">
<a href="#">
<img :src="item.imgurl" class="pic">
</a>
</div>
<h4 class="playlist-title">
<span class="playlist-title-txt">{{item.dissname}}</span>
</h4>
<div class="playlist-author">
<a href="#">{{item.creator.name}}</a>
</div> </div> </li>
</ul>
</div>
</div> </div>
</scroll>
</div>
</template>
<script> import Scroll from '../../base/scroll/scroll.vue'
import Slider from '../../base/slider/slider.vue'
import {getRecommend,getDiscList} from '../../api/recommend.js'
import { ERR_OK } from '../../api/config.js' export default {
data(){//为了将实例里面的轮播图数据与dom相关 要有一个data()方法
return {
recommend:[],
discList:[]
} },
created(){//一般在这个生命钩子里面加载数据
this._getRecommend(),
this._getDiscList()
},
methods:{
_getRecommend(){
getRecommend().then((res)=>{//这个res就是我们抓取到的数据对象
if(res.code===ERR_OK){
// console.log(res.data.slider)
this.recommend=res.data.slider
}
}) },
_getDiscList(){
getDiscList().then((res)=>{
if(res.code===ERR_OK){
// console.log(res.data.list)
this.discList=res.data.list
}
})
},
}, components:{
Slider,Scroll
}
}
<template>
<div ref="wrapper">
<slot></slot>
</div>
</template> <script> //将better-scroll相关都放在这里 可以实现代码的复用 import BScroll from 'better-scroll' export default {
props: {
probeType: {
type: Number,
default: 1
},
click: {
type: Boolean,
default: true
},
data: {//因为我们是滚动的 所以数据会改变 需要一个数组来监听发生的数据变化 从而可以refresh()scroll之后 重新计算滚动的高度
type:Array,
default:null
}
},
//vue在mounted()这个生命周期钩子里面加载dom到页面上 一般在这个钩子里面还可以初始化插件 以及操作dom //要写个定时器,,因为一般数据的请求是异步的 那么异步的数据请求和同样也是异步的mounted()的顺序是什么呢?
//可能是mounted()先执行 那么就会在数据更新之前将dom挂载了 这样会产生虚拟dom
//所以我们要保证dom的挂载是在数据更新之后 所以使用setTimeout() 或者是this.$nextTick
//可以用nextTick 将回调延迟到下次dom更新循环之后执行 在修改数据之后立即使用它,然后等待dom更新 //浏览器渲染一般是17ms 这里延迟到20ms mounted(){
setTimeout(()=>{
this._initScroll(); //better-scroll的渲染原理是 //根据初始化的时机 或者调用refresh()的时机的那个时候的scroll的父元素的高度和子元素的高度之差去做一个计算
//计算出他可以滚动的位置 所以我们去实例化或者refresh这个scroll的时候 一定要保证 这个dom是已经渲染好的 我们能正确计算到高度的
//所以我们在这里一定要保证我们能计算到正确的高度 因此我们要判断一下 此时dom有没有渲染好 在recommend.vue组件中确认
},20)
},
methods:{
_initScroll(){
//在这里先判断一下this.$refs.wrapper是不是undefined
//如果是undefined 那么BScroll类由于第一个参数为undefined会报错
if(!this.$refs.wrapper){
return
}
this.scroll=new BScroll(this.$refs.wrapper,{
probeType:this.probeType,
click:this.click
})
},
enable(){
this.scroll&&this.scroll.enable()
},
disable(){
this.scroll&&this.scroll.disable()
},
refresh(){
this.scroll&&this.scroll.refresh()
}
},
//监控data的变化 如果data变化了 刷新scroll
watch:{
data(){
setTimeout(()=>{
//这里也是操作dom 只要涉及到操作dom就需要延迟
this.refresh()
},20)
}
}
}
</script> <style lang="stylus" scoped> </style>
完成以上这些操作 scroll组件已经初始化了 但是并不能滚动 这是因为 我们初始化这个scroll插件的时机是在scroll.vue组件中的mounted()里面初始化到的 然而我的scroll插件里面的数据是动态渲染拿到的 也就是一个异步操作 即mounted()挂载的前提是 也可以说是实例化或者是refresh()这个插件的前提是 动态获取到数据之后 将dom撑开了之后 能够计算到滚动的高度差之后 在挂载到页面 然后此时我们重新计算scroll 然后调用this.refresh()
才能让scroll正确的滚动

那么我们在recommend.vue中就要确保一下有数据 或者是直接父传子一个data属性 如果recommend.vue中的数据变化了 就会触发scroll.vue中的高度改变
<template>
<div class="recommend">
<!-- 这里的data可以看成是父传子的属性 即<scroll>组件中的props属性下的data
当这里的data改变了的话 scroll组件的data也会改变 因为监听(watch)了data 所以data改变之后就会刷新scroll
即重新计算滚动的高度等等
如果这里先没有传一个data过去 那么我们可能在初始化scroll组件里面的时候可能拿不到数据 如果没有数据
那么scroll组件可能认为不需要滚动
--> <scroll class="recommend-content" :data="discList" ref="scroll">
<!-- //scroll插件作用于他的第一个子元素 -->
<!-- 局部轮播的父级 -->
<div> <!-- 注意这里要写当轮播图的数据都拿到了之后 即slider.vue组件里面的mounted()方法能执行成功之后
执行下面操作
--> <!-- 因为我们的recommend是通过异步拿到的 可能会有延时 但是如果不加上v-if的话 我们可能在没有拿到数据的情况下就
把插槽插入进去了 那么slider.vue里面的mounted()也就执行了
-->
<div class="slider-wrapper" v-if="recommend.length">
<slider>
<!-- 填写插槽 -->
<div v-for="(item,index) in recommend" :key="index">
<a :href="item.linkUrl">
<img :src="item.picUrl" @load="loadImage" class="needsclick">
</a>
</div>
</slider>
</div>
<div class="recommend-list">
<h1 class="list-title">热门歌单推荐</h1>
<div class="mod-playlist">
<ul class="playlist-list">
<li v-for="(item,index) in discList" :key="index" class="playlist-item">
<div class="playlist-item-box">
<div class="playlist-cover mod-cover">
<a href="#">
<img v-lazy="item.imgurl" class="pic">
</a>
</div>
<h4 class="playlist-title">
<span class="playlist-title-txt">{{item.dissname}}</span>
</h4>
<div class="playlist-author">
<a href="#">{{item.creator.name}}</a>
</div> </div> </li>
</ul>
</div>
</div> </div>
</scroll>
</div>
</template>
用Vue来实现音乐播放器(10):Scroll组件的抽象和应用的更多相关文章
- vue小练习--音乐播放器
1 首先建一个文件夹 放几首歌曲 2 看代码 1)基本版本 <!DOCTYPE html> <html lang="zh-CN"> <head> ...
- 用Vue来实现音乐播放器(三十八):歌词滚动列表的问题
1.频繁切换歌曲时,歌词会跳来跳去 原因: // 歌词跳跃是因为内部有一个currentLyric对像内部有一些功能来完成歌词的跳跃 //每个currentLyric能实现歌曲的播放跳到相应的位置 是 ...
- 用Vue来实现音乐播放器(十六):滚动列表的实现
滚动列表是一个基础组件 他是基于scroll组件实现的 在base文件夹下面创建一个list-view文件夹 里面有list-view.vue组件 <template> < ...
- Vue实战:音乐播放器(一) 页面效果
先看一下效果图 首页 歌单详情页 歌手列表 歌手详情页 排行页面 榜单的详情页(排序样式) 搜索页面 搜索结果 播放器内核 歌词自动滚动 播放列表 用户中心
- 用Vue来实现音乐播放器(十四):歌手数据接口抓取
第一步:在api文件夹下创建一个singer.js文件 返回一个getSingerList()方法 使他能够在singer.vue中调用 import jsonp from '../common/j ...
- 用Vue来实现音乐播放器(九):歌单数据接口分析
z这里如果我们和之前获取轮播图的数据一样来获取表单的数据 发现根本获取不到 原因是qq音乐在请求头里面加了authority和refer等 但是如果我们通过jsonp实现跨域来请求数据的话 是根本 ...
- 用Vue来实现音乐播放器(八):自动轮播图啊
slider.vue组件的模板部分 <template> <div class="slider" ref="slider"> <d ...
- 用Vue来实现音乐播放器(二十三):音乐列表
当我们将音乐列表往上滑的时候 我们上面的歌手图片部分也会变小 当我们将音乐列表向下拉的时候 我们的图片会放大 当我们将音乐列表向上滑的时候 我们的图片有一个高斯模糊的效果 并且随着我们的列 ...
- 用Vue来实现音乐播放器(二十一):歌手详情数据抓取
第一步:在api文件夹下的singer.js中抛出getSingerDetail方法 第二步:在singer-detail.vue组件中引入api文件夹下的singer.js和config.js 第三 ...
随机推荐
- [LeetCode] 52. N皇后 II
题目链接 : https://leetcode-cn.com/problems/n-queens-ii/ 题目描述: n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间 ...
- linux查找进程id和杀死进程以及查看内存??
ps 命令用于查看当前正在运行的进程 ps ax : 显示当前系统进程的列表 ps aux : 显示当前系统进程详细列表以及进程用户 -e 显示所有进程,环境变量 此参数的效果和指定"A&q ...
- 3、Java调用C语言(JNA法)
这个方法挺方便的……(改写“二.Java调用C语言(JNative法)“的例子) 一.访问https://github.com/twall/jna ,下载jna-4.1.0.jar(版本不同名字不同) ...
- Docker守护式容器的创建和登录
创建守护式容器 如果对于一个需要长期运行的容器来说,我们可以创建一个守护式容器(后台运行的容器). 创建(-d)并运行(-i)守护式容器命令如下(容器名称不能重复): docker run -id - ...
- MySQL中Innodb的聚簇索引和非聚簇索引
聚簇索引 数据库表的索引从数据存储方式上可以分为聚簇索引和非聚簇索引(又叫二级索引)两种.Innodb的聚簇索引在同一个B-Tree中保存了索引列和具体的数据,在聚簇索引中,实际的数据保存在叶子页中, ...
- 高可用4层lvs——keepalived
搭建方式: node01: ipvsadm -C ifconfig eth0:2 down --------------------------------- node01,node04安装keepa ...
- fhq_treap || BZOJ 3223: Tyvj 1729 文艺平衡树 || Luogu P3391 【模板】文艺平衡树(Splay)
题面: [模板]文艺平衡树(Splay) 题解:无 代码: #include<cstdio> #include<cstring> #include<iostream> ...
- 排序二叉树、平衡二叉树、红黑树、B+树
一.排序二叉树(Binary Sort Tree,BST树) 二叉排序树,又叫二叉搜索树.有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree). 1 ...
- JAVA的深浅拷备
package com.jd.ng.shiro.testFactory; import java.io.*; /** * @author wangzhilei * @Author: husToy.Wa ...
- H5 FormData对象
FormData对象 2018年01月08日 14:31:53 阅读数:2635 FormData对象,可以把所有表单元素的name与value组成一个queryString,提交到后台. 在使用aj ...