Vue實現(xiàn)雙向滑動輸入條
本文實例為大家分享了Vue實現(xiàn)雙向滑動輸入條的具體代碼,供大家參考,具體內(nèi)容如下
效果圖如下:
組件支持傳入最小值(min)最大值(max)的范圍,并可設(shè)置初始最小值(initialMin)和初始最大值(initialMax)
拖動滑塊調(diào)整最大最小值,并可點擊輸入條位置,切換數(shù)值
①創(chuàng)建滑動輸入條組件Slider.vue
<template> ? <div class="m-slider" ref="slider"> ? ? <div class="u-slider-rail" @click="onClickPoint"></div> ? ? <div class="u-slider-track" @click="onClickPoint" :style="`left: ${left}px; right: auto; width: ${right - left}px;`"></div> ? ? <div class="u-slider-handle" ref="left" @mousedown="onLeftMouseDown" :style="`left: ${left}px; right: auto; transform: translateX(-50%);`"></div> ? ? <div class="u-slider-handle" ref="right" @mousedown="onRightMouseDown" :style="`left: ${right}px; right: auto; transform: translateX(-50%);`"></div> ? </div> </template> <script> export default { ? name: 'Slider', ? props: { ? ? min: { // 滑動輸入條最小值 ? ? ? type: Number, ? ? ? default: 0 ? ? }, ? ? max: { // 滑動輸入條最大值 ? ? ? type: Number, ? ? ? default: 100 ? ? }, ? ? initialMin: { // 滑動輸入條初始最小值,默認在最左側(cè) ? ? ? type: Number, ? ? ? default: 0 ? ? }, ? ? initialMax: { // 滑動輸入條初始最大值,默認在最右側(cè) ? ? ? type: Number, ? ? ? default: 100 ? ? } ? }, ? data () { ? ? return { ? ? ? left: '', // 左滑塊距離滑動條左端的距離 ? ? ? right: '', // 右滑動距離滑動條左端的距離 ? ? ? width: '' // 滑動輸入條在頁面中的寬度 ? ? } ? }, ? mounted () { ? ? this.width = this.$refs.slider.clientWidth ? ? this.left = this.initialMin * this.width / this.max ? ? this.right = this.initialMax * this.width / this.max ? }, ? computed: { ? ? low () { ? ? ? return Math.round(this.left / this.width * this.max) ? ? }, ? ? high () { ? ? ? return Math.round(this.right / this.width * this.max) ? ? } ? }, ? watch: { ? ? low (to, from) { ? ? ? this.$emit('lowChange', to) // 左滑塊對應數(shù)字回調(diào) ? ? }, ? ? high (to, from) { ? ? ? this.$emit('highChange', to) // 右滑塊對應數(shù)字回調(diào) ? ? } ? }, ? methods: { ? ? onClickPoint (e) { // 點擊滑動條,移動滑塊 ? ? ? var offsetLeft = this.$refs.slider.offsetLeft // 滑動條左端距離屏幕左側(cè)的距離 ? ? ? var moveX = e.clientX - offsetLeft ? ? ? if (moveX <= this.left) { ? ? ? ? this.left = moveX ? ? ? } else if (this.moveX >= this.right) { ? ? ? ? this.right = this.moveX ? ? ? } else { ? ? ? ? if ((moveX - this.left) < (this.right - moveX)) { ? ? ? ? ? this.left = moveX ? ? ? ? } else { ? ? ? ? ? this.right = moveX ? ? ? ? } ? ? ? } ? ? }, ? ? onLeftMouseDown (e) { // 在滾動條上拖動左滑塊 ? ? ? // 滑塊水平方向上距離屏幕左端的距離,減去滑塊距離滑動條最左端的距離:e.clientX - this.$refs.left.offsetLeft ? ? ? var offsetLeft = this.$refs.slider.offsetLeft // 滑動條左端距離屏幕左側(cè)的距離 ? ? ? document.onmousemove = (e) => { ? ? ? ? var moveX = e.clientX - offsetLeft ? ? ? ? if (moveX < 0) { ? ? ? ? ? this.left = 0 ? ? ? ? } else if (moveX >= this.right) { ? ? ? ? ? this.left = this.right ? ? ? ? } else { ? ? ? ? ? this.left = moveX ? ? ? ? } ? ? ? } ? ? ? document.onmouseup = (e) => { ? ? ? ? document.onmousemove = null ? ? ? ? document.onmouseup = null ? ? ? } ? ? }, ? ? onRightMouseDown (e) { // 在滾動條上拖動右滑塊 ? ? ? /// 滑塊水平方向上距離屏幕左端的距離,減去滑塊距離滑動條最左端的距離:e.clientX - this.$refs.left.offsetLeft ? ? ? var offsetLeft = this.$refs.slider.offsetLeft // 滑動條左端距離屏幕左側(cè)的距離 ? ? ? console.log('offsetLeft:', offsetLeft) ? ? ? document.onmousemove = (e) => { ? ? ? ? var moveX = e.clientX - offsetLeft ? ? ? ? if (moveX > this.width) { ? ? ? ? ? this.right = this.width ? ? ? ? } else if (moveX <= this.left) { ? ? ? ? ? this.right = this.left ? ? ? ? } else { ? ? ? ? ? this.right = moveX ? ? ? ? } ? ? ? } ? ? ? document.onmouseup = (e) => { ? ? ? ? document.onmousemove = null ? ? ? ? document.onmouseup = null ? ? ? } ? ? } ? } } </script> <style lang="less" scoped> .m-slider { ? height: 4px; ? position: relative; ? cursor: pointer; ? touch-action: none; ? &:hover { ? ? .u-slider-rail { // 灰色未選擇滑動條背景色 ? ? ? background: #E3E3E3; ? ? } ? ? .u-slider-track { // 藍色已選擇滑動條背景色 ? ? ? background: #1890ff; ? ? } ? } ? .u-slider-rail { // 灰色未選擇滑動條背景色 ? ? position: absolute; ? ? z-index: 99; ? ? height: 4px; ? ? width: 100%; ? ? background: #f5f5f5; ? ? border-radius: 2px; ? ? transition: background .3s; ? } ? .u-slider-track { // 藍色已選擇滑動條背景色 ? ? background: #91d5ff; ? ? border-radius: 4px; ? ? position: absolute; ? ? z-index: 99; ? ? height: 4px; ? ? cursor: pointer; ? ? transition: background .3s; ? } ? .u-slider-handle { // 滑塊 ? ? position: absolute; ? ? z-index: 999; ? ? width: 14px; ? ? height: 14px; ? ? margin-top: -7px; ? ? box-shadow: 0; ? ? background: #fff; ? ? border: 2px solid #91d5ff; ? ? border-radius: 50%; ? ? cursor: pointer; ? ? transition: border-color .3s,box-shadow .6s,transform .3s cubic-bezier(.18,.89,.32,1.28); ? ? &:hover { ? ? ? border-color: #1890ff; ? ? } ? } } </style>
②在要使用的頁面引入
<div class="m-num"> ?? ?<p class="u-num">{{ low }}</p> ?? ?<p class="u-num">{{ high }}</p> </div> <div class="slider"> ?? ?<Slider ?? ??? ?:min="0" ?? ??? ?:max="100" ?? ??? ?:initialMin="low" ?? ??? ?:initialMax="high" ?? ??? ?@lowChange="lowChange" ?? ??? ?@highChange="highChange" ?? ?/> </div> import Slider from '@/components/Slider' components: { ? ? Slider } data () { ?? ?return { ?? ??? ?low: 20, ?? ??? ?high: 80 ?? ?} } lowChange (val) { ? ? ? this.low = val ? ? ? console.log('lowChange:', val) }, highChange (val) { ? ? ? this.high = val ? ? ? console.log('highChange:', val) }
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue2.0+webpack環(huán)境的構(gòu)造過程
本文分步驟給大家介紹了vue2.0+webpack環(huán)境的構(gòu)造過程的相關(guān)資料,非常不錯具有參考借鑒價值,需要的朋友可以參考下2016-11-11vue.js獲取數(shù)據(jù)庫數(shù)據(jù)實例代碼
本篇文章主要介紹了vue.js獲取數(shù)據(jù)庫數(shù)據(jù)實例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05Vue reactive函數(shù)實現(xiàn)流程詳解
一個基本類型的數(shù)據(jù),想要變成響應式數(shù)據(jù),那么需要通過ref函數(shù)包裹,而如果是一個對象的話,那么需要使用reactive函數(shù),這篇文章主要介紹了Vue reactive函數(shù)2023-01-01使用van-picker?動態(tài)設(shè)置當前選中項
這篇文章主要介紹了使用van-picker?動態(tài)設(shè)置當前選中項方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10