better-scroll、父组件给子组件传递函数方法示例、实例化过早的问题
背景:
在移动端触发事件一般不用click 因为有延迟,一般用的是 touchstart (但是有问题,点击滑动都会触发)
所以用tap(只点击生效,滑动不生效) ,但是原生不支持
所以要用第三方的库来实现比如:zepto、vue-touch 、better-scroll(在iscroll之上再做了一层封装)、swiper
better-scroll
1、下载安装
cnpm i -S better-scroll
2、使用
注意:1、内容要足够多 能撑开(如图,橙色是内容)
2、要等数据获取到之后再使用better-croll
在使用的页面引入
import BScroll from 'better-scroll';
数据加载完后实例化
参数:第一个参数是最外层dom,第二个是配置:tap等事件 的一个对象
xxxxxx.then(res=>{
var msg = res.data.msg;
if(msg==='ok'){
this.movieList = res.data.data.films;
this.$nextTick(()=>{
new BScroll(this.$refs.movie_body,{
tap:true,
click:true
});
});
}
})
不得不说nextTick了,因为数据是异步请求过来的,bs需要等数据加载渲染页面后才能实例化,所以正式nextTick使用场景
实现下拉刷新功能
1、在ul列表中和data 添加 提示字段
<li>{{ pullDowmMsg }}</li>
2、在bs第二个配置参数 添加
probeType: 1, // 滚动的时候会派发scroll事件,会截流
3、scroll 事件滑动触发,scrollEnd滑动结束后触发
scroll.on("scroll", (pos) => { if (pos.y > 30) { //pos是位置 pos.y是高度 this.pullDowmMsg = "正在更新中"; } }); scroll.on("touchEnd", (pos) => { if (pos.y > 30) { this.$axios({ url: "https://m.maizuo.com/gateway?cityId=350200&pageNum=1&pageSize=11&type=1&k=8679068", headers: { "X-Client-Info": '{"a":"3000","ch":"1002","v":"5.0.4","e":"1616165493940859830829057"}', "X-Host": "mall.film-ticket.film.list", }, }).then((res) => { var msg = res.data.msg; if (msg === "ok") { this.pullDowmMsg = "更新成功"; setTimeout(() => { this.movieList = res.data.data.films; this.pullDowmMsg = ""; },1000); } }); } });
on()函数用于为指定元素的 一个或多个事件 绑定事件处理函数
组件封装
毕竟不只有一个页面使用,所以把他封装,能更好的复用
1、全局调用 main.js
import Scroller from '@/components/Scroller'
Vue.component('Scroller',Scroller)
2、创建组件
<template> <div class="wrapper" ref="wrapper"> <slot></slot> </div> </template> <script> import BScroll from "better-scroll"; export default { name: "Scroller", data() { return { }; }, props: { handleToScroll: { type: Function, default: function () {}, }, handleToTouchEnd: { type: Function, default: function () {}, }, }, mounted() { var scroll = new BScroll(this.$refs.wrapper, { tap: true, probeType: 1, click: true, }); console.log(scroll); this.scroll = scroll; // this.scroll.hasVerticalScroll=true; this.scroll.on("scroll", (pos) => { console.log("handleToScroll"); this.handleToScroll(pos); }); this.scroll.on("touchEnd", (pos) => { this.handleToTouchEnd(pos); }); }, }; </script> <style scoped> .wrapper { height: 100%; } </style>
3、页面使用模板
<Scroller :handleToScroll="handleToScroll" :handleToTouchEnd="handleToTouchEnd" :key="movieList.length" //给子组件传递函数方法 > <ul> 、、、、 </ul> </Scroller>
方法
methods: { handleToDetail() { console.log("123"); }, handleToScroll(pos) { if (pos.y > 30) { this.pullDowmMsg = "正在更新中"; } }, handleToTouchEnd(pos) { if (pos.y > 30) { this.$axios({ url: "xxx", headers: { "X-Client-Info": 'xx', "X-Host": "xx", }, }).then((res) => { var msg = res.data.msg; if (msg === "ok") { this.pullDowmMsg = "更新成功"; setTimeout(() => { this.movieList = res.data.data.films; this.pullDowmMsg = ""; }, 1000); } }); } }, }
这边我碰到了一个超级大坑,研究了一早上,无非就是那两个问题,内容高度要比容器大,要dom加载成功再实例化bs
然后我。。实例化过早了,滚动失效! 哎,研究了一早上,用diff原理解决就行了,方法在上面代码里。