手写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>
  
相关推荐
YUELEI1181 分钟前
vue3 使用sass变量
前端·css·sass
枣仁_19 分钟前
大型语言模型(LLM)深度解析
前端·javascript·面试
程序员马晓博25 分钟前
用上OpenManus啦,这玩意有点像...
前端
鱼樱前端28 分钟前
36道我命由我不由天的JavaScript 基础面试题详解
前端·javascript·面试
嘉琪coder40 分钟前
显示器报废,win笔记本远程连接mac mini4 3种方法实测
前端·windows·mac
hrrrrb1 小时前
【CSS3】筑基篇
前端·css·css3
boy快快长大1 小时前
【VUE】day01-vue基本使用、调试工具、指令与过滤器
前端·javascript·vue.js
三原1 小时前
五年使用vue2、vue3经验,我直接上手react
前端·javascript·react.js