看到網(wǎng)上很多關于Vue的尺子組件屡律,有一些上傳到npm官網(wǎng)的腌逢,但是使用并不方便,支持的定制化也不夠用超埋,抽空寫了一個搏讶,總體來說主要是樣式寫好,效果是基于better-scroll實現(xiàn)的霍殴,支持bounce效果媒惕,自動識別最近的刻度,只需要傳入自己的最大值和最小值来庭,就會幫你算出一個包含最大值的最大刻度吓笙,整體效果不錯关摇,由于是demo芳杏,沒有基于任何UI效果,要達到自己設計師要求的UI效果冲甘,可以將這份代碼拷貝過去自己改造定義一個尺子的Vue組件來使用尊搬,效果圖:
頁面DOM結構如下叁鉴,樣式采用的stylus預處理語法,個人覺得stylus就是為css而生的佛寿,相比less幌墓,sass好用很多,請現(xiàn)在webpack.config.js里面配上處理stylus的規(guī)則冀泻,
<template>
? ? <div class="box">
? ? ? ? <div class="arrow">{{value}}</div>
? ? ? ? <div class="wrapper ruler">
? ? ? ? ? ? <ul ref="ul" :style="{width: ul_width + 'px'}">
? ? ? ? ? ? ? ? <li v-for="(v, i) in ruler_max_num" :key="i">
? ? ? ? ? ? ? ? ? ? <label>{{v * 10}}</label>
? ? ? ? ? ? ? ? ? ? <span v-for="(e, d) in 10" :key="d"></span>
? ? ? ? ? ? ? ? </li>
? ? ? ? ? ? </ul>
? ? ? ? </div>
? ? </div>
</template>
樣式如下:
<style lang="stylus" rel="stylesheet/stylus" scoped>
.box
? ? .arrow
? ? ? ? font-weight 500
? ? ? ? width 100%
? ? ? ? height 20px
? ? ? ? text-align center
? ? ? ? position relative
? ? ? ? top -20px
? ? ? ? &::after
? ? ? ? ? ? content ''
? ? ? ? ? ? position absolute
? ? ? ? ? ? left 50%
? ? ? ? ? ? top 110px
? ? ? ? ? ? transform translateX(-50%)
? ? ? ? ? ? border 8px solid black
? ? ? ? ? ? border-color black? transparent transparent transparent
? ? .ruler
? ? ? ? font-size 12px
? ? ? ? width 100%
? ? ? ? padding-top 100px
? ? ? ? >ul
? ? ? ? ? ? width 100%
? ? ? ? ? ? height 80px
? ? ? ? ? ? border 1px solid #ddd
? ? ? ? ? ? border-left none
? ? ? ? ? ? border-right none
? ? ? ? ? ? display flex
? ? ? ? ? ? justify-content space-between
? ? ? ? ? ? background #fff
? ? ? ? ? ? >li
? ? ? ? ? ? ? ? height 18px
? ? ? ? ? ? ? ? display flex
? ? ? ? ? ? ? ? justify-content space-between
? ? ? ? ? ? ? ? box-sizing border-box
? ? ? ? ? ? ? ? position relative
? ? ? ? ? ? ? ? &:first-child
? ? ? ? ? ? ? ? ? ? position relative
? ? ? ? ? ? ? ? ? ? &::before
? ? ? ? ? ? ? ? ? ? ? ? position absolute
? ? ? ? ? ? ? ? ? ? ? ? content ""
? ? ? ? ? ? ? ? ? ? ? ? left -1px
? ? ? ? ? ? ? ? ? ? ? ? top 0
? ? ? ? ? ? ? ? ? ? ? ? height 11px
? ? ? ? ? ? ? ? ? ? ? ? width 1px
? ? ? ? ? ? ? ? ? ? ? ? background black
? ? ? ? ? ? ? ? ? ? ? ? opacity 0.8
? ? ? ? ? ? ? ? &::after
? ? ? ? ? ? ? ? ? ? position absolute
? ? ? ? ? ? ? ? ? ? content ""
? ? ? ? ? ? ? ? ? ? right 0
? ? ? ? ? ? ? ? ? ? top 0
? ? ? ? ? ? ? ? ? ? height 15px
? ? ? ? ? ? ? ? ? ? width 1px
? ? ? ? ? ? ? ? ? ? background black
? ? ? ? ? ? ? ? >label
? ? ? ? ? ? ? ? ? ? position absolute
? ? ? ? ? ? ? ? ? ? right -6px
? ? ? ? ? ? ? ? ? ? bottom -16px
? ? ? ? ? ? ? ? >span
? ? ? ? ? ? ? ? ? ? width 10px
? ? ? ? ? ? ? ? ? ? height 11px
? ? ? ? ? ? ? ? ? ? box-sizing border-box
? ? ? ? ? ? ? ? ? ? border-right 1px solid black
? ? ? ? ? ? ? ? ? ? opacity 0.8
? ? ? ? ? ? ? ? ? ? position relative
? ? ? ? ? ? ? ? ? ? &::after
? ? ? ? ? ? ? ? ? ? ? ? position absolute
? ? ? ? ? ? ? ? ? ? ? ? content ""
? ? ? ? ? ? ? ? ? ? ? ? left 50%
? ? ? ? ? ? ? ? ? ? ? ? top 0
? ? ? ? ? ? ? ? ? ? ? ? transform translateX(-50%)
? ? ? ? ? ? ? ? ? ? ? ? height 8px
? ? ? ? ? ? ? ? ? ? ? ? width 1px
? ? ? ? ? ? ? ? ? ? ? ? background black
? ? ? ? ? ? ? ? ? ? ? ? opacity 0.5
</style>
js代碼如下:
<script>
import BScroll from 'better-scroll'
export default {
? ? props: {
? ? ? ? max_val: { // 需要
? ? ? ? ? ? type: Number,
? ? ? ? ? ? default() {
? ? ? ? ? ? ? ? return 168
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? min_val: {
? ? ? ? ? ? type: Number,
? ? ? ? ? ? default() {
? ? ? ? ? ? ? ? return 0
? ? ? ? ? ? }
? ? ? ? }
? ? },
? ? data() {
? ? ? ? return {
? ? ? ? ? ? split_val: 10,
? ? ? ? ? ? value: 0
? ? ? ? }
? ? },
? ? mounted() {
? ? ? ? let ul = this.$refs.ul
? ? ? ? let lis = ul.getElementsByTagName('li')
? ? ? ? let first_li = lis[0]
? ? ? ? let last_li = lis[lis.length - 1]
? ? ? ? first_li.style.marginLeft = document.body.clientWidth/2 + 'px'
? ? ? ? last_li.style.marginRight= document.body.clientWidth/2 + 'px'
? ? ? ? this.$nextTick(()=>{
? ? ? ? ? ? let bs = new BScroll('.wrapper', {
? ? ? ? ? ? ? ? startX: 0,
? ? ? ? ? ? ? ? scrollX: true,
? ? ? ? ? ? ? ? probeType: 2,
? ? ? ? ? ? ? ? useTransition: false,
? ? ? ? ? ? ? ? bounce: true,
? ? ? ? ? ? ? ? momentum: true
? ? ? ? ? ? })
? ? ? ? ? ? bs.on('scrollEnd', ({x, y}) => {
? ? ? ? ? ? ? ? if (x > 0) {
? ? ? ? ? ? ? ? ? ? x = 0
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? this.value = -Math.round(x/10)
? ? ? ? ? ? ? ? bs.scrollTo(Math.round(x/10) * 10, 0)
? ? ? ? ? ? })
? ? ? ? })
? ? },
? ? computed: {
? ? ? ? ul_width() {
? ? ? ? ? ? return this.ruler_max_num * 10 * 10 + document.body.clientWidth?
? ? ? ? },
? ? ? ? ruler_max_num() {
? ? ? ? ? ? let split_num = Math.floor(this.max_val / this.split_val)
? ? ? ? ? ? let left_v = this.max_val % this.split_val
? ? ? ? ? ? if (left_v > 0) {
? ? ? ? ? ? ? ? split_num = split_num + 1
? ? ? ? ? ? }
? ? ? ? ? ? return split_num
? ? ? ? }
? ? }
}
</script>
基本上項目安裝好better-scroll后就可以運行起來了,
今天做了一個小小的優(yōu)化常侣,支持傳入最大值和最小值,從而只顯示這個值域段的刻度
樣式添加:
<style lang="stylus" rel="stylesheet/stylus" scoped>
.box
? ? .arrow
? ? ? ? font-weight 500
? ? ? ? width 100%
? ? ? ? height 20px
? ? ? ? text-align center
? ? ? ? position relative
? ? ? ? top -20px
? ? ? ? &::after
? ? ? ? ? ? content ''
? ? ? ? ? ? position absolute
? ? ? ? ? ? left 50%
? ? ? ? ? ? top 110px
? ? ? ? ? ? transform translateX(-50%)
? ? ? ? ? ? border 8px solid black
? ? ? ? ? ? border-color black? transparent transparent transparent
? ? .ruler
? ? ? ? font-size 12px
? ? ? ? width 100%
? ? ? ? padding-top 100px
? ? ? ? >ul
? ? ? ? ? ? width 100%
? ? ? ? ? ? height 80px
? ? ? ? ? ? border 1px solid #ddd
? ? ? ? ? ? border-left none
? ? ? ? ? ? border-right none
? ? ? ? ? ? display flex
? ? ? ? ? ? justify-content space-between
? ? ? ? ? ? background #fff
? ? ? ? ? ? >li
? ? ? ? ? ? ? ? height 18px
? ? ? ? ? ? ? ? display flex
? ? ? ? ? ? ? ? justify-content space-between
? ? ? ? ? ? ? ? box-sizing border-box
? ? ? ? ? ? ? ? position relative
? ? ? ? ? ? ? ? &:first-child
? ? ? ? ? ? ? ? ? ? position relative
? ? ? ? ? ? ? ? ? ? &::before
? ? ? ? ? ? ? ? ? ? ? ? position absolute
? ? ? ? ? ? ? ? ? ? ? ? content ""
? ? ? ? ? ? ? ? ? ? ? ? left -1px
? ? ? ? ? ? ? ? ? ? ? ? top 0
? ? ? ? ? ? ? ? ? ? ? ? height 11px
? ? ? ? ? ? ? ? ? ? ? ? width 1px
? ? ? ? ? ? ? ? ? ? ? ? background black
? ? ? ? ? ? ? ? ? ? ? ? opacity 0.8
? ? ? ? ? ? ? ? &::after
? ? ? ? ? ? ? ? ? ? position absolute
? ? ? ? ? ? ? ? ? ? content ""
? ? ? ? ? ? ? ? ? ? right 0
? ? ? ? ? ? ? ? ? ? top 0
? ? ? ? ? ? ? ? ? ? height 15px
? ? ? ? ? ? ? ? ? ? width 1px
? ? ? ? ? ? ? ? ? ? background black
? ? ? ? ? ? ? ? >label
? ? ? ? ? ? ? ? ? ? position absolute
? ? ? ? ? ? ? ? ? ? right -6px
? ? ? ? ? ? ? ? ? ? bottom -16px
? ? ? ? ? ? ? ? ? ? &.first
? ? ? ? ? ? ? ? ? ? ? ? right 100%
? ? ? ? ? ? ? ? ? ? ? ? bottom -14px
? ? ? ? ? ? ? ? ? ? ? ? margin-right -6px
? ? ? ? ? ? ? ? >span
? ? ? ? ? ? ? ? ? ? width 10px
? ? ? ? ? ? ? ? ? ? height 11px
? ? ? ? ? ? ? ? ? ? box-sizing border-box
? ? ? ? ? ? ? ? ? ? border-right 1px solid black
? ? ? ? ? ? ? ? ? ? opacity 0.8
? ? ? ? ? ? ? ? ? ? position relative
? ? ? ? ? ? ? ? ? ? &::after
? ? ? ? ? ? ? ? ? ? ? ? position absolute
? ? ? ? ? ? ? ? ? ? ? ? content ""
? ? ? ? ? ? ? ? ? ? ? ? left 50%
? ? ? ? ? ? ? ? ? ? ? ? top 0
? ? ? ? ? ? ? ? ? ? ? ? transform translateX(-50%)
? ? ? ? ? ? ? ? ? ? ? ? height 8px
? ? ? ? ? ? ? ? ? ? ? ? width 1px
? ? ? ? ? ? ? ? ? ? ? ? background black
? ? ? ? ? ? ? ? ? ? ? ? opacity 0.5
</style>
JS邏輯:
export default {
? ? props: {
? ? ? ? max_val: {
? ? ? ? ? ? type: Number,
? ? ? ? ? ? default() {
? ? ? ? ? ? ? ? return 888
? ? ? ? ? ? }
? ? ? ? },
? ? ? ? min_val: {
? ? ? ? ? ? type: Number,
? ? ? ? ? ? default() {
? ? ? ? ? ? ? ? return 666
? ? ? ? ? ? }
? ? ? ? }
? ? },
? ? data() {
? ? ? ? return {
? ? ? ? ? ? split_val: 10,
? ? ? ? ? ? value: 0,
? ? ? ? ? ? initail_val: 0
? ? ? ? }
? ? },
? ? mounted() {
? ? ? ? let ul = this.$refs.ul
? ? ? ? let lis = ul.getElementsByTagName('li')
? ? ? ? let first_li = lis[0]
? ? ? ? let last_li = lis[lis.length - 1]
? ? ? ? first_li.style.marginLeft = document.body.clientWidth/2 + 'px'
? ? ? ? last_li.style.marginRight= document.body.clientWidth/2 + 'px'
? ? ? ? this.value = this.ruler_min_num * 10
? ? ? ? this.initail_val = this.ruler_min_num * 10
? ? ? ? this.$nextTick(()=>{
? ? ? ? ? ? let bs = new BScroll('.wrapper', {
? ? ? ? ? ? ? ? startX: 0,
? ? ? ? ? ? ? ? scrollX: true,
? ? ? ? ? ? ? ? probeType: 2,
? ? ? ? ? ? ? ? useTransition: false,
? ? ? ? ? ? ? ? bounce: true,
? ? ? ? ? ? ? ? momentum: true
? ? ? ? ? ? })
? ? ? ? ? ? bs.on('scrollEnd', ({x, y}) => {
? ? ? ? ? ? ? ? if (x > 0) {
? ? ? ? ? ? ? ? ? ? x = 0
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? this.value = -Math.round(x / 10) + this.ruler_min_num * 10
? ? ? ? ? ? ? ? bs.scrollTo(Math.round(x / 10) * 10, 0)
? ? ? ? ? ? })
? ? ? ? })
? ? },
? ? computed: {
? ? ? ? ul_width() {
? ? ? ? ? ? return this.actual_num * 10 * 10 + document.body.clientWidth
? ? ? ? },
? ? ? ? ruler_max_num() {
? ? ? ? ? ? let split_num = Math.floor(this.max_val / this.split_val)
? ? ? ? ? ? let left_v = this.max_val % this.split_val
? ? ? ? ? ? if (left_v > 0) {
? ? ? ? ? ? ? ? split_num = split_num + 1
? ? ? ? ? ? }
? ? ? ? ? ? return split_num
? ? ? ? },
? ? ? ? ruler_min_num() {
? ? ? ? ? ? let split_num = Math.floor(this.min_val / this.split_val)
? ? ? ? ? ? return split_num
? ? ? ? },
? ? ? ? actual_num() {
? ? ? ? ? ? return this.ruler_max_num - this.ruler_min_num
? ? ? ? }
? ? }
}
效果圖:傳入最大值88弹渔,傳入最小值66胳施,顯示為60-90之前的尺段,提高尺子的滑動效率: