• 小DEMO:在vue中自定义range组件


    1、组件样式

    2、使用

    1. import cSlider from '@/components/c-slider/c-slider.vue'
    2. <div class="range">
    3. <cSlider v-model="cScale" @change="cScaleChange" :min="1" :max="10"/>
    4. div>

    3、组件代码

    1. <template>
    2. <div
    3. class="slider-box"
    4. data-id="1"
    5. ref="sliderBox"
    6. @mousedown.stop.prevent="onMousedown($event)"
    7. @mouseup.stop.prevent="onMouseup"
    8. @mouseleave.stop.prevent="onMouseup"
    9. @mousemove.stop.prevent="onMousemove($event)"
    10. >
    11. <div class="slider-wrap">
    12. <div
    13. class="slider-bar"
    14. data-id="1"
    15. :style="{
    16. width: ((modelValue - min)*stepWidth)+'px'
    17. }">
    18. <span
    19. class="slider-btn"
    20. :class="{
    21. active: sliderActive
    22. }"
    23. data-id="1"
    24. @mousedown.stop.prevent="onMousedown($event, true)"
    25. :style="{
    26. left: ((modelValue - min)*stepWidth)+'px'
    27. }">
    28. <b>{{ modelValue }}b>
    29. span>
    30. div>
    31. div>
    32. div>
    33. template>
    34. <script>
    35. export default {
    36. model: {
    37. prop: 'modelValue',
    38. event: 'change'
    39. },
    40. props: {
    41. modelValue: {
    42. type: Number,
    43. default: 0
    44. },
    45. min: {
    46. type: Number,
    47. default: 0
    48. },
    49. max: {
    50. type: Number,
    51. default: 10
    52. },
    53. step: {
    54. type: Number,
    55. default: 1
    56. }
    57. },
    58. data() {
    59. return {
    60. rangeValue: 0,
    61. stepWidth: 0,
    62. sliderBox: null,
    63. moveAbled: false,
    64. mousePoint: null,
    65. sliderActive: false
    66. }
    67. },
    68. mounted() {
    69. // document.addEventListener('mouseup', this.onMouseup)
    70. // document.addEventListener('mouseleave', this.onMouseup)
    71. // this.$nextTick(() => {
    72. let _sliderBox = this.$refs['sliderBox'].getBoundingClientRect()
    73. this.sliderBox = {
    74. width: _sliderBox.width,
    75. height: _sliderBox.height,
    76. top: _sliderBox.top + document.documentElement.scrollTop,
    77. left: _sliderBox.left + document.documentElement.scrollLeft
    78. }
    79. this.stepWidth = this.sliderBox.width/(this.max-this.min)
    80. // console.log('xxx', _sliderBox, this.sliderBox)
    81. // })
    82. },
    83. beforeMount() {
    84. // document.removeEventListener('mouseup', this.onMouseup)
    85. // document.removeEventListener('mouseleave', this.onMouseup)
    86. },
    87. methods: {
    88. onMousemove(e) {
    89. if(this.moveAbled) {
    90. this.sliderActive = true
    91. let d = e.pageX - this.mousePoint.pageX
    92. let _val = Math.round(this.modelValue + d/this.stepWidth)
    93. if(_val < this.min) {
    94. _val = this.min
    95. } else if(_val > this.max) {
    96. _val = this.max
    97. }
    98. if(_val !== this.modelValue) {
    99. this.mousePoint = e
    100. }
    101. this.$emit('update:modelValue', _val)
    102. this.$emit('change')
    103. console.log('onMousemove', _val)
    104. }
    105. },
    106. onMouseup() {
    107. // console.log('onMouseup')
    108. this.moveAbled = false
    109. this.sliderActive = false
    110. },
    111. onMousedown(e, moveAbled) {
    112. console.log('onMousedown', this.stepWidth)
    113. if(moveAbled) {
    114. this.moveAbled = moveAbled
    115. this.mousePoint = e
    116. } else {
    117. let d = e.pageX - this.sliderBox.left
    118. let _val = Math.round(this.min + d/this.stepWidth)
    119. if(_val < this.min) {
    120. _val = this.min
    121. } else if(_val > this.max) {
    122. _val = this.max
    123. }
    124. this.$emit('update:modelValue', _val)
    125. this.$emit('change')
    126. }
    127. },
    128. }
    129. }
    130. script>
    131. <style lang="scss" scoped>
    132. .slider-box {
    133. width: 100%;
    134. height: 100%;
    135. display: flex;
    136. align-items: center;
    137. .range {
    138. position: absolute;
    139. top: 50%;
    140. left: 50%;
    141. width: 100%;
    142. transform: translate(-50%, -50%);
    143. opacity: 0.3;
    144. }
    145. .slider-wrap {
    146. position: relative;
    147. width: 100%;
    148. height: 3px;
    149. border-radius: 2px;
    150. background: #D9D9D9;
    151. cursor: pointer;
    152. .slider-bar {
    153. border-radius: 2px;
    154. height: 100%;
    155. background: #0256FF;
    156. .slider-btn {
    157. cursor: grab;
    158. position: absolute;
    159. top: 50%;
    160. left: 0;
    161. transform: translate(-50%, -50%);
    162. width: 10px;
    163. height: 10px;
    164. background: white;
    165. border-radius: 100%;
    166. box-shadow: 0 0 2px 2px #D6D6D6;
    167. &:hover, &.active {
    168. width: 15px;
    169. height: 15px;
    170. b {
    171. display: block;
    172. }
    173. }
    174. &::after {
    175. position: absolute;
    176. top: 50%;
    177. left: 50%;
    178. transform: translate(-50%, -50%);
    179. content: '';
    180. width: 4px;
    181. height: 4px;
    182. background: #0256FF;
    183. border-radius: 100%;
    184. }
    185. b {
    186. display: none;
    187. position: absolute;
    188. top: -10px;
    189. left: 50%;
    190. background: rgba(0, 0, 0, 0.3);
    191. color: white;
    192. font-size: 12px;
    193. padding: 0 5px;
    194. border-radius: 5px;
    195. transform: translate(-50%, -100%);
    196. &::after {
    197. position: absolute;
    198. bottom: 0px;
    199. left: 50%;
    200. transform: translate(-50%, 100%);
    201. content: '';
    202. width: 0;
    203. height: 0;
    204. border-top: 4px solid rgba(0, 0, 0, 0.3);
    205. border-left: 4px solid transparent;
    206. border-right: 4px solid transparent;
    207. border-right: 4px solid transparent;
    208. }
    209. }
    210. }
    211. }
    212. }
    213. }
    214. style>

  • 相关阅读:
    STM32CubeMX外部中断
    Sentinel dashboard规则持久化到nacos改造
    SpringBoot+Mybatis 配置多数据源及事务管理
    i5 12600HX比i5 12600H选哪个好
    Highlight_Matching_Pair问题解决
    常用排序算法实现
    uView 2.0:uni-app生态的利剑出鞘,引领UI框架新纪元
    ggkegg | 用这个神包玩转kegg数据库吧!~(一)
    【go微服务】protobuf中oneof、WrapValue和FieldMask的使用
    【前端设计模式】之享元模式
  • 原文地址:https://blog.csdn.net/qq_31851435/article/details/134422566