# wheel
# 介绍
wheel 插件,是实现类似 IOS Picker 组件的基石。
# 安装
npm install @better-scroll/wheel --save
// or
yarn add @better-scroll/wheel
# 使用
首先引入 wheel 插件,并通过静态方法 BScroll.use()
注册插件。
import BScroll from '@better-scroll/core'
import Wheel from '@better-scroll/wheel'
BScroll.use(Wheel)
接着在 options
传入正确的配置
let bs = new BScroll('.bs-wrapper', {
wheel: true // wheel options 为 true
})
TIP
wheel options 是 true 或者对象,否则插件功能失效,具体请参考 wheel options。
危险
BetterScroll 结合 wheel 插件只是实现 Picker 效果的 JS 逻辑部分,还有 DOM 模版是需要用户去实现,所幸,对于大多数的 Picker 场景,我们给出了相对应的示例。
基本使用
<template> <div class="container"> <ul class="example-list"> <li class="example-item" @click="show"> <span class="open">{{selectedText}}</span> </li> </ul> <transition name="picker-fade"> <div class="picker" v-show="state===1" @touchmove.prevent @click="_cancel"> <transition name="picker-move"> <div class="picker-panel" v-show="state===1" @click.stop> <div class="picker-choose border-bottom-1px"> <span class="cancel" @click="_cancel">Cancel</span> <span class="confirm" @click="_confirm">Confirm</span> <h1 class="picker-title">Title</h1> </div> <div class="picker-content"> <div class="mask-top border-bottom-1px"></div> <div class="mask-bottom border-top-1px"></div> <div class="wheel-wrapper" ref="wheelWrapper"> <div class="wheel"> <ul class="wheel-scroll"> <li v-for="(item, index) in pickerData" :key="index" :class="{'wheel-disabled-item':item.disabled}" class="wheel-item">{{item.text}}</li> </ul> </div> </div> </div> <div class="picker-footer"></div> </div> </transition> </div> </transition> </div> </template>
<script type="text/ecmascript-6"> import BScroll from '@better-scroll/core' import Wheel from '@better-scroll/wheel' BScroll.use(Wheel) const STATE_HIDE = 0 const STATE_SHOW = 1 const COMPONENT_NAME = 'picker' const EVENT_SELECT = 'select' const EVENT_CANCEL = 'cancel' const EVENT_CHANGE = 'change' const WHEEL_INDEX_CHANGED = 'wheelIndexChanged' const DATA = [ { text: 'Venomancer', value: 1, disabled: 'wheel-disabled-item' }, { text: 'Nerubian Weaver', value: 2 }, { text: 'Spectre', value: 3 }, { text: 'Juggernaut', value: 4 }, { text: 'Karl', value: 5 }, { text: 'Zeus', value: 6 }, { text: 'Witch Doctor', value: 7 }, { text: 'Lich', value: 8 }, { text: 'Oracle', value: 9 }, { text: 'Earthshaker', value: 10 } ] export default { name: COMPONENT_NAME, data() { return { state: STATE_HIDE, selectedIndex: 2, selectedText: 'open', pickerData: DATA } }, methods: { _confirm() { /* * if bs is scrolling, force it stop at the nearest wheel-item * or you can use 'restorePosition' method as the below */ this.wheel.stop() /* * if bs is scrolling, restore it to the start position * it is same with iOS picker and web Select element implementation * supported at v2.1.0 */ // this.wheel.restorePosition() this.hide() const currentSelectedIndex = this.selectedIndex = this.wheel.getSelectedIndex() this.selectedText = `${this.pickerData[currentSelectedIndex].text}-${currentSelectedIndex}` this.$emit(EVENT_SELECT, currentSelectedIndex) }, _cancel() { /* * if bs is scrolling, restore it to the start position * it is same with iOS picker and web Select element implementation * supported at v2.1.0 */ this.wheel.restorePosition() this.hide() this.$emit(EVENT_CANCEL) }, show() { if (this.state === STATE_SHOW) { return } this.state = STATE_SHOW if (!this.wheel) { // waiting for DOM rendered this.$nextTick(() => { const wrapper = this.$refs.wheelWrapper.children[0] this._createWheel(wrapper) }) } }, hide() { this.state = STATE_HIDE }, _createWheel(wheelWrapper) { if (!this.wheel) { this.wheel = new BScroll(wheelWrapper, { wheel: { selectedIndex: this.selectedIndex, wheelWrapperClass: 'wheel-scroll', wheelItemClass: 'wheel-item', wheelDisabledItemClass: 'wheel-disabled-item' }, useTransition: false, probeType: 3 }) // < v2.1.0 this.wheel.on('scrollEnd', () => { this.$emit(EVENT_CHANGE, this.wheel.getSelectedIndex()) }) // v2.1.0, only when selectedIndex changed this.wheel.on(WHEEL_INDEX_CHANGED, (index) => { console.log(index) }) } else { this.wheel.refresh() } return this.wheel } } } </script>
<style scoped lang="stylus" rel="stylesheet/stylus"> /* reset */ ul list-style none padding 0 .border-bottom-1px, .border-top-1px position: relative &:before, &:after content: "" display: block position: absolute transform-origin: 0 0 .border-bottom-1px &:after border-bottom: 1px solid #ebebeb left: 0 bottom: 0 width: 100% transform-origin: 0 bottom .border-top-1px &:before border-top: 1px solid #ebebeb left: 0 top: 0 width: 100% transform-origin: 0 top @media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) .border-top-1px &:before width: 200% transform: scale(.5) translateZ(0) .border-bottom-1px &:after width: 200% transform: scale(.5) translateZ(0) @media (-webkit-min-device-pixel-ratio: 3), (min-device-pixel-ratio: 3) .border-top-1px &:before width: 300% transform: scale(.333) translateZ(0) .border-bottom-1px &:after width: 300% transform: scale(.333) translateZ(0) .example-list display: flex justify-content: space-between flex-wrap: wrap margin: 2rem .example-item background-color white padding: 0.8rem border: 1px solid rgba(0, 0, 0, .1) box-shadow: 0 1px 2px 0 rgba(0,0,0,0.1) text-align: center margin-bottom: 1rem flex: 1 &.placeholder visibility: hidden height: 0 margin: 0 padding: 0 .picker position: fixed left: 0 top: 0 z-index: 100 width: 100% height: 100% overflow: hidden text-align: center font-size: 14px background-color: rgba(37, 38, 45, .4) &.picker-fade-enter, &.picker-fade-leave-active opacity: 0 &.picker-fade-enter-active, &.picker-fade-leave-active transition: all .3s ease-in-out .picker-panel position: absolute z-index: 600 bottom: 0 width: 100% height: 273px background: white &.picker-move-enter, &.picker-move-leave-active transform: translate3d(0, 273px, 0) &.picker-move-enter-active, &.picker-move-leave-active transition: all .3s ease-in-out .picker-choose position: relative height: 60px color: #999 .picker-title margin: 0 line-height: 60px font-weight: normal text-align: center font-size: 18px color: #333 .confirm, .cancel position: absolute top: 6px padding: 16px font-size: 14px .confirm right: 0 color: #007bff &:active color: #5aaaff .cancel left: 0 &:active color: #c2c2c2 .picker-content position: relative top: 20px .mask-top, .mask-bottom z-index: 10 width: 100% height: 68px pointer-events: none transform: translateZ(0) .mask-top position: absolute top: 0 background: linear-gradient(to top, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.8)) .mask-bottom position: absolute bottom: 1px background: linear-gradient(to bottom, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.8)) .wheel-wrapper display: flex padding: 0 16px .wheel flex: 1 width: 1% height: 173px overflow: hidden font-size: 18px .wheel-scroll padding: 0 margin-top: 68px line-height: 36px list-style: none .wheel-item list-style: none height: 36px overflow: hidden white-space: nowrap color: #333 &.wheel-disabled-item opacity: .2; .picker-footer height: 20px </style>
单列 Picker 是一个比较常见的效果。你可以通过
selectedIndex
来配置初始化时选中对应索引的 item,wheelDisabledItemClass
配置想要禁用的 item 项来模拟 Web Select 标签 disable 的效果。多项选择器
<template> <div class="container"> <ul class="example-list"> <li class="example-item" @click="show"> <span class="open">{{selectedText}}</span> </li> </ul> <transition name="picker-fade"> <div class="picker" v-show="state===1" @touchmove.prevent @click="_cancel"> <transition name="picker-move"> <div class="picker-panel" v-show="state===1" @click.stop> <div class="picker-choose border-bottom-1px"> <span class="cancel" @click="_cancel">Cancel</span> <span class="confirm" @click="_confirm">Confirm</span> <h1 class="picker-title">Title</h1> </div> <div class="picker-content"> <div class="mask-top border-bottom-1px"></div> <div class="mask-bottom border-top-1px"></div> <div class="wheel-wrapper" ref="wheelWrapper"> <div class="wheel" v-for="(data, index) in pickerData" :key="index"> <ul class="wheel-scroll"> <li v-for="item in data" :key="item.value" class="wheel-item">{{item.text}}</li> </ul> </div> </div> </div> <div class="picker-footer"></div> </div> </transition> </div> </transition> </div> </template>
<script type="text/ecmascript-6"> import BScroll from '@better-scroll/core' import Wheel from '@better-scroll/wheel' BScroll.use(Wheel) const STATE_HIDE = 0 const STATE_SHOW = 1 const COMPONENT_NAME = 'picker' const EVENT_SELECT = 'select' const EVENT_CANCEL = 'cancel' const EVENT_CHANGE = 'change' const DATA1 = [ { text: 'Venomancer', value: 1 }, { text: 'Nerubian Weaver', value: 2 }, { text: 'Spectre', value: 3 }, { text: 'Juggernaut', value: 4 }, { text: 'Karl', value: 5 }, { text: 'Zeus', value: 6 }, { text: 'Witch Doctor', value: 7 }, { text: 'Lich', value: 8 }, { text: 'Oracle', value: 9 }, { text: 'Earthshaker', value: 10 } ] const DATA2 = [ { text: 'Durable', value: 'a' }, { text: 'Pusher', value: 'b' }, { text: 'Carry', value: 'c' }, { text: 'Nuker', value: 'd' }, { text: 'Support', value: 'e' }, { text: 'Jungle', value: 'f' }, { text: 'Escape', value: 'g' }, { text: 'Initiator', value: 'h' } ] export default { name: COMPONENT_NAME, data() { return { state: STATE_HIDE, selectedIndexPair: [0, 0], selectedText: 'open', pickerData: [DATA1, DATA2] } }, methods: { _confirm() { this.wheels.forEach(wheel => { /* * if bs is scrolling, force it stop at the nearest wheel-item * or you can use 'restorePosition' method as the below */ // wheel.stop() /* * if bs is scrolling, restore it to the start position * it is same with iOS picker and web Select element implementation * supported at v2.1.0 */ wheel.restorePosition() }) this.hide() const currentSelectedIndexPair = this.selectedIndexPair = this.wheels.map(wheel => { return wheel.getSelectedIndex() }) this.selectedText = this.pickerData.map((data, i) => { const index = currentSelectedIndexPair[i] return `${data[index].text}-${index}` }).join('__') this.$emit(EVENT_SELECT, currentSelectedIndexPair) }, _cancel() { /* * if bs is scrolling, restore it to the start position * it is same with iOS picker and web Select element implementation * supported at v2.1.0 */ this.wheels.forEach(wheel => { wheel.restorePosition() }) this.hide() this.$emit(EVENT_CANCEL) }, show() { if (this.state === STATE_SHOW) { return } this.state = STATE_SHOW if (!this.wheels) { // waiting for DOM rendered this.$nextTick(() => { this.wheels = [] let wheelWrapper = this.$refs.wheelWrapper for (let i = 0; i < this.pickerData.length; i++) { this._createWheel(wheelWrapper, i) } }) } }, hide() { this.state = STATE_HIDE }, _createWheel(wheelWrapper, i) { if (!this.wheels[i]) { this.wheels[i] = new BScroll(wheelWrapper.children[i], { wheel: { selectedIndex: this.selectedIndexPair[i], wheelWrapperClass: 'wheel-scroll', wheelItemClass: 'wheel-item' }, probeType: 3 }) this.wheels[i].on('scrollEnd', () => { this.$emit(EVENT_CHANGE, i, this.wheels[i].getSelectedIndex()) }) } else { this.wheels[i].refresh() } return this.wheels[i] } } } </script>
<style scoped lang="stylus" rel="stylesheet/stylus"> /* reset */ ul list-style none padding 0 .border-bottom-1px, .border-top-1px position: relative &:before, &:after content: "" display: block position: absolute transform-origin: 0 0 .border-bottom-1px &:after border-bottom: 1px solid #ebebeb left: 0 bottom: 0 width: 100% transform-origin: 0 bottom .border-top-1px &:before border-top: 1px solid #ebebeb left: 0 top: 0 width: 100% transform-origin: 0 top @media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) .border-top-1px &:before width: 200% transform: scale(.5) translateZ(0) .border-bottom-1px &:after width: 200% transform: scale(.5) translateZ(0) @media (-webkit-min-device-pixel-ratio: 3), (min-device-pixel-ratio: 3) .border-top-1px &:before width: 300% transform: scale(.333) translateZ(0) .border-bottom-1px &:after width: 300% transform: scale(.333) translateZ(0) .example-list display: flex justify-content: space-between flex-wrap: wrap margin: 2rem .example-item background-color white padding: 0.8rem border: 1px solid rgba(0, 0, 0, .1) box-shadow: 0 1px 2px 0 rgba(0,0,0,0.1) text-align: center margin-bottom: 1rem flex: 1 &.placeholder visibility: hidden height: 0 margin: 0 padding: 0 .picker position: fixed left: 0 top: 0 z-index: 100 width: 100% height: 100% overflow: hidden text-align: center font-size: 14px background-color: rgba(37, 38, 45, .4) &.picker-fade-enter, &.picker-fade-leave-active opacity: 0 &.picker-fade-enter-active, &.picker-fade-leave-active transition: all .3s ease-in-out .picker-panel position: absolute z-index: 600 bottom: 0 width: 100% height: 273px background: white &.picker-move-enter, &.picker-move-leave-active transform: translate3d(0, 273px, 0) &.picker-move-enter-active, &.picker-move-leave-active transition: all .3s ease-in-out .picker-choose position: relative height: 60px color: #999 .picker-title margin: 0 line-height: 60px font-weight: normal text-align: center font-size: 18px color: #333 .confirm, .cancel position: absolute top: 6px padding: 16px font-size: 14px .confirm right: 0 color: #007bff &:active color: #5aaaff .cancel left: 0 &:active color: #c2c2c2 .picker-content position: relative top: 20px .mask-top, .mask-bottom z-index: 10 width: 100% height: 68px pointer-events: none transform: translateZ(0) .mask-top position: absolute top: 0 background: linear-gradient(to top, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.8)) .mask-bottom position: absolute bottom: 1px background: linear-gradient(to bottom, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.8)) .wheel-wrapper display: flex padding: 0 16px .wheel flex: 1 width: 1% height: 173px overflow: hidden font-size: 18px .wheel-scroll padding: 0 margin-top: 68px line-height: 36px list-style: none .wheel-item list-style: none height: 36px overflow: hidden white-space: nowrap color: #333 &.wheel-disabled-item opacity: .2; .picker-footer height: 20px </style>
示例是一个两列的选择器,JS 逻辑部分与单列选择器没有多大的区别,你会发现这个两列选择器之间是没有任何关联,因为它们是两个不同的 BetterScroll 实例。如果你想要实现省市联动的效果,那么得加上一部分代码,让这两个 BetterScroll 实例能够关联起来。请看下一个例子:
城市联动选择器
<template> <div class="container"> <ul class="example-list"> <li class="example-item" @click="show"> <span class="open">{{selectedText}}</span> </li> </ul> <transition name="picker-fade"> <div class="picker" v-show="state===1" @touchmove.prevent @click="_cancel"> <transition name="picker-move"> <div class="picker-panel" v-show="state===1" @click.stop> <div class="picker-choose border-bottom-1px"> <span class="cancel" @click="_cancel">Cancel</span> <span class="confirm" @click="_confirm">Confirm</span> <h1 class="picker-title">Title</h1> </div> <div class="picker-content"> <div class="mask-top border-bottom-1px"></div> <div class="mask-bottom border-top-1px"></div> <div class="wheel-wrapper" ref="wheelWrapper"> <div class="wheel" v-for="(data, index) in pickerData" :key="index"> <ul class="wheel-scroll"> <li v-for="item in data" :key="item.value" :class="{'wheel-disabled-item':item.disabled}" class="wheel-item">{{item.text}}</li> </ul> </div> </div> </div> <div class="picker-footer"></div> </div> </transition> </div> </transition> </div> </template>
<script type="text/ecmascript-6"> import BScroll from '@better-scroll/core' import Wheel from '@better-scroll/wheel' BScroll.use(Wheel) const STATE_HIDE = 0 const STATE_SHOW = 1 const COMPONENT_NAME = 'picker' const EVENT_SELECT = 'select' const EVENT_CANCEL = 'cancel' const EVENT_CHANGE = 'change' const DATA = [ { text: '北京市', value: '110000', children: [ { text: "北京市", value: '110100' } ] }, { text: '天津市', value: '120000', children: [ { text: "天津市", value: '120000' } ] }, { text: '河北省', value: '130000', children: [ { text: '石家庄市', value: '130100' }, { text: '唐山市', value: '130200' }, { text: '秦皇岛市', value: '130300' }, { text: '邯郸市', value: '130400' }, { text: '邢台市', value: '130500' }, { text: '保定市', value: '130600' }, { text: '张家口市', value: '130700' }, { text: '承德市', value: '130800' } ] }, { text: '山西省', value: '140000', children: [ { text: '太原市', value: '140100' }, { text: '大同市', value: '140200' }, { text: '阳泉市', value: '140300' }, { text: '长治市', value: '140400' }, { text: '晋城市', value: '140500' }, { text: '朔州市', value: '140600' }, { text: '晋中市', value: '140700' } ] } ] export default { name: COMPONENT_NAME, data() { return { state: STATE_HIDE, selectedIndexPair: [0, 0], selectedText: 'open', pickerData: [] } }, created () { // generate data this._loadPickerData(this.selectedIndexPair, undefined /* no prevSelectedIndex due to instantiating */) }, methods: { _loadPickerData (newIndexPair, oldIndexPair) { let provinces let cities // first instantiated if (!oldIndexPair) { provinces = DATA.map(({ value, text }) => ({ value, text })) cities = DATA[newIndexPair[0]].children this.pickerData = [provinces, cities] } else { // provinces'index changed, refresh cities data if (newIndexPair[0] !== oldIndexPair[0]) { cities = DATA[newIndexPair[0]].children this.pickerData.splice(1, 1, cities) // Since cities data changed // refresh better-scroll to recaculate scrollHeight this.$nextTick(() => { this.wheels[1].refresh() }) } } }, _confirm() { this.wheels.forEach(wheel => { /* * if bs is scrolling, force it stop at the nearest wheel-item * or you can use 'restorePosition' method as the below */ // wheel.stop() /* * if bs is scrolling, restore it to the start position * it is same with iOS picker and web Select element implementation * supported at v2.1.0 */ wheel.restorePosition() }) this.hide() const currentSelectedIndexPair = this.selectedIndexPair = this.wheels.map(wheel => { return wheel.getSelectedIndex() }) this.selectedText = this.pickerData.map((data, i) => { const index = currentSelectedIndexPair[i] return `${data[index].text}-${index}` }).join('__') this.$emit(EVENT_SELECT, currentSelectedIndexPair) }, _cancel() { /* * if bs is scrolling, restore it to the start position * it is same with iOS picker and web Select element implementation * supported at v2.1.0 */ this.wheels.forEach(wheel => { wheel.restorePosition() }) this.hide() this.$emit(EVENT_CANCEL) }, show() { if (this.state === STATE_SHOW) { return } this.state = STATE_SHOW if (!this.wheels) { this.$nextTick(() => { this.wheels = [] let wheelWrapper = this.$refs.wheelWrapper for (let i = 0; i < this.pickerData.length; i++) { this._createWheel(wheelWrapper, i) } }) } }, hide() { this.state = STATE_HIDE }, _createWheel(wheelWrapper, i) { const wheels = this.wheels if (!wheels[i]) { wheels[i] = new BScroll(wheelWrapper.children[i], { wheel: { selectedIndex: this.selectedIndexPair[i], wheelWrapperClass: 'wheel-scroll', wheelItemClass: 'wheel-item' }, probeType: 3 }) // when any of wheels'scrolling ended , refresh data let prevSelectedIndexPair = this.selectedIndexPair wheels[i].on('scrollEnd', () => { const currentSelectedIndexPair = wheels.map(wheel => wheel.getSelectedIndex()) this._loadPickerData(currentSelectedIndexPair, prevSelectedIndexPair) prevSelectedIndexPair = currentSelectedIndexPair this.$emit(EVENT_CHANGE, i, this.wheels[i].getSelectedIndex()) }) } else { wheels[i].refresh() } return wheels[i] } } } </script>
<style scoped lang="stylus" rel="stylesheet/stylus"> /* reset */ ul list-style none padding 0 .border-bottom-1px, .border-top-1px position: relative &:before, &:after content: "" display: block position: absolute transform-origin: 0 0 .border-bottom-1px &:after border-bottom: 1px solid #ebebeb left: 0 bottom: 0 width: 100% transform-origin: 0 bottom .border-top-1px &:before border-top: 1px solid #ebebeb left: 0 top: 0 width: 100% transform-origin: 0 top @media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) .border-top-1px &:before width: 200% transform: scale(.5) translateZ(0) .border-bottom-1px &:after width: 200% transform: scale(.5) translateZ(0) @media (-webkit-min-device-pixel-ratio: 3), (min-device-pixel-ratio: 3) .border-top-1px &:before width: 300% transform: scale(.333) translateZ(0) .border-bottom-1px &:after width: 300% transform: scale(.333) translateZ(0) .example-list display: flex justify-content: space-between flex-wrap: wrap margin: 2rem .example-item background-color white padding: 0.8rem border: 1px solid rgba(0, 0, 0, .1) box-shadow: 0 1px 2px 0 rgba(0,0,0,0.1) text-align: center margin-bottom: 1rem flex: 1 &.placeholder visibility: hidden height: 0 margin: 0 padding: 0 .picker position: fixed left: 0 top: 0 z-index: 100 width: 100% height: 100% overflow: hidden text-align: center font-size: 14px background-color: rgba(37, 38, 45, .4) &.picker-fade-enter, &.picker-fade-leave-active opacity: 0 &.picker-fade-enter-active, &.picker-fade-leave-active transition: all .3s ease-in-out .picker-panel position: absolute z-index: 600 bottom: 0 width: 100% height: 273px background: white &.picker-move-enter, &.picker-move-leave-active transform: translate3d(0, 273px, 0) &.picker-move-enter-active, &.picker-move-leave-active transition: all .3s ease-in-out .picker-choose position: relative height: 60px color: #999 .picker-title margin: 0 line-height: 60px font-weight: normal text-align: center font-size: 18px color: #333 .confirm, .cancel position: absolute top: 6px padding: 16px font-size: 14px .confirm right: 0 color: #007bff &:active color: #5aaaff .cancel left: 0 &:active color: #c2c2c2 .picker-content position: relative top: 20px .mask-top, .mask-bottom z-index: 10 width: 100% height: 68px pointer-events: none transform: translateZ(0) .mask-top position: absolute top: 0 background: linear-gradient(to top, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.8)) .mask-bottom position: absolute bottom: 1px background: linear-gradient(to bottom, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.8)) .wheel-wrapper display: flex padding: 0 16px .wheel flex: 1 width: 1% height: 173px overflow: hidden font-size: 18px .wheel-scroll padding: 0 margin-top: 68px line-height: 36px list-style: none .wheel-item list-style: none height: 36px overflow: hidden white-space: nowrap color: #333 &.wheel-disabled-item opacity: .2; .picker-footer height: 20px </style>
城市联动 Picker 的效果,必须通过 JS 部分逻辑将不同 BetterScroll 的实例联系起来,不管是省市,还是省市区的联动,亦是如此。
# wheel 选项对象
提示
当 wheel 配置为 true 的时候,插件内部使用的是默认的插件选项对象。
const bs = new BScroll('.wrapper', {
wheel: true
})
// 相当于
const bs = new BScroll('.wrapper', {
wheel: {
wheelWrapperClass: 'wheel-scroll',
wheelItemClass: 'wheel-item',
rotate: 25,
adjustTime: 400,
selectedIndex: 0,
wheelDisabledItemClass: 'wheel-disabled-item'
}
})
# selectedIndex
- 类型:
number
- 默认值:
0
实例化 Wheel,默认选中第 selectedIndex 项,索引从 0 开始。
# rotate
- 类型:
number
- 默认值:
25
当滚动 wheel 时,wheel item 的弯曲程度。
# adjustTime
- 类型:
number
- 默认值:
400
(ms)
当点击某一项的时候,滚动过去的动画时长。
# wheelWrapperClass
- 类型:
string
- 默认值:
wheel-scroll
滚动元素的 className,这里的「滚动元素」 指的就是 BetterScroll 的 content 元素。
# wheelItemClass
- 类型:
string
- 默认值:
wheel-item
滚动元素的子元素的样式。
# wheelDisabledItemClass
- 类型:
string
- 默认值:
wheel-disabled-item
滚动元素中想要禁用的子元素,类似于 select
元素中禁用的 option
效果。wheel 插件的内部根据 wheelDisabledItemClass
配置来判断是否将该项指定为 disabled 状态。
# 实例方法
提示
以下方法皆已代理至 BetterScroll 实例,例如:
import BScroll from '@better-scroll/core'
import Wheel from '@better-scroll/wheel'
BScroll.use(Wheel)
const bs = new BScroll('.bs-wrapper', {
wheel: true
})
bs.getSelectedIndex()
bs.wheelTo(1, 300)
# getSelectedIndex()
- 返回值:当前选中项的 index,下标从 0 开始
获取当前选中项的索引。
# wheelTo(index = 0, time = 0, [ease])
- 参数:
{ number } index
:选项索引{ number } time
:动画时长{ number } ease<可选>
:动画时长。缓动效果配置,参考 ease.ts (opens new window),默认是bounce
效果
滚动至对应索引的列表项。
# stop() 2.1.0
强制让滚动的 BetterScroll 停止下来,并且吸附至当前距离最近的 wheel-item 的位置。
# restorePosition() 2.1.0
强制让滚动的 BetterScroll 停止下来,并且恢复至滚动开始前的位置。
提示
以上两个方法只对处于滚动中的 BetterScroll 有效,并且 restorePosition
是与原生的 iOS picker 组件的效果一模一样,用户可以根据自己的需求选择对应的方法。
# 事件
# wheelIndexChanged 2.1.0
- 参数:当前选中的 wheel-item 的索引。
- 触发时机:当列表项发生改变的时候。
import BScroll from '@better-scroll/core'
import Wheel from '@better-scroll/wheel'
BScroll.use(Wheel)
const bs = new BScroll('.bs-wrapper', {
wheel: true
})
bs.on('wheelIndexChanged', (index) => {
console.log(index)
})