Switch组件

Switch组件在分析的时候,主要需要关注三个点。如何实现自定义宽度、如何实现自定义背景颜色,以及html的整体架构。

<label class="el-switch">
    <input type="checkbox" class="el-switch-input">
    <span class="el-switch-core" ref="core">
      <span class="el-switch-button" :style="buttonStyle"></span>
    </span>
    <transition name="label-fade">
      <div class="el-switch-label el-switch-label-left">
      </div>
    </transition>
    <transition name="label-fade">
      <div class="el-switch-label el-switch-label-right">
      </div>
    </transition>
 </label>
  1. 使用label包裹input, 利用了当选中label, input也会被选中的特性。这用即使隐藏了input, 使用label去“模拟”, 其实底层实质伤上,switch还是在操作这个input的value值。
  2. 因为按接口的文档,如果有文字就显示文字,如果有不同状态的图标就优先显示图标。所以这里就将这里边的逻辑单独提取到了switch-label里面。

后面就单独说几个Switch设计里面,我学到的东西

  1. 为什么要重新使用一个computed属性 _value
<input
      type="checkbox"
      class="el-switch-input"
      v-model="_value">  //而不是传入的props: value

试了以后发现,Vue报了警告信息

Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"

尽量避免直接去重写父组件中传入的props值,尝试使用computed属性。官方的说法是,这样随意的改变props,会让父子组件中的数据流变得非常的怪异和混乱。

平时都只是用到了computed的getter,但是,它是可以设置setter的!!!

computed: {
    hasText: function () {
      return this.onText || this.offText;
    },
    _value: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit('input', val);
      }
    }
  },

要看懂为什么使用$emit('input', val)就实现了_value的改变,就需要明白v-model的本质,这个语法糖的原理,以及v-bind和v-model有什么区别。

  1. 如何实现自定义宽度
    利用一个data()属性 coreWidth, 加上mounted钩子函数,来初始化coreWidth
mounted() {
    if(this.width === 0) {
      this.coreWidth = this.hasText ? 58 : 46;
    }
}

在core 和 switch-label上,都是通过:style动态设置宽度为coreWidth.

  1. 如何自定义背景颜色
    当没有设置onColor或者offColor的时候,改变switch状态,input会根据checked与否来改变core的背景颜色和边框颜色。如果设置了onColor、offColor怎么办呢?
    watch监听value值的变化。
watch: {
    value() {
      if(this.onColor || this.offColor) {
        this.setBackgroundColor();
      }
      this.handleButtonTransform();
    }
},
  1. 如何改变button圆圈的位置
    因为不同的宽度,button的定位位置也不一样,js动态修改css值是肯定的。所以这里就和以前绑定类名这种不一样了,直接绑定一个style对象。
<span class="el-switch-button" :style="buttonStyle"></span>
handleButtonTransform() {
      this.buttonStyle.transform = this.value ? `translate(${this.coreWidth - 20}px, 2px)`: 'translate(2px, 2px)';
    },
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,868评论 18 139
  • 关于作者 周林,github,陆金所前端程序员,专注 Hybrid APP 性能优化和新技术探索。欢迎任何形式的提...
    federerchou阅读 7,291评论 0 2
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,074评论 0 29
  • Mr丶Song阅读 186评论 0 0
  • 文 / 無月 Vol.19 你是否也有过这样的经历,每当到了自己的楼层的时候,在电梯门打开之前,就有一只手迫不及待...
    無月阅读 1,119评论 6 6