Switch组件

2017-01-17  本文已影响0人  maneo

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)';
    },
上一篇 下一篇

猜你喜欢

热点阅读