前端组件化(可拖拽进度条组件)

    项目更迭创建前端ui组件库的一些归纳总结。

1.组件化开发解决的问题:
  • 复用代码降低耦合性,不同模块相同功能表现一致,使代码阅读清晰,减少重复工作,降低开发成本。
2.组件化开发原则:
  • 耦合性:减少依赖和业务属性,数据要求通用,一个组件专注一件事。

  • 可配置:明确输入配置和输出结果,输入配置包括数据,样式,配置代码,事件回调等,输出结果是响应式的

  • 标准性:遵守约定俗成和系统统一标准,能被不同开发人员简单使用。

  • 复用性:可作用于不同场景,不拘泥于特定业务

    注释:  如果与业务强关联的组件应根据不同业务场景切割组件,组件过于粗糙则开发低效解耦失败,组件粒度过细则增强了数据控制难度,调用难度 。

3.实例(可拖拽进度条组件)

实际效果:
在这里插入图片描述

可拖拽进度条组件参数:

入参描述
min进度调左侧对应最小值
max进度条右侧对应最大值
value当前值
color进度条颜色
renderSign是否重绘进度条

代码:

<template>
  <div ref="slider" class="common-slider-style">
    <div class="process" :style="{ width, background: color }"></div>
    <div class="thunk" ref="trunk" :style="{ left }">
      <span class="thunk-number">{{ scale * 10 }}</span>
    </div>
    <span class="process-min">{{ min }}</span>
    <span class="process-max">{{ max }}</span>
  </div>
</template>
<script>
/*
 * min 进度条最小值
 * max 进度条最大值
 * v-model 对当前值进行双向绑定实时显示拖拽进度
 * */
export default {
  props: ['min', 'max', 'value', 'color', 'renderSign'],
  data () {
    return {
      slider: null, //滚动条DOM元素
      thunk: null, //拖拽DOM元素
      per: this.value //当前值
    }
  },
  //渲染到页面的时候
  mounted () {
    this.init()
  },
  watch: {
    renderSign () {
      console.log(
        'value change currentval  is : ' +
          this.per +
          ' this.value:' +
          this.value
      )
      this.per = this.value
      this.init()
    }
  },
  computed: {
    // 设置一个百分比,提供计算slider进度宽度和trunk的left值
    // 对应公式为  当前值-最小值/最大值-最小值 = slider进度width / slider总width
    // trunk left =  slider进度width + trunk宽度/2
    scale () {
      return (this.per - this.min) / (this.max - this.min)
    },
    width () {
      if (this.slider) {
        return this.slider.offsetWidth * this.scale + 'px'
      } else {
        return 0 + 'px'
      }
    },
    left () {
      if (this.slider) {
        return (
          this.slider.offsetWidth * this.scale -
          this.thunk.offsetWidth / 2 +
          'px'
        )
      } else {
        return 0 + 'px'
      }
    }
    // per(){
    //   return this.value
    // }
  },
  methods: {
    init () {
      this.slider = this.$refs.slider
      this.thunk = this.$refs.trunk
      var _this = this
      this.thunk.onmousedown = function (e) {
        var width = parseInt(_this.width)
        var disX = e.clientX
        document.onmousemove = function (e) {
          // value, left, width
          // 当value变化的时候,会通过计算属性修改left,width

          // 拖拽的时候获取的新width
          var newWidth = e.clientX - disX + width
          // 拖拽的时候得到新的百分比
          var scale = newWidth / _this.slider.offsetWidth
          _this.per = Math.ceil((_this.max - _this.min) * scale + _this.min)
          _this.per = Math.max(_this.per, _this.min)
          _this.per = Math.min(_this.per, _this.max)
          _this.$emit('input', _this.per)
        }
        document.onmouseup = function () {
          document.onmousemove = document.onmouseup = null
        }
        return false
      }
    }
  }
}
</script>
<style>
.box {
  margin: 100px auto 0;
  width: 80%;
}
.clear:after {
  content: '';
  display: block;
  clear: both;
}
.slider {
  position: relative;
  margin: 20px 0;
  width: 200px;
  height: 10px;
  background: #e4e7ed;
  border-radius: 5px;
  cursor: pointer;
}
.slider .process {
  position: absolute;
  left: 0;
  top: 0;
  width: 112px;
  height: 10px;
  border-radius: 5px;
  background: #409eff;
}
.slider .thunk {
  position: absolute;
  left: 100px;
  top: -7px;
  width: 20px;
  height: 20px;
}
.slider .block {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid #409eff;
  background: rgba(255, 255, 255, 1);
  transition: 0.2s all;
}
.slider .tips {
  position: absolute;
  left: -7px;
  bottom: 30px;
  min-width: 15px;
  text-align: center;
  padding: 4px 8px;
  background: #000;
  border-radius: 5px;
  height: 24px;
  color: #fff;
}
.slider .tips i {
  position: absolute;
  margin-left: -5px;
  left: 50%;
  bottom: -9px;
  font-size: 16px;
  color: #000;
}
.slider .block:hover {
  transform: scale(1.1);
  opacity: 0.6;
}
</style>

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值