From f26f29d84e0a68831a6af14dab3eec5500496d2e Mon Sep 17 00:00:00 2001 From: spring <2396852758@qq.com> Date: 星期三, 28 五月 2025 16:48:52 +0800 Subject: [PATCH] 初始化项目 --- uview-ui/components/u-slider/u-slider.vue | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 257 insertions(+), 0 deletions(-) diff --git a/uview-ui/components/u-slider/u-slider.vue b/uview-ui/components/u-slider/u-slider.vue new file mode 100644 index 0000000..ae695c4 --- /dev/null +++ b/uview-ui/components/u-slider/u-slider.vue @@ -0,0 +1,257 @@ +<template> + <view class="u-slider" @tap="onClick" :class="[disabled ? 'u-slider--disabled' : '']" :style="{ + backgroundColor: inactiveColor + }"> + <view + class="u-slider__gap" + :style="[ + barStyle, + { + height: height + 'rpx', + backgroundColor: activeColor + } + ]" + > + <view class="u-slider__button-wrap" @touchstart="onTouchStart" + @touchmove="onTouchMove" @touchend="onTouchEnd" + @touchcancel="onTouchEnd"> + <slot v-if="$slots.default || $slots.$default"/> + <view v-else class="u-slider__button" :style="[blockStyle, { + height: blockWidth + 'rpx', + width: blockWidth + 'rpx', + backgroundColor: blockColor + }]"></view> + </view> + </view> + </view> +</template> + +<script> +/** + * slider 婊戝潡閫夋嫨鍣� + * @tutorial https://uviewui.com/components/slider.html + * @property {Number | String} value 婊戝潡榛樿鍊硷紙榛樿0锛� + * @property {Number | String} min 鏈�灏忓�硷紙榛樿0锛� + * @property {Number | String} max 鏈�澶у�硷紙榛樿100锛� + * @property {Number | String} step 姝ラ暱锛堥粯璁�1锛� + * @property {Number | String} blockWidth 婊戝潡瀹藉害锛岄珮绛変簬瀹斤紙30锛� + * @property {Number | String} height 婊戝潡鏉¢珮搴︼紝鍗曚綅rpx锛堥粯璁�6锛� + * @property {String} inactiveColor 搴曢儴鏉¤儗鏅鑹诧紙榛樿#c0c4cc锛� + * @property {String} activeColor 搴曢儴閫夋嫨閮ㄥ垎鐨勮儗鏅鑹诧紙榛樿#497bff锛� + * @property {String} blockColor 婊戝潡棰滆壊锛堥粯璁�#ffffff锛� + * @property {Object} blockStyle 缁欐粦鍧楄嚜瀹氫箟鏍峰紡锛屽璞″舰寮� + * @property {Boolean} disabled 鏄惁绂佺敤婊戝潡(榛樿涓篺alse) + * @event {Function} start 婊戝姩瑙﹀彂 + * @event {Function} moving 姝e湪婊戝姩涓� + * @event {Function} end 婊戝姩缁撴潫 + * @example <u-slider v-model="value" /> + */ +export default { + name: 'u-slider', + props: { + // 褰撳墠杩涘害鐧惧垎姣斿�硷紝鑼冨洿0-100 + value: { + type: [Number, String], + default: 0 + }, + // 鏄惁绂佺敤婊戝潡 + disabled: { + type: Boolean, + default: false + }, + // 婊戝潡瀹藉害锛岄珮绛変簬瀹斤紝鍗曚綅rpx + blockWidth: { + type: [Number, String], + default: 30 + }, + // 鏈�灏忓�� + min: { + type: [Number, String], + default: 0 + }, + // 鏈�澶у�� + max: { + type: [Number, String], + default: 100 + }, + // 姝ヨ繘鍊� + step: { + type: [Number, String], + default: 1 + }, + // 婊戝潡鏉¢珮搴︼紝鍗曚綅rpx + height: { + type: [Number, String], + default: 6 + }, + // 杩涘害鏉$殑婵�娲婚儴鍒嗛鑹� + activeColor: { + type: String, + default: '#497bff' + }, + // 杩涘害鏉$殑鑳屾櫙棰滆壊 + inactiveColor: { + type: String, + default: '#c0c4cc' + }, + // 婊戝潡鐨勮儗鏅鑹� + blockColor: { + type: String, + default: '#ffffff' + }, + // 鐢ㄦ埛瀵规粦鍧楃殑鑷畾涔夐鑹� + blockStyle: { + type: Object, + default() { + return {}; + } + }, + }, + data() { + return { + startX: 0, + status: 'end', + newValue: 0, + distanceX: 0, + startValue: 0, + barStyle: {}, + sliderRect: { + left: 0, + width: 0 + } + }; + }, + watch: { + value(n) { + // 鍙湁鍦ㄩ潪婊戝姩鐘舵�佹椂锛屾墠鍙互閫氳繃value鏇存柊婊戝潡鍊硷紝杩欓噷鐩戝惉锛屾槸涓轰簡璁╃敤鎴疯Е鍙� + if(this.status == 'end') this.updateValue(this.value, false); + } + }, + created() { + this.updateValue(this.value, false); + }, + mounted() { + // 鑾峰彇婊戝潡鏉$殑灏哄淇℃伅 + this.$uGetRect('.u-slider').then(rect => { + this.sliderRect = rect; + }); + }, + methods: { + onTouchStart(event) { + if (this.disabled) return; + this.startX = 0; + // 瑙︽懜鐐归泦 + let touches = event.touches[0]; + // 瑙︽懜鐐瑰埌灞忓箷宸﹁竟鐨勮窛绂� + this.startX = touches.clientX; + // 姝ゅ鐨則his.value铏戒负props鍊硷紝浣嗘槸閫氳繃$emit('input')杩涜浜嗕慨鏀� + this.startValue = this.format(this.value); + // 鏍囩ず褰撳墠鐨勭姸鎬佷负寮�濮嬭Е鎽告粦鍔� + this.status = 'start'; + }, + onTouchMove(event) { + if (this.disabled) return; + // 杩炵画瑙︽懜鐨勮繃绋嬩細涓�鐩磋Е鍙戞湰鏂规硶锛屼絾鍙湁鎵嬫寚瑙﹀彂涓旂Щ鍔ㄤ簡鎵嶈璁や负鏄嫋鍔ㄤ簡锛屾墠鍙戝嚭浜嬩欢 + // 瑙︽懜鍚庣涓�娆$Щ鍔ㄥ凡缁忓皢status璁剧疆涓簃oving鐘舵�侊紝鏁呰Е鎽哥浜屾绉诲姩涓嶄細瑙﹀彂鏈簨浠� + if (this.status == 'start') this.$emit('start'); + let touches = event.touches[0]; + // 婊戝潡鐨勫乏杈逛笉涓�瀹氳窡灞忓箷宸﹁竟鎺ュ¥锛屾墍浠ラ渶瑕佸噺鍘绘渶澶栧眰鐖跺厓绱犵殑宸﹁竟鍊� + this.distanceX = touches.clientX - this.sliderRect.left; + // 鑾峰緱绉诲姩璺濈瀵规暣涓粦鍧楃殑鐧惧垎姣斿�硷紝姝や负甯︽湁澶氫綅灏忔暟鐨勫�硷紝涓嶈兘鐢ㄦ鏇存柊瑙嗗浘 + // 鍚﹀垯閫犳垚閫氫俊闃诲锛岄渶瑕佹瘡鏀瑰彉涓�涓猻tep鍊兼椂淇敼涓�娆¤鍥� + this.newValue = (this.distanceX / this.sliderRect.width) * 100; + this.status = 'moving'; + // 鍙戝嚭moving浜嬩欢 + this.$emit('moving'); + this.updateValue(this.newValue, true); + }, + onTouchEnd() { + if (this.disabled) return; + if (this.status === 'moving') { + this.updateValue(this.newValue, false); + this.$emit('end'); + } + this.status = 'end'; + }, + updateValue(value, drag) { + // 鍘绘帀灏忔暟閮ㄥ垎锛屽悓鏃朵篃鏄step姝ヨ繘鐨勫鐞� + const width = this.format(value); + // 涓嶅厑璁告粦鍔ㄧ殑鍊艰秴杩噈ax鏈�澶у�硷紝鐧惧垎姣斾篃涓嶈兘瓒呰繃100 + if(width > this.max || width > 100) return; + // 璁剧疆绉诲姩鐨勭櫨鍒嗘瘮鍊� + let barStyle = { + width: width + '%' + }; + // 绉诲姩鏈熼棿鏃犻渶杩囨浮鍔ㄧ敾 + if (drag == true) { + barStyle.transition = 'none'; + } else { + // 闈炵Щ鍔ㄦ湡闂达紝鍒犳帀瀵硅繃娓′负绌虹殑澹版槑锛岃css涓殑澹版槑璧锋晥 + delete barStyle.transition; + } + // 淇敼value鍊� + this.$emit('input', width); + this.barStyle = barStyle; + }, + format(value) { + // 灏嗗皬鏁板彉鎴愭暣鏁帮紝涓轰簡鍑忓皯瀵硅鍥剧殑鏇存柊锛岄�犳垚瑙嗗浘灞備笌閫昏緫灞傜殑闃诲 + return Math.round(Math.max(this.min, Math.min(value, this.max)) / this.step) * this.step; + }, + onClick(event) { + if (this.disabled) return; + // 鐩存帴鐐瑰嚮婊戝潡鐨勬儏鍐碉紝璁$畻鏂瑰紡涓巓nTouchMove鏂规硶鐩稿悓 + const value = ((event.detail.x - this.sliderRect.left) / this.sliderRect.width) * 100; + this.updateValue(value, false); + } + } +}; +</script> + +<style lang="scss" scoped> +@import "../../libs/css/style.components.scss"; + +.u-slider { + position: relative; + border-radius: 999px; + border-radius: 999px; + background-color: #ebedf0; +} + +.u-slider:before { + position: absolute; + right: 0; + left: 0; + content: ''; + top: -8px; + bottom: -8px; + z-index: -1; +} + +.u-slider__gap { + position: relative; + border-radius: inherit; + transition: width 0.2s; + transition: width 0.2s; + background-color: #1989fa; +} + +.u-slider__button { + width: 24px; + height: 24px; + border-radius: 50%; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); + background-color: #fff; + cursor: pointer; +} + +.u-slider__button-wrap { + position: absolute; + top: 50%; + right: 0; + transform: translate3d(50%, -50%, 0); +} + +.u-slider--disabled { + opacity: 0.5; +} +</style> -- Gitblit v1.9.3