提交 0377929c 编写于 作者: A Amy 提交者: doly mood

feat(index-list): pull up load + pull down refresh (#158)

* feat(index-list): pull up load

* test

* feat(index-list): pull down refresh

* test+docs: pull down refresh

* optimize: use forceUpdate replace watch deep
上级 c288db8c
...@@ -131,6 +131,98 @@ ...@@ -131,6 +131,98 @@
color: #ffcd32 color: #ffcd32
``` ```
- Pull Up Load
Beside, you could use `pullUpLoad` to enable pull-up-load, the detail config is same as the `options.pullUpLoad` of Scroll.
```html
<cube-index-list
ref="indexList"
:data="data"
:title="title"
:pullUpLoad="true"
@select="selectItem"
@title-click="clickTitle"
@pulling-up="onPullingUp">
</cube-index-list>
```
```javascript
export default {
data() {
return {
title: 'Current City: BEIJING',
data: cityData.slice(0, 4)
}
},
methods: {
selectItem(item) {
console.log(item.name)
},
clickTitle(title) {
console.log(title)
},
onPullingUp() {
// Mock async load.
setTimeout(() => {
const length = this.data.length
if (length < cityData.length) {
// Update data.
this.data.push(cityData[length])
}
// Call forceUpdate after finishing data load.
this.$refs.indexList.forceUpdate()
}, 1000)
}
}
}
```
- Pull Down Refresh
Beside, you could use `pullDownRefresh` to enable pull-down-refresh, the detail config is same as the `options.pullDownRefresh` of Scroll.
```html
<cube-index-list
ref="indexList"
:data="data"
:title="title"
:pullDownRefresh="pullDownRefresh"
@select="selectItem"
@title-click="clickTitle"
@pulling-down="onPullingDown">
</cube-index-list>
```
```javascript
export default {
data() {
return {
title: 'Current City: BEIJING',
data: cityData,
pullDownRefresh: {
stop: 55
}
}
},
methods: {
selectItem(item) {
console.log(item.name)
},
clickTitle(title) {
console.log(title)
},
onPullingDown() {
// Mock async load.
setTimeout(() => {
// Update data.
this.data[1].items.push(...cityData[1].items)
// Call forceUpdate after finishing data load.
this.$refs.indexList.forceUpdate()
}, 1000)
}
}
}
```
### Props configuration ### Props configuration
| Attribute | Description | Type | Default | | Attribute | Description | Type | Default |
...@@ -139,6 +231,8 @@ ...@@ -139,6 +231,8 @@
| data | data to be displayed | Array | [] | | data | data to be displayed | Array | [] |
| navbar | whether need navbar | Boolean | true | | navbar | whether need navbar | Boolean | true |
| speed | when click the navigator, the transition time of scrolling to the specific anchor (unit: ms). | number | 0 | | speed | when click the navigator, the transition time of scrolling to the specific anchor (unit: ms). | number | 0 |
| pullUpLoad<sup>1.8.0+</sup> | pull-up-load, the detail config is same as the `options.pullUpLoad` of Scroll | Boolean/Object | false |
| pullDownRefresh<sup>1.8.0+</sup> | pull-down-refresh, the detail config is same as the `options.pullDownRefresh` of Scroll | Boolean/Object | false |
- `data` sub configuration - `data` sub configuration
...@@ -157,3 +251,5 @@ Each item of `items` array must be an object that must contains the `name` attri ...@@ -157,3 +251,5 @@ Each item of `items` array must be an object that must contains the `name` attri
| - | - | - | | - | - | - |
| select | triggers when clicking one of the items in IndexList | data of the item | | select | triggers when clicking one of the items in IndexList | data of the item |
| title-click | triggers when clicking title(valid only if title has been configured) | the value of title | | title-click | triggers when clicking title(valid only if title has been configured) | the value of title |
| pulling-up<sup>1.8.0+</sup> | triggers when the distance of pulling up exceeds the threshold, if pullUpLoad is true | - |
| pulling-down<sup>1.8.0+</sup> | triggers when the distance of pulling down exceeds the threshold, if pullDownRefresh is true | - |
...@@ -68,13 +68,13 @@ ...@@ -68,13 +68,13 @@
}, },
methods: { methods: {
onPullingDown() { onPullingDown() {
// 模拟更新数据 // Mock async load.
setTimeout(() => { setTimeout(() => {
if (Math.random() > 0.5) { if (Math.random() > 0.5) {
// 如果有新数据 // If have new data, just update the data property.
this.items.unshift('I am new data: ' + +new Date()) this.items.unshift('I am new data: ' + +new Date())
} else { } else {
// 如果没有新数据 // If no new data, you need use the method forceUpdate to tell us the load is done.
this.$refs.scroll.forceUpdate() this.$refs.scroll.forceUpdate()
} }
}, 1000) }, 1000)
...@@ -113,10 +113,10 @@ ...@@ -113,10 +113,10 @@
}, },
methods: { methods: {
onPullingUp() { onPullingUp() {
// 更新数据 // Mock async load.
setTimeout(() => { setTimeout(() => {
if (Math.random() > 0.5) { if (Math.random() > 0.5) {
// 如果有新数据 // If have new data, just update the data property.
let newPage = [ let newPage = [
'I am line ' + ++this.itemIndex, 'I am line ' + ++this.itemIndex,
'I am line ' + ++this.itemIndex, 'I am line ' + ++this.itemIndex,
...@@ -127,7 +127,7 @@ ...@@ -127,7 +127,7 @@
this.items = this.items.concat(newPage) this.items = this.items.concat(newPage)
} else { } else {
// 如果没有新数据 // If no new data, you need use the method forceUpdate to tell us the load is done.
this.$refs.scroll.forceUpdate() this.$refs.scroll.forceUpdate()
} }
}, 1000) }, 1000)
......
...@@ -131,6 +131,98 @@ ...@@ -131,6 +131,98 @@
color: #ffcd32 color: #ffcd32
``` ```
- 上拉加载
可以通过 `pullUpLoad` 属性开启上拉加载功能,具体配置同 Scroll 组件的 `options.pullUpLoad`
```html
<cube-index-list
ref="indexList"
:data="data"
:title="title"
:pullUpLoad="true"
@select="selectItem"
@title-click="clickTitle"
@pulling-up="onPullingUp">
</cube-index-list>
```
```javascript
export default {
data() {
return {
title: 'Current City: BEIJING',
data: cityData.slice(0, 4)
}
},
methods: {
selectItem(item) {
console.log(item.name)
},
clickTitle(title) {
console.log(title)
},
onPullingUp() {
// Mock async load.
setTimeout(() => {
const length = this.data.length
if (length < cityData.length) {
// Update data.
this.data.push(cityData[length])
}
// Call forceUpdate after finishing data load.
this.$refs.indexList.forceUpdate()
}, 1000)
}
}
}
```
- 下拉刷新
可以通过 `pullDownRefresh` 属性开启下拉刷新功能,具体配置同 Scroll 组件的 `options.pullDownRefresh`
```html
<cube-index-list
ref="indexList"
:data="data"
:title="title"
:pullDownRefresh="pullDownRefresh"
@select="selectItem"
@title-click="clickTitle"
@pulling-down="onPullingDown">
</cube-index-list>
```
```javascript
export default {
data() {
return {
title: 'Current City: BEIJING',
data: cityData,
pullDownRefresh: {
stop: 55
}
}
},
methods: {
selectItem(item) {
console.log(item.name)
},
clickTitle(title) {
console.log(title)
},
onPullingDown() {
// Mock async load.
setTimeout(() => {
// Update data.
this.data[1].items.push(...cityData[1].items)
// Call forceUpdate after finishing data load.
this.$refs.indexList.forceUpdate()
}, 1000)
}
}
}
```
### Props 配置 ### Props 配置
| 参数 | 说明 | 类型 | 默认值 | | 参数 | 说明 | 类型 | 默认值 |
...@@ -139,6 +231,8 @@ ...@@ -139,6 +231,8 @@
| data | 需要展示的数据 | Array | [] | | data | 需要展示的数据 | Array | [] |
| navbar | 是否需要导航栏 | Boolean | true | | navbar | 是否需要导航栏 | Boolean | true |
| speed | 点击导航栏索引时,滚动到相应位置的动画时间(单位:ms) | number | 0 | | speed | 点击导航栏索引时,滚动到相应位置的动画时间(单位:ms) | number | 0 |
| pullUpLoad<sup>1.8.0+</sup> | 上拉加载,具体配置参考 scroll 组件的 `options.pullUpLoad` | Boolean/Object | false |
| pullDownRefresh<sup>1.8.0+</sup> | 下拉刷新,具体配置参考 scroll 组件的 `options.pullDownRefresh` | Boolean/Object | false |
- `data` 子配置项 - `data` 子配置项
...@@ -157,3 +251,5 @@ ...@@ -157,3 +251,5 @@
| - | - | - | | - | - | - |
| select | 点击 IndexList 的某一项后触发 | 该选项的数据 | | select | 点击 IndexList 的某一项后触发 | 该选项的数据 |
| title-click | 点击 title 后触发(title 必须设置后才有效) | title属性值 | | title-click | 点击 title 后触发(title 必须设置后才有效) | title属性值 |
| pulling-up<sup>1.8.0+</sup> | 当 pullUpLoad 属性为 true 时,在上拉超过阈值时触发 | - |
| pulling-down<sup>1.8.0+</sup> | 当 pullDownRefresh 属性为 true 时,在下拉超过阈值时触发 | - |
...@@ -83,13 +83,13 @@ ...@@ -83,13 +83,13 @@
}, },
methods: { methods: {
onPullingDown() { onPullingDown() {
// 模拟更新数据 // Mock async load.
setTimeout(() => { setTimeout(() => {
if (Math.random() > 0.5) { if (Math.random() > 0.5) {
// 如果有新数据 // If have new data, just update the data property.
this.items.unshift('I am new data: ' + +new Date()) this.items.unshift('I am new data: ' + +new Date())
} else { } else {
// 如果没有新数据 // If no new data, you need use the method forceUpdate to tell us the load is done.
this.$refs.scroll.forceUpdate() this.$refs.scroll.forceUpdate()
} }
}, 1000) }, 1000)
...@@ -130,10 +130,10 @@ ...@@ -130,10 +130,10 @@
}, },
methods: { methods: {
onPullingUp() { onPullingUp() {
// 更新数据 // Mock async load.
setTimeout(() => { setTimeout(() => {
if (Math.random() > 0.5) { if (Math.random() > 0.5) {
// 如果有新数据 // If have new data, just update the data property.
let newPage = [ let newPage = [
'I am line ' + ++this.itemIndex, 'I am line ' + ++this.itemIndex,
'I am line ' + ++this.itemIndex, 'I am line ' + ++this.itemIndex,
...@@ -144,7 +144,7 @@ ...@@ -144,7 +144,7 @@
this.items = this.items.concat(newPage) this.items = this.items.concat(newPage)
} else { } else {
// 如果没有新数据 // If no new data, you need use the method forceUpdate to tell us the load is done.
this.$refs.scroll.forceUpdate() this.$refs.scroll.forceUpdate()
} }
}, 1000) }, 1000)
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
<cube-button-group> <cube-button-group>
<cube-button @click="goTo('default')">Default</cube-button> <cube-button @click="goTo('default')">Default</cube-button>
<cube-button @click="goTo('custom')">Custom</cube-button> <cube-button @click="goTo('custom')">Custom</cube-button>
<cube-button @click="goTo('pull-up-load')">Pull Up Load</cube-button>
<cube-button @click="goTo('pull-down-refresh')">Pull Down Refresh</cube-button>
</cube-button-group> </cube-button-group>
<cube-view></cube-view> <cube-view></cube-view>
</div> </div>
......
<template>
<cube-page type="index-list" title="IndexList">
<div slot="content">
<div class="view-wrapper">
<div class="index-list-wrapper">
<cube-index-list
ref="indexList"
:data="data"
:title="title"
:pullDownRefresh="pullDownRefresh"
@select="selectItem"
@title-click="clickTitle"
@pulling-down="onPullingDown">
</cube-index-list>
</div>
</div>
</div>
</cube-page>
</template>
<script type="text/ecmascript-6">
import CubePage from '../../components/cube-page.vue'
import cityData from '../../data/index-list.json'
export default {
components: {
CubePage
},
data() {
return {
title: 'Current City: BEIJING',
data: cityData,
pullDownRefresh: {
stop: 55
}
}
},
methods: {
selectItem(item) {
console.log(item.name)
},
clickTitle(title) {
console.log(title)
},
onPullingDown() {
// Mock async load.
setTimeout(() => {
// Update data.
this.data[1].items.push(...cityData[1].items)
// Call forceUpdate after finishing data load.
this.$refs.indexList.forceUpdate()
}, 1000)
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
.view-wrapper
position: fixed
top: 54px
left: 0
bottom: 0
width: 100%
.index-list-wrapper
height: 98%
width: 94%
margin: 0 auto
overflow: hidden
</style>
<template>
<cube-page type="index-list" title="IndexList">
<div slot="content">
<div class="view-wrapper">
<div class="index-list-wrapper">
<cube-index-list
ref="indexList"
:data="data"
:title="title"
:pullUpLoad="true"
@select="selectItem"
@title-click="clickTitle"
@pulling-up="onPullingUp">
</cube-index-list>
</div>
</div>
</div>
</cube-page>
</template>
<script type="text/ecmascript-6">
import CubePage from '../../components/cube-page.vue'
import cityData from '../../data/index-list.json'
export default {
components: {
CubePage
},
data() {
return {
title: 'Current City: BEIJING',
data: cityData.slice(0, 4)
}
},
methods: {
selectItem(item) {
console.log(item.name)
},
clickTitle(title) {
console.log(title)
},
onPullingUp() {
// Mock async load.
setTimeout(() => {
const length = this.data.length
if (length < cityData.length) {
// Update data.
this.data.push(cityData[length])
}
// Call forceUpdate after finishing data load.
this.$refs.indexList.forceUpdate()
}, 1000)
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
.view-wrapper
position: fixed
top: 54px
left: 0
bottom: 0
width: 100%
.index-list-wrapper
height: 98%
width: 94%
margin: 0 auto
overflow: hidden
</style>
...@@ -233,22 +233,22 @@ ...@@ -233,22 +233,22 @@
}, },
methods: { methods: {
onPullingDown() { onPullingDown() {
// 模拟更新数据 // Mock async load.
setTimeout(() => { setTimeout(() => {
if (Math.random() > 0.5) { if (Math.random() > 0.5) {
// 如果有新数据 // If have new data, just update the data property.
this.items.unshift(this.customList ? _foods[1] : `I am new data: ${+new Date()}`) this.items.unshift(this.customList ? _foods[1] : `I am new data: ${+new Date()}`)
} else { } else {
// 如果没有新数据 // If no new data, you need use the method forceUpdate to tell us the load is done.
this.$refs.scroll.forceUpdate() this.$refs.scroll.forceUpdate()
} }
}, 1000) }, 1000)
}, },
onPullingUp() { onPullingUp() {
// 更新数据 // Mock async load.
setTimeout(() => { setTimeout(() => {
if (Math.random() > 0.5) { if (Math.random() > 0.5) {
// 如果有新数据 // If have new data, just update the data property.
let newPage = this.customList ? _foods.slice(0, 5) : [ let newPage = this.customList ? _foods.slice(0, 5) : [
'I am line ' + ++this.itemIndex, 'I am line ' + ++this.itemIndex,
'I am line ' + ++this.itemIndex, 'I am line ' + ++this.itemIndex,
...@@ -259,7 +259,7 @@ ...@@ -259,7 +259,7 @@
this.items = this.items.concat(newPage) this.items = this.items.concat(newPage)
} else { } else {
// 如果没有新数据 // If no new data, you need use the method forceUpdate to tell us the load is done.
this.$refs.scroll.forceUpdate() this.$refs.scroll.forceUpdate()
} }
}, 1000) }, 1000)
......
...@@ -22,9 +22,11 @@ import Select from '../pages/select.vue' ...@@ -22,9 +22,11 @@ import Select from '../pages/select.vue'
import Dialog from '../pages/dialog.vue' import Dialog from '../pages/dialog.vue'
import ActionSheet from '../pages/action-sheet.vue' import ActionSheet from '../pages/action-sheet.vue'
import Scroll from '../pages/scroll.vue' import Scroll from '../pages/scroll.vue'
import IndexList from '../pages/index-list/index-list.vue' import IndexList from '../pages/index-list/index.vue'
import IndexListDefault from '../pages/index-list/default.vue' import IndexListDefault from '../pages/index-list/default.vue'
import IndexListCustom from '../pages/index-list/custom.vue' import IndexListCustom from '../pages/index-list/custom.vue'
import IndexListPullUpLoad from '../pages/index-list/pull-up-load.vue'
import IndexListPullDownRefresh from '../pages/index-list/pull-down-refresh.vue'
import Upload from '../pages/upload.vue' import Upload from '../pages/upload.vue'
import Validator from '../pages/validator.vue' import Validator from '../pages/validator.vue'
import Swipe from '../pages/swipe/index.vue' import Swipe from '../pages/swipe/index.vue'
...@@ -147,6 +149,14 @@ const routes = [ ...@@ -147,6 +149,14 @@ const routes = [
{ {
path: 'custom', path: 'custom',
component: IndexListCustom component: IndexListCustom
},
{
path: 'pull-up-load',
component: IndexListPullUpLoad
},
{
path: 'pull-down-refresh',
component: IndexListPullDownRefresh
} }
] ]
}, },
......
<template> <template>
<div class="cube-index-list"> <div class="cube-index-list">
<cube-scroll <cube-scroll
ref="indexList" ref="scroll"
:listen-scroll="listenScroll" :listen-scroll="listenScroll"
:options="options" :options="options"
:data="data" :data="data"
@scroll="scroll"> @scroll="scroll"
@pulling-down="onPullingDown"
@pulling-up="onPullingUp">
<div class="cube-index-list-content" ref="content"> <div class="cube-index-list-content" ref="content">
<h1 class="cube-index-list-title" v-if="title" ref="title" @click="titleClick"> <h1 class="cube-index-list-title" v-if="title" ref="title" @click="titleClick">
{{ title }} {{ title }}
...@@ -52,6 +54,8 @@ ...@@ -52,6 +54,8 @@
const COMPONENT_NAME = 'cube-index-list' const COMPONENT_NAME = 'cube-index-list'
const EVENT_SELECT = 'select' const EVENT_SELECT = 'select'
const EVENT_TITLE_CLICK = 'title-click' const EVENT_TITLE_CLICK = 'title-click'
const EVENT_PULLING_UP = 'pulling-up'
const EVENT_PULLING_DOWN = 'pulling-down'
const ANCHOR_HEIGHT = inBrowser ? window.innerHeight <= 480 ? 17 : 18 : 18 const ANCHOR_HEIGHT = inBrowser ? window.innerHeight <= 480 ? 17 : 18 : 18
const transformStyleKey = prefixStyle('transform') const transformStyleKey = prefixStyle('transform')
...@@ -76,6 +80,14 @@ ...@@ -76,6 +80,14 @@
navbar: { navbar: {
type: Boolean, type: Boolean,
default: true default: true
},
pullDownRefresh: {
type: [Boolean, Object],
default: false
},
pullUpLoad: {
type: [Boolean, Object],
default: false
} }
}, },
data() { data() {
...@@ -83,25 +95,9 @@ ...@@ -83,25 +95,9 @@
currentIndex: 0, currentIndex: 0,
scrollY: -1, scrollY: -1,
diff: -1, diff: -1,
options: {
probeType: 3
},
titleHeight: null titleHeight: null
} }
}, },
created() {
this.listenScroll = true
this.groupList = []
this.listHeight = []
this.touch = {}
this.subTitleHeight = 0
},
mounted() {
this.$nextTick(() => {
this.titleHeight = this.title && this.$refs.title ? getRect(this.$refs.title).height : 0
this._calculateHeight()
})
},
computed: { computed: {
fixedTitle() { fixedTitle() {
if (this.titleHeight === null || this.scrollY > -this.titleHeight) { if (this.titleHeight === null || this.scrollY > -this.titleHeight) {
...@@ -113,12 +109,32 @@ ...@@ -113,12 +109,32 @@
return this.data.map((group) => { return this.data.map((group) => {
return group ? group.shortcut || group.name.substr(0, 1) : '' return group ? group.shortcut || group.name.substr(0, 1) : ''
}) })
},
options() {
return {
probeType: 3,
pullDownRefresh: this.pullDownRefresh,
pullUpLoad: this.pullUpLoad
}
} }
}, },
created() {
this.listenScroll = true
this.groupList = []
this.listHeight = []
this.touch = {}
this.subTitleHeight = 0
},
mounted() {
this.$nextTick(() => {
this.titleHeight = this.title && this.$refs.title ? getRect(this.$refs.title).height : 0
this._calculateHeight()
})
},
methods: { methods: {
/* TODO: remove refresh next minor version */ /* TODO: remove refresh next minor version */
refresh() { refresh() {
this.$refs.indexList.refresh() this.$refs.scroll.refresh()
}, },
selectItem(item) { selectItem(item) {
this.$emit(EVENT_SELECT, item) this.$emit(EVENT_SELECT, item)
...@@ -129,6 +145,9 @@ ...@@ -129,6 +145,9 @@
titleClick() { titleClick() {
this.$emit(EVENT_TITLE_CLICK, this.title) this.$emit(EVENT_TITLE_CLICK, this.title)
}, },
forceUpdate() {
this.$refs.scroll.forceUpdate()
},
onShortcutTouchStart(e) { onShortcutTouchStart(e) {
const target = getMatchedTarget(e, 'cube-index-list-nav-item') const target = getMatchedTarget(e, 'cube-index-list-nav-item')
if (!target) return if (!target) return
...@@ -147,6 +166,12 @@ ...@@ -147,6 +166,12 @@
this._scrollTo(anchorIndex) this._scrollTo(anchorIndex)
}, },
onPullingUp() {
this.$emit(EVENT_PULLING_UP)
},
onPullingDown() {
this.$emit(EVENT_PULLING_DOWN)
},
_calculateHeight() { _calculateHeight() {
this.groupList = this.$el.getElementsByClassName('cube-index-list-group') this.groupList = this.$el.getElementsByClassName('cube-index-list-group')
const subTitleEl = this.$el.getElementsByClassName('cube-index-list-anchor')[0] const subTitleEl = this.$el.getElementsByClassName('cube-index-list-anchor')[0]
...@@ -171,8 +196,8 @@ ...@@ -171,8 +196,8 @@
} else if (index > this.listHeight.length - 2) { } else if (index > this.listHeight.length - 2) {
index = this.listHeight.length - 2 index = this.listHeight.length - 2
} }
this.$refs.indexList.scrollToElement(this.groupList[index], this.speed) this.$refs.scroll.scrollToElement(this.groupList[index], this.speed)
this.scrollY = this.$refs.indexList.scroll.y this.scrollY = this.$refs.scroll.scroll.y
} }
}, },
watch: { watch: {
......
...@@ -2,8 +2,8 @@ import Vue from 'vue2' ...@@ -2,8 +2,8 @@ import Vue from 'vue2'
import IndexList from '@/modules/index-list' import IndexList from '@/modules/index-list'
import instantiateComponent from '@/common/helpers/instantiate-component' import instantiateComponent from '@/common/helpers/instantiate-component'
import { dispatchSwipe, dispatchTap } from '../utils/event' import { dispatchSwipe, dispatchTap } from '../utils/event'
import cityData from '../fake/index-list.json' import cityData from '../fake/index-list.json'
// 处理数据 // 处理数据
let data = [] let data = []
cityData.forEach((cityGroup) => { cityData.forEach((cityGroup) => {
...@@ -18,7 +18,9 @@ cityData.forEach((cityGroup) => { ...@@ -18,7 +18,9 @@ cityData.forEach((cityGroup) => {
}) })
data.push(group) data.push(group)
}) })
const title = '当前城市:北京市' const title = '当前城市:北京市'
describe('IndexList', () => { describe('IndexList', () => {
describe('IndexList.vue', () => { describe('IndexList.vue', () => {
let vm let vm
...@@ -69,67 +71,147 @@ describe('IndexList', () => { ...@@ -69,67 +71,147 @@ describe('IndexList', () => {
'title-click': titleClickHandler 'title-click': titleClickHandler
}) })
vm.$nextTick(() => { vm.$nextTick(() => {
// select
const items = vm.$el.querySelectorAll('.cube-index-list-item') const items = vm.$el.querySelectorAll('.cube-index-list-item')
dispatchTap(items[2]) dispatchTap(items[2])
expect(selectHandler).to.be.calledOnce expect(selectHandler).to.be.calledOnce
// title-click
dispatchTap(vm.$el.querySelector('.cube-index-list-title')) dispatchTap(vm.$el.querySelector('.cube-index-list-title'))
expect(titleClickHandler).to.be.calledOnce expect(titleClickHandler).to.be.calledOnce
done() done()
}) })
}) })
it('should fixed title', function () { it('should trigger pulling-up', function (done) {
this.timeout(10000) this.timeout(10000)
vm = createIndexList()
return new Promise((resolve) => { const pullingUpHandler = sinon.spy()
vm = createIndexList({
title,
data: data.slice(0, 1),
pullUpLoad: true
}, {
'pulling-up': pullingUpHandler
})
const scrollWrapper = vm.$el.querySelector('.cube-scroll-wrapper')
scrollWrapper.style.height = '300px'
vm.refresh()
setTimeout(() => {
const scrollContent = vm.$el.querySelector('.cube-scroll-content li:first-child')
dispatchSwipe(scrollContent, [
{
pageX: 10,
pageY: 300
},
{
pageX: 10,
pageY: 10
}
], 100)
setTimeout(() => { setTimeout(() => {
vm.$parent.updateRenderData({ expect(pullingUpHandler).to.be.calledOnce
props: {
title: title, vm.forceUpdate()
data: data, done()
speed: 0 }, 400)
}, }, 150)
on: {} })
})
vm.$parent.$forceUpdate() it('should trigger pulling-down', function (done) {
}, 30) this.timeout(10000)
const pullingDownHandler = sinon.spy()
vm = createIndexList({
title,
data: data.slice(0, 1),
pullDownRefresh: true
}, {
'pulling-down': pullingDownHandler
})
const scrollWrapper = vm.$el.querySelector('.cube-scroll-wrapper')
scrollWrapper.style.height = '300px'
vm.refresh()
setTimeout(() => {
const scrollContent = vm.$el.querySelector('.cube-scroll-content li:first-child')
dispatchSwipe(scrollContent, [
{
pageX: 10,
pageY: 10
},
{
pageX: 10,
pageY: 300
}
], 100)
setTimeout(() => {
expect(pullingDownHandler).to.be.calledOnce
done()
}, 400)
}, 150)
})
it('should fixed title', function (done) {
this.timeout(10000)
vm = createIndexList()
setTimeout(() => {
vm.$parent.updateRenderData({
props: {
title: title,
data: data,
speed: 0
},
on: {}
})
vm.$parent.$forceUpdate()
}, 30)
setTimeout(() => {
const zEle = vm.$el.querySelector('.cube-index-list-nav li[data-index="2"]')
// nav li
dispatchSwipe(zEle, {
pageX: 342,
pageY: 327
}, 0)
setTimeout(() => { setTimeout(() => {
const zEle = vm.$el.querySelector('.cube-index-list-nav li[data-index="2"]') // item active class
// nav li dispatchSwipe(vm.$el.querySelector('.cube-index-list-item'), {
dispatchSwipe(zEle, {
pageX: 342, pageX: 342,
pageY: 327 pageY: 327
}, 0) }, 0)
setTimeout(() => { // scroll
// item active class const fixedEle = vm.$el.querySelector('.cube-index-list-fixed')
dispatchSwipe(vm.$el.querySelector('.cube-index-list-item'), { expect(fixedEle.textContent.trim())
pageX: 342, .to.equal('B')
pageY: 327 const el = vm.$el.querySelector('.cube-index-list-content')
}, 0) vm.$refs.scroll.scroll.on('scrollEnd', () => {
// scroll
const fixedEle = vm.$el.querySelector('.cube-index-list-fixed')
expect(fixedEle.textContent.trim()) expect(fixedEle.textContent.trim())
.to.equal('B') .to.equal('C')
const el = vm.$el.querySelector('.cube-index-list-content') done()
vm.$refs.indexList.scroll.on('scrollEnd', () => { })
expect(fixedEle.textContent.trim()) dispatchSwipe(el, [
.to.equal('C') {
resolve() pageX: 300,
}) pageY: 400
dispatchSwipe(el, [ },
{ {
pageX: 300, pageX: 300,
pageY: 400 pageY: 380
}, }
{ ], 100)
pageX: 300, }, 20)
pageY: 380 }, 150)
}
], 100)
}, 20)
}, 150)
})
}) })
it('should not have navbar when navbar prop is false', () => { it('should not have navbar when navbar prop is false', () => {
...@@ -155,16 +237,30 @@ describe('IndexList', () => { ...@@ -155,16 +237,30 @@ describe('IndexList', () => {
}) })
}) })
it('should handle condition of unexpected param', function () { it('should handle condition of unexpected param', function (done) {
this.timeout(10000) this.timeout(10000)
vm = createIndexList({ vm = createIndexList({
title, title,
data, data,
speed: 0 speed: 0
}) })
return new Promise((resolve) => { setTimeout(() => {
const bEl = vm.$el.querySelector('.cube-index-list-nav li[data-index="2"]')
dispatchSwipe(bEl, [
{
pageX: 300,
pageY: 400
},
{
pageX: 300,
pageY: 50
}
], 100)
setTimeout(() => { setTimeout(() => {
const bEl = vm.$el.querySelector('.cube-index-list-nav li[data-index="2"]') const fixedEl = vm.$el.querySelector('.cube-index-list-fixed')
expect(fixedEl.textContent.trim())
.to.equal('★热门城市')
dispatchSwipe(bEl, [ dispatchSwipe(bEl, [
{ {
pageX: 300, pageX: 300,
...@@ -172,37 +268,21 @@ describe('IndexList', () => { ...@@ -172,37 +268,21 @@ describe('IndexList', () => {
}, },
{ {
pageX: 300, pageX: 300,
pageY: 50 pageY: 1000
} }
], 100) ], 100)
setTimeout(() => { setTimeout(() => {
const fixedEl = vm.$el.querySelector('.cube-index-list-fixed')
expect(fixedEl.textContent.trim()) expect(fixedEl.textContent.trim())
.to.equal('★热门城市') .to.equal('Z')
done()
dispatchSwipe(bEl, [
{
pageX: 300,
pageY: 400
},
{
pageX: 300,
pageY: 1000
}
], 100)
setTimeout(() => {
expect(fixedEl.textContent.trim())
.to.equal('Z')
resolve()
}, 150)
}, 150) }, 150)
}, 150)
vm.scrollY = 0 vm.scrollY = 0
setTimeout(() => { setTimeout(() => {
vm.scrollY = -10000 vm.scrollY = -10000
}, 0) }, 0)
}, 30) }, 30)
})
}) })
function createIndexList(props = {}, events = {}) { function createIndexList(props = {}, events = {}) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册