手写WBXslider 组件 (标签为微博小程序,需要改成对应的标签,或方法)

引入自己封装的组件

javascript 复制代码
    <WBXslider style="width: 200px;margin-left: 20px;" 
    :value="30" 
    :radiusNum="20"
     @moveChange="move" >
     <template slot="round">
      <wbx-view style="width: 10px;height:20px;background-color: rebeccapurple;"></wbx-view>
     </template>
    </WBXslider>

组件内部 wbxslider组件也是自定义的,需要请看我主页关于wbxslider的文章
有默认模式,也可以使用插槽模式自定义

javascript 复制代码
<template>
    <wbx-view ref="styleObj" >
      <wbx-view  style="display: flex;flex-direction: row;align-items: center;" :style="{height:computedHeight+'px'}">
        <wbxslider ref="slider" :radiusNum="radiusNum" :style="{color:progressColor}" :progressHeight="progressHeight" :videoProgressWidth="videoProgressWidth" :progressColor="progressColor" :ProgressWidth="moveDistanceNum" :progressBackgroundColor="progressBackgroundColor"></wbxslider>
        <wbx-view  :style="{left: moveDistanceNum+'px',position: 'absolute'}" @touchmove="handleTouchMove"@touchstart~stop="a()">
          <wbx-view v-if="isUseRoundSlot" ref="roundSlot">
            <slot name="round" ></slot>
          </wbx-view> 
          <wbx-view v-else
            :style="{ height: roundSize + 'px', width:roundSize + 'px', borderRadius:roundSize + 'px',backgroundColor:roundColor }"
            style="border: 1px solid #808080;">
          </wbx-view>
        </wbx-view> 
      </wbx-view>
      <!-- <wbx-view v-if="showValue">{{ value }}</wbx-view> -->
    </wbx-view>
  </template>
  
  <script>
  /**
   * 用法<WBXslider style="margin-left: 30px;width: 300px;"></WBXslider>
   * @moveChange() 拖动过程中触发的事件,
   * slot="round"   插槽用来自定义滑块的样式 
   * progressHeight 进度条高度
   * roundSize  圆圈的大小
   * roundColor 圆圈的颜色
   * progressColor 进度条的选中颜色
   * progressBackgroundColor 进度条未选中的颜色
   * step  步长
   * value  当前取值
   * disabled  是否禁用
   * max  最大值
   * 
   * @type WBXAppOption
   */
  import wbxslider from "./wbxslider.vue";
  const pageOptions = {
    data() {
      return {
        roundSize:0,//圆的大小
        moveDistanceNum:0,//移动距离
        percent:0,
        marginLeftNum:0,//左边距
        videoProgressWidth:0,//进度条宽
        percentValue:0,//展示的值百分比
        roundHeightSize:0 //插槽高
      };
    },
    props: {
      roundSize: {
      type: Number,
      default: 15,
    },
    progressHeight:{
      type: Number,
      default: 5,
    },
    roundColor:{
      type:String,
        default:'#fff'
    },
    value:{
      type: Number,
      default: 0,
    },
    disabled:{
      type: Boolean,
      default: false,
    },
    max:{
      type: Number,
      default: 100,
    },
    radiusNum:{
      type: Number,
      default: 0,
    },
    progressBackgroundColor:{
      type:String,
      default:'#e6e6e6'
    },
    progressColor:{
      type:String,
      default:'#bfbfbf'
    },
    step:{
      type: Number,
      default: 0,
    }
  },
    mounted() {   
      this.$nextTick(() => {
        this.progressStyleObject = this.$refs.styleObj.styleObject;
        // console.log(this.progressStyleObject ,"this.$refs.styleObj33333333333333")
        this.videoProgressWidth=parseFloat(this.progressStyleObject.width)?parseFloat(this.progressStyleObject.width):300
        this.marginLeftNum=parseFloat(this.progressStyleObject.marginLeft)?parseFloat(this.progressStyleObject.marginLeft):0
        if(this.value>0){
            this.moveDistanceNum=((this.videoProgressWidth-this.roundSize)/this.max)*this.value
          }
        if(this.isUseRoundSlot){
            this.roundHeightSize=parseFloat(this.$refs.roundSlot.childNodes[0].styleObject.height)
            this.roundSize=parseFloat(this.$refs.roundSlot.childNodes[0].styleObject.width)
          }
    });
  },
    components: {
      wbxslider
    },
    computed: {
      // 是否使用插槽
      isUseRoundSlot() {
        console.log(11111111,!!this.$slots.round)
      return !!this.$slots.round;
    },
    computedHeight() {
      return  this.isUseRoundSlot?this.roundHeightSize:this.roundSize
    }
  },
    methods: {
      a(){},
      handleTouchMove(e) {
        if(this.disabled==true){
          return
        }
      let minx = e.touches[0].clientX-this.marginLeftNum;
      if (minx >= this.videoProgressWidth-this.roundSize) {
        this.percent = this.videoProgressWidth-this.roundSize;
      } else if (minx <= 0) {
        this.percent = 0;
      } else {
        this.percent = minx;
      }
      if(this.step>0){
        this.percentValue =parseInt(this.percent/((this.videoProgressWidth-this.roundSize)/this.max))
        if(this.percentValue%this.step==0){
          this.moveDistanceNum=this.percentValue*((this.videoProgressWidth-this.roundSize)/this.max)
          this.percentValue =this.moveDistanceNum/((this.videoProgressWidth-this.roundSize)/this.max)
          this.$emit('moveChange',{value:this.percentValue})

        }
      }else{
        this.moveDistanceNum = this.percent;
        this.percentValue =this.moveDistanceNum/((this.videoProgressWidth-this.roundSize)/this.max)
        this.$emit('moveChange',{value:this.percentValue})

      }
      
    },},
    wbox: {
      onLoad() { 
      },
      onShow() {
        // 页面显示/切入前台时触发
      },
      onHide() {
        // 页面隐藏时触发
      },
      onUnload() {
        // 页面退出时触发
      },
    },
  };
  export default pageOptions;
  </script>
  
  <style></style>
  
相关推荐
kyriewen39 分钟前
你的代码仓库变成“毛线团”了?Monorepo 用 Turborepo 拆成“乐高积木”
前端·javascript·面试
身如柳絮随风扬41 分钟前
你知道什么是 Ajax 吗?—— 从入门到原理,一篇彻底搞懂
前端·ajax·okhttp
旷世奇才李先生1 小时前
Vue3\+TypeScript 2026实战——企业级前端项目架构搭建与性能优化全指南
前端·架构·typescript
Beginner x_u2 小时前
前端八股整理(工程化 02)|CommonJS/ESM、Webpack Loader/Plugin 与Vite 对比
前端·webpack·node.js·plugin·loader
openKaka_2 小时前
createRoot 到底创建了什么:FiberRootNode 和 HostRootFiber 的初始化过程
前端·javascript·react.js
习明然3 小时前
UniApp开发体验感受总结
前端·uni-app
刀法如飞3 小时前
Claude Code Skills 推荐:2026年最值得安装的10个AI技能
前端·后端·ai编程
Lee川4 小时前
面试手写 KeepAlive:React 组件缓存的实现原理
前端·react.js·面试
墨染天姬4 小时前
【AI】cursor提示词小技巧
前端·数据库·人工智能
烛阴4 小时前
TEngine 入门系列(一):TEngine 是什么 & 为什么选它
前端·unity3d