/**
* @component Scroll
* @description
*
* ## 滚动组件 / Scroll滚动组件
*
* ### 来源
*
* Content组件也具有滚动属性, 但是Content组件的定位是页面基础布局的中间层, 也就是内容层, 这个内容层也支持jsScroll, 但是不支持滚动事件, 移除也是为了考虑性能的问题. 当然也有特殊情况, 如果内容层希望能有一个支持jsScroll的子组件这里就需要Scroll组件了.
*
* 比如:
*
* - 订单App, 左侧的菜单类别, 右侧类别详情(菜单详情).
* - 滑动可切换的tab组件, 能更具我外接触发滚动祖选择等.
* - 横向的跑马灯, 根据指令切换到某个位置.
* - 对Content组件的拓展, 是的浏览内容支持jsScroll
*
* ### 传参及事件
*
* Scroll组件是对 `better-scroll` 组件的封装, 组件书写完毕也是初始化完毕的时候, props就是传入的参数, 如果需要监听事件, 则通过@绑定即可, 例如:
*
* ```
* <Scroll @scroll="scrollHandler" ref="scroll">内容</Scroll>
* ```
*
* 虽然事件的命名不符合Vimo既有规范, 但这部分是封装了better-scroll, 因此不改变原基础为好, `better-scroll`的文档参看下方链接.
*
* 通过ref获取组件实例进行操作, 因此使用逻辑完全一致. 其余详情请参考下方链接.
*
*
* ### 获取jsScroll的实例
* ```
* <Scroll ref="scroll">内容</Scroll>
*
* computed: {
* scrollComponent () {
* return this.$refs.scroll.jsScrollInstance
* }
* }
* ```
*
* ### 关于销毁
*
* 组件关闭自动销毁, 因此不存在持续占用内存的问题
*
* ### 如何引入
* ```
* // 引入
* import { Scroll } from 'vimo'
* // 安装
* Vue.component(Scroll.name, Scroll)
* // 或者
* export default{
* components: {
* Scroll
* }
* }
* ```
*
*/
/**
* @component Scroll
* @description
*
* 滚动列表,提供了优质的原生滚动体验,便捷的配置项和事件,是一个基于`better-scroll`进行封装的组件。
*
* ### 示例
*
* - 基本使用
*
* 通过设置 `data` 属性为一个数组,即可生成能够在容器内优雅滚动的列表。
*
* ```html
* <div class="scroll-wrapper">
* <vm-scroll>
* <vm-list>
<vm-item v-for="item in datas">{{item.text}}</vm-item>
</vm-list>
* </vm-scroll>
* </div>
* ```
- 配置 better-scroll 选项
通过 options 属性可以配置 better-scroll 的选项,包括滚动条、下拉刷新、上拉加载等,具体可查看 better-scroll 的[官方文档](https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/options.html),这里仅对几个常用的配置项进行介绍说明。
1)滚动条
默认无滚动条,还可设为淡入淡出滚动条或一直显示滚动条。
```html
<vm-scroll :options="options">
<vm-list>
<vm-item v-for="item in datas">{{item.text}}</vm-item>
</vm-list>
</vm-scroll>
```
```javascript
export default {
data() {
return {
datas: [1, 2, 3, 4, 5],
options: {
scrollbar: {
fade: false
}
}
}
}
}
```
2)下拉刷新
默认无下拉刷新功能,可通过配置项`pullDownRefresh`开启`pulling-down`事件派发和下拉动画,你可以监听`pulling-down`事件更新数据。
```html
<vm-scroll
ref="scroll"
:options="options"
@pulling-down="onPullingDown">
<vm-list>
<vm-item v-for="item in datas">{{item.text}}</vm-item>
</vm-list>
</vm-scroll>
```
```javascript
export default {
data() {
return {
items: [1, 2, 3, 4, 5],
options: {
pullDownRefresh: {
threshold: 90,
stop: 40,
txt: 'Refresh success'
}
}
}
},
methods: {
onPullingDown() {
// 模拟更新数据
setTimeout(() => {
if (Math.random() > 0.5) {
// 如果有新数据
this.items.unshift('I am new data: ' + +new Date())
} else {
// 如果没有新数据
this.$refs.scroll.forceUpdate()
}
}, 1000)
}
}
}
```
3)上拉加载
默认无上拉加载功能,可通过配置项`pullUpLoad`开启`pulling-up`事件派发和上拉动画,你可以监听`pulling-up`事件更新数据。
```html
<vm-scroll
ref="scroll"
:options="options"
@pulling-up="onPullingUp">
<vm-list>
<vm-item v-for="item in datas">{{item.text}}</vm-item>
</vm-list>
</vm-scroll>
```
```javascript
export default {
data() {
return {
items: [1, 2, 3, 4, 5],
itemIndex: 5,
options: {
pullUpLoad: {
threshold: 0,
txt: {
more: 'Load more',
noMore: 'No more data'
}
}
}
}
},
methods: {
onPullingUp() {
// 更新数据
setTimeout(() => {
if (Math.random() > 0.5) {
// 如果有新数据
let newPage = [
'I am line ' + ++this.itemIndex,
'I am line ' + ++this.itemIndex,
'I am line ' + ++this.itemIndex,
'I am line ' + ++this.itemIndex,
'I am line ' + ++this.itemIndex
]
this.items = this.items.concat(newPage)
} else {
// 如果没有新数据
this.$refs.scroll.forceUpdate()
}
}, 1000)
}
}
}
```
- 自定义下拉刷新和上拉加载动画
如果你不喜欢内置的下载刷新插槽和上拉加载,还可以用[作用域插槽](https://cn.vuejs.org/v2/guide/components.html#作用域插槽)做自定义动画。下面这个示例,就是用作用域插槽对下拉刷新做了自定义动画,而上拉加载则保留了缺省的内置动画。
```html
<vm-scroll
ref="scroll"
:options="options"
@pulling-down="onPullingDown"
@pulling-up="onPullingUp">
<template slot="pulldown" slot-scope="props">
<div
v-if="props.pullDownRefresh"
class="cube-pulldown-wrapper"
:style="props.pullDownStyle">
<div
v-if="props.beforePullDown"
class="before-trigger"
:style="{paddingTop: props.bubbleY + 'px'}">
<span :class="{rotate: props.bubbleY > 40}">↓</span>
</div>
<div class="after-trigger" v-else>
<div v-if="props.isPullingDown" class="loading">
<cube-loading></cube-loading>
</div>
<div v-else><span>Refresh success</span></div>
</div>
</div>
</template>
<vm-list>
<vm-item v-for="item in datas">{{item.text}}</vm-item>
</vm-list>
</vm-scroll>
```
通过作用域插槽提供的作用域参数,你可以根据各个状态的变化来控制动画流程。具体的作用域参数及其含义详见下面的插槽。
### Props 配置
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| - | - | - | - | - |
| data | 用于列表渲染的数据 | Array | - | [] |
| options | better-scroll 配置项 | Object | - | {<br> observeDOM: true,<br> click: true,<br> probeType: 1,<br> scrollbar: false,<br> pullDownRefresh: false,<br> pullUpLoad: false<br>} |
| direction | 滚动方向 | String | 'vertical', 'horizontal' | 'vertical' |
| listenScroll | 是否派发 scroll 事件 | Boolean | true/false | false |
| listenBeforeScroll | 是否派发 before-scroll-start 事件 | Boolean | true/false | false |
| refreshDelay | data属性的数据更新后,scroll 的刷新延时 | Number | - | 20 |
- `scrollbar` 子配置项
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| - | - | - | - | - |
| fade | 是否淡入淡出 | Boolean | true/false | false |
- `pullDownRefresh` 子配置项
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| - | - | - | - | - |
| threshold | 下拉刷新动作的下拉距离阈值 | Number | - | 90 |
| stop | 回弹停留的位置 | Number | - | 40 |
| txt | 刷新成功的文案 | String | - | 'Refresh success' |
- `pullUpLoad` 子配置项
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| - | - | - | - | - |
| threshold | 上拉刷新动作的上拉距离阈值 | Number | - | 0 |
| txt | 上拉加载的相关文案 | Object | - | { more: 'Load more', noMore: 'No more data' } |
### 插槽
| 名字 | 说明 | 作用域参数 |
| - | - | - |
| default | 基于`data`属性渲染的列表 | - |
| pulldown | 位于列表上方,会在下拉刷新时显示 | pullDownRefresh: 是否开启了下拉刷新功能 <br> pullDownStyle: 移入移出的样式 <br> beforePullDown: 是否正在做下拉操作 <br> isPullingDown: 是否正在拉取数据 <br> bubbleY: 当前下拉的距离 - 50|
| pullup | 位于列表下方,会在上拉加载时显示 | pullUpLoad: 是否开启了上拉加载功能 <br> isPullUpLoad: 是否正在加载数据 |
### 事件
| 事件名 | 说明 | 参数 |
| - | - | - |
| click | 点击列表项时触发 | item - 该列表项的数据 |
| scroll | 当 listenScroll 为 true 时,根据 probeType 的值决定派发时机 | Object {x, y} - 滚动的实时坐标 |
| before-scroll-start | 当 listenBeforeScroll 属性为 true 时,在滚动开始之前触发 | - |
| pulling-down | 当 pullDownRefresh 属性为 true 时,在下拉超过阈值时触发 | - |
| pulling-up | 当 pullUpLoad 属性为 true 时,在上拉超过阈值时触发 | - |
* @see https://www.npmjs.com/package/better-scroll
* @see https://github.com/ustbhuangyi/better-scroll
* @demo #/scroll
*/
export { default } from './scroll.vue'