| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * 使ç¨bindingxæ¹æ¡å®ç°slider |
| | | * åªè½ä½¿ç¨äºnvueä¸ |
| | | */ |
| | | // å¼å
¥bindingxï¼æ¤åºç±»ä¼¼äºå¾®ä¿¡å°ç¨åºwxsï¼ç®çæ¯è®©jsè¿è¡å¨è§å¾å±ï¼åå°è§å¾å±åé»è¾å±çéä¿¡ææ |
| | | const BindingX = uni.requireNativePlugin('bindingx') |
| | | // nvueæä½domçåºï¼ç¨äºè·ådomçå°ºå¯¸ä¿¡æ¯ |
| | | const dom = uni.requireNativePlugin('dom') |
| | | // nvueä¸ç¨äºæä½å
ç´ å¨ç»çåºï¼ç±»ä¼¼äºuni.animationï¼åªä¸è¿uni.animationä¸è½ç¨äºnvue |
| | | const animation = uni.requireNativePlugin('animation') |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | // bindingxçåè°å¼ï¼ç¨äºåæ¶ç»å® |
| | | panEvent: null, |
| | | // æ è®°æ¯å¦ç§»å¨ç¶æ |
| | | moving: false, |
| | | // ä½ç§»çåç§»é |
| | | x: 0, |
| | | // æ¯å¦æ£å¨è§¦æ¸è¿ç¨ä¸ï¼ç¨äºæ è®°å¨ç»ç±»æ¯å¦æ·»å æç§»é¤ |
| | | touching: false, |
| | | changeFromInside: false |
| | | } |
| | | }, |
| | | watch: { |
| | | // çå¬vlaueçååï¼æ¤ååå¯è½æ¯ç±äºå
é¨ä¿®æ¹v-modelçå¼ï¼æè
å¤é¨ |
| | | // 仿å¡ç«¯è·åä¸ä¸ªå¼åï¼èµå¼ç»sliderçv-modelè导è´ç |
| | | value(n) { |
| | | if (!this.changeFromInside) { |
| | | this.initX() |
| | | } else { |
| | | this.changeFromInside = false |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | | }, |
| | | methods: { |
| | | init() { |
| | | this.getSliderRect() |
| | | }, |
| | | // è·åèç¹ä¿¡æ¯ |
| | | // è·åslider尺寸 |
| | | getSliderRect() { |
| | | // è·åæ»åæ¡çå°ºå¯¸ä¿¡æ¯ |
| | | // éè¿nvueçdom模åï¼æ¥è¯¢èç¹ä¿¡æ¯ |
| | | setTimeout(() => { |
| | | dom.getComponentRect(this.$refs['slider'], res => { |
| | | this.sliderRect = res.size |
| | | this.initX() |
| | | }) |
| | | }, 10) |
| | | }, |
| | | // åå§åæé®ä½ç½® |
| | | initButtonStyle({ |
| | | barStyle, |
| | | buttonWrapperStyle |
| | | }) { |
| | | this.barStyle = barStyle |
| | | this.buttonWrapperStyle = buttonWrapperStyle |
| | | }, |
| | | emitEvent(event, value) { |
| | | this.$emit(event, value ? value : this.value) |
| | | }, |
| | | formatStep(value) { |
| | | // ç§»å¨ç¹å æ»é¿åº¦çç¾åæ¯ |
| | | return Math.round(Math.max(this.min, Math.min(value, this.max)) / this.step) * this.step |
| | | }, |
| | | // æ»å¨å¼å§ |
| | | onTouchStart(e) { |
| | | // 黿¢é¡µé¢æ»å¨ï¼å¯ä»¥ä¿è¯å¨æ»å¨è¿ç¨ä¸ï¼ä¸è®©é¡µé¢å¯ä»¥ä¸ä¸æ»å¨ï¼é æä¸å¥½çä½éª |
| | | e.stopPropagation && e.stopPropagation() |
| | | e.preventDefault && e.preventDefault() |
| | | if (this.moving || this.disabled) { |
| | | // éæ¾ä¸ä¸æ¬¡çèµæº |
| | | if (this.panEvent?.token != 0) { |
| | | BindingX.unbind({ |
| | | token: this.panEvent.token, |
| | | // pan为æå¿äºä»¶ |
| | | eventType: 'pan' |
| | | }) |
| | | this.gesToken = 0 |
| | | } |
| | | return |
| | | } |
| | | |
| | | this.moving = true |
| | | this.touching = true |
| | | |
| | | // è·åå
ç´ ref |
| | | const button = this.$refs['nvue-button'].ref |
| | | const gap = this.$refs['nvue-gap'].ref |
| | | |
| | | const { |
| | | min, |
| | | max, |
| | | step |
| | | } = this |
| | | const { |
| | | left, |
| | | width |
| | | } = this.sliderRect |
| | | |
| | | // åå§å¼ä¸ºæ¬æ¬¡åç§»éxï¼å 䏿¬¡åæ¢æ»å¨æ¶çç»æå¼ |
| | | let exporession = `(${this.x} + x)` |
| | | // å°åç§»çxå¼ï¼è½¬ä¸ºæ»ä½ç§»çç¾åæ¯å¼ï¼ä¸ºäºåminåmaxè¿è¡å¤æ |
| | | exporession = `(${exporession} / ${width}) * 100` |
| | | if (step > 1) { |
| | | // 妿stepæ¥è¿å¤§äº1ï¼éè¦è·³æ¥ï¼æä»¥éè¦ä½¿ç¨Math.roundè¿è¡åæ´ |
| | | exporession = `round(max(${min}, min(${exporession}, ${max})) / ${step}) * ${step}` |
| | | } else { |
| | | // å½step=1æ¶ï¼æ éè·³æ¥ï¼å
åå©ç¨bindingxæ§è½ï¼æ»å宿¶è·éæå¿ï¼è¾¾å°ä¸æ»çææ |
| | | exporession = `max(${min}, min(${exporession}, ${max}))` |
| | | } |
| | | // å°ç¾åæ¯æå转å为对åºçpxå¼ |
| | | exporession = `${exporession} / 100 * ${width}` |
| | | // æå¤§å¼ä¸å
许è¶
è¿è½¨è¿¹ç宽度 |
| | | const { |
| | | sliderWidth |
| | | } = this.sliderRect |
| | | exporession = `min(${sliderWidth}, ${exporession})` |
| | | // æ»åç¹æ»æ¯éè¦ä¸ä¸ªå·¦åç§»çå¼ï¼ä¸ºèªèº«å®½åº¦çä¸å |
| | | const buttonExpression = `${exporession} - ${this.blockHeight / 2}` |
| | | // é¿é为äºKPIè弿ºçBindingX |
| | | this.panEvent = BindingX.bind({ |
| | | anchor: button, |
| | | eventType: 'pan', |
| | | props: [{ |
| | | element: gap, |
| | | // ç»å®width屿§ï¼è®¾ç½®å
¶å®½åº¦å¼ |
| | | property: 'width', |
| | | expression |
| | | }, { |
| | | element: button, |
| | | // ç»å®width屿§ï¼è®¾ç½®å
¶å®½åº¦å¼ |
| | | property: 'transform.translateX', |
| | | expression: buttonExpression |
| | | }] |
| | | }, (e) => { |
| | | if (e.state === 'end' || e.state === 'exit') { |
| | | // |
| | | this.x = uni.$u.range(0, left + width, e.deltaX + this.x) |
| | | // æ ¹æ®åç§»å¼ï¼å¾åºç§»å¨çç¾åæ¯ï¼è¿èä¿®æ¹ååç»å®çv-modelçå¼ |
| | | const value = (this.x / width) * 100 |
| | | const percent = this.formatStep(value) |
| | | // ä¿®æ¹valueå¼ |
| | | this.$emit('input', percent) |
| | | // æ è®°ä¸ä¸æ¬¡è§¦åvalueçwatchæ¶ï¼è¿ä¸ªå¼çååï¼æ¯ç±å
鍿¹åç |
| | | this.changeFromInside = true |
| | | this.moving = false |
| | | this.touching = false |
| | | } |
| | | }) |
| | | }, |
| | | // ä»valueçååï¼åæ¨å¾åºxçå¼è¯¥ä¸ºå¤å° |
| | | initX() { |
| | | const { |
| | | left, |
| | | width |
| | | } = this.sliderRect |
| | | // å¾åºxçåå§åç§»å¼ï¼ä¹æä»¥éè¦è¿ä¹åï¼æ¯å 为å¨bindingXä¸ï¼è§¦æ¸æ»å¨æ¶ï¼åªè½ç弿¬æ¬¡ç§»å¨çåç§»å¼ |
| | | // èæ æ³çå¼åç¡®çååç§»å¨ç两个ç¹çåæ å¼ï¼weex纯粹为é¿éå·´å·´çKPI(é¨é¨ä¸ç»©èæ ¸)产ç©ï¼ä¹å°±è¿æ ·äº |
| | | this.x = this.value / 100 * width |
| | | // 设置移å¨çå¼ |
| | | const barStyle = { |
| | | width: this.x + 'px' |
| | | } |
| | | // æé®çåå§å¼ |
| | | const buttonWrapperStyle = { |
| | | transform: `translateX(${this.x - this.blockHeight / 2}px)` |
| | | } |
| | | this.initButtonStyle({ |
| | | barStyle, |
| | | buttonWrapperStyle |
| | | }) |
| | | } |
| | | } |
| | | } |