手写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>
  
相关推荐
by__csdn7 小时前
Node.js版本与npm版本的对应关系
前端·npm·node.js
AI_56788 小时前
Webpack性能优化终极指南:4步实现闪电打包
前端·webpack·性能优化
威风的虫8 小时前
ES6 数组方法:告别循环,拥抱函数式编程
开发语言·前端·javascript
小杨快跑~8 小时前
ES6 Promise:告别回调地狱的异步编程革命
前端·javascript·ecmascript·es6
linweidong8 小时前
VIVO前端面试题及参考答案
前端·跨域·localstorage·重绘·浏览器兼容·git管理·前端重构
有意义8 小时前
从零搭建:json-server+Bootstrap+OpenAI 全栈 AI 小项目
前端·后端·llm
温宇飞8 小时前
CCState:为大型 Web 应用设计的状态管理库
前端
r0ad9 小时前
读诗的时候我却使用了自己研发的Chrome元素截图插件
前端·javascript·chrome
IT_陈寒9 小时前
React性能优化实战:这5个Hooks技巧让我的应用快了40%
前端·人工智能·后端
江天澄10 小时前
HTML5 中常用的语义化标签及其简要说明
前端·html·html5