1.在src/base/sroll中创建scroll.vue
<template>
<div ref="wrapper">
<slot></slot>
</div>
</template>
<script type="text/ecmascript-6">
import BScroll from 'better-scroll'
export default {
props: {
probeType: {
type: Number,
default: 1
},
click: {
type: Boolean,
default: true
},
listenScroll: {
type: Boolean,
default: false
},
data: {
type: Array,
default: null
},
pullup: {
type: Boolean,
default: false
},
beforeScroll: {
type: Boolean,
default: false
},
refreshDelay: {
type: Number,
default: 20
}
},
mounted() {
setTimeout(() => {
this._initScroll()
}, 20)
},
methods: {
_initScroll() {
if (!this.$refs.wrapper) {
return
}
this.scroll = new BScroll(this.$refs.wrapper, {
probeType: this.probeType,
click: this.click
})
if (this.listenScroll) {
let me = this
this.scroll.on('scroll', (pos) => {
me.$emit('scroll', pos)
})
}
if (this.pullup) {
this.scroll.on('scrollEnd', () => {
if (this.scroll.y <= (this.scroll.maxScrollY + 50)) {
this.$emit('scrollToEnd')
}
})
}
if (this.beforeScroll) {
this.scroll.on('beforeScrollStart', () => {
this.$emit('beforeScroll')
})
}
},
disable() {
this.scroll && this.scroll.disable()
},
enable() {
this.scroll && this.scroll.enable()
},
refresh() {
this.scroll && this.scroll.refresh()
},
scrollTo() {
this.scroll && this.scroll.scrollTo.apply(this.scroll, arguments)
},
scrollToElement() {
this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments)
}
},
watch: {
data() {
setTimeout(() => {
this.refresh()
}, this.refreshDelay)
}
}
}
</script>
<style scoped lang="stylus" rel="stylesheet/stylus">
</style>
2.在recommend 中使用
绑定 :data="discList"
完成数据之后再调用sroll的的refresh方法。sroll能用主要取决于内容的高度。
<scroll ref="scroll" class="recommend-content" :data="discList">
<div>
<div v-if="recommends.length" class="slider-wrapper" ref="sliderWrapper">
<slider>
<div v-for="item in recommends">
<a :href="item.linkUrl">
<img class="needsclick" @load="loadImage" :src="item.picUrl">
</a>
</div>
</slider>
</div>
<div class="recommend-list">
<h1 class="list-title">热门歌单推荐</h1>
<ul>
<li @click="selectItem(item)" v-for="item in discList" class="item">
<div class="icon">
<img width="60" height="60" v-lazy="item.imgurl">
</div>
<div class="text">
<h2 class="name" v-html="item.creator.name"></h2>
<p class="desc" v-html="item.dissname"></p>
</div>
</li>
</ul>
</div>
</div>
<div class="loading-container" v-show="!discList.length">
<loading></loading>
</div>
</scroll>
为了防止屏幕改变导致scroll不能计算出滚动区域的大小,给图片绑定一个loadImage的方法。触动sroll重新计算。
<img class="needsclick" @load="loadImage" :src="item.picUrl">
在loadImage中。this.checkloaded 表示以经加载过了
loadImage() {
if (!this.checkloaded) {
this.checkloaded = true
this.$refs.scroll.refresh()
}
},
确认dom已经渲染了,如果dom变化,去调用srcoll的刷新方法
3.懒加载
引入
"vue-lazyload": "1.0.3",
在main.js里面引用 强调内容
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload, {
loading: require('common/image/default.png')
})
4.click冲突
srcoll中
click: {
type: Boolean,
default: true
},
main.js中引用了fastclick
从点击屏幕上的元素到触发元素的 click 事件,移动浏览器会有大约 300 毫秒的等待时间。因为它想看看你是不是要进行双击(double tap)操作。
import fastclick from 'fastclick'
fastclick.attach(document.body)
解决方法 给img添加class needsclick
<slider>
<div v-for="item in recommends">
<a :href="item.linkUrl">
<img class="needsclick" @load="loadImage" :src="item.picUrl">
</a>
</div>
</slider>
5.准备loading基础组件,在recommend中引用
外部需要一个容器discList.length没有的时候显示
<div class="loading-container" v-show="!discList.length">
<loading></loading>
</div>