爱凉拌菜真是太好了

vue 中使用iScroll

iScroll 是一个js 多平台滚动库,https://github.com/cubiq/iscroll

这几天用下来发现这个库确实强大,github的star数也已经到达10000多。在vue中使用iScroll 和平常使用大同小异,核心思路都一样。

使用时需要注意几个问题:

  • iScroll 需要在DOM加载完毕过后在进行初始化
  • DOM 更新过后要执行refresh
  • 如果需要监听scroll事件,需要使用iscroll-probe.js版本
  • iScroll 只会对第一个子节点实现滚动, 其余的子节点会自动忽略
  • iScroll 初始化指定的节点最好有position:relative; height: 100%
  • 初始化指定的节点可以加上transform: translate3d(0,0,0),以此开启硬件加速
  • vue 组件中初始化iScroll一定要在mounted钩子函数中,并且使用this.$nextTick()回调,也可以用setTimeout延迟执iScroll的初始化

可以自己通过iScroll实现一个vue组件,可以命名为Scroll;在Scroll 的 template中使用slot插槽, 可以很方便的自行决定Scroll 下面的DOM结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<template>
<!-- iScroll初始化指定的div -->
<div ref="wrapper" class="scroll-wrapper" style="position:relative; -webkit-transform:translate3d(0,0,0);overflow: hidden; height: 100%">
<slot></slot>
</div>
</template>
<script>
export default {
props: {
// 主要的数据 ,这里是属性中的data,这个数据主要来自于父组件
data: {
type: Array,
default: function () {
return null
}
},
// 设置一个refreshTrigger 数据, 只要这个数据改变就执行refresh
refreshTrigger: {
type: [String, Array, Number],
default: ''
},
// 是否监听Scroll ,如果true, 则iscroll 使用probeType: 3 来进行初始化
// 关于probeType: https://github.com/cubiq/iscroll#optionsprobetype
listenScroll: {
type: Boolean,
default: false
}
},
// 这个是vue组件中的data,和属性中的那个data不是一个东西
data () {
return {
scroll: null,
timer: 0,
timer2: 0
}
},
methods: {
scrollTo () {
this.scroll && this.scroll.scrollTo.apply(this.scroll, arguments)
},
scrollToElement () {
this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments)
},
refresh () {
this.scroll && this.scroll.refresh()
}
},
mounted () {
// 这里也可以使用this.$nextTick(() => { this.scroll ... })
this.timer = setTimeout(() => {
/* eslint-disable no-new */
this.scroll = new IScroll(this.$refs.wrapper, {
click: true,
// 是否监听Scroll ,如果true, 则iscroll 使用probeType: 3 来进行初始化;
probeType: this.listenScroll ? 3 : 1,
preventDefault: true,
HWCompositing: true,
disablePointer: true,
bounce: true,
elastic: true
})
}, 20)
},
watch: {
data (value) {
// 必须使用setTimeout 由于refresh 也是异步的
this.timer2 = setTimeout(() => {
this.scroll && this.scroll.refresh()
}, 20)
},
refreshTrigger () {
this.refresh()
}
},
destroyed () {
clearTimeout(this.timer)
clearTimeout(this.timer2)
}
}
</script>
<style scoped lang="stylus" rel="stylesheet/stylus">
/* solve Unable to preventDefault inside passive event listener due to target being treated as passive */
.scroll-wrapper
touch-action: none;
</style>