element-ui switch组件源码分析整理笔记(二)

摘要:
'is checked':aria checked=“checked”:true value=“activeValue”:false value=“inactiveValue”:disabled=“switchDisabled”@keydown。enter=“switchValue”&gt:spanref=“core”;style=“{'width';coreWidth+'px'}”&gt

源码如下:

<template>
  <div
     
    :class="{ 'is-disabled': switchDisabled, 'is-checked': checked }"
    role="switch"
    :aria-checked="checked"
    :aria-disabled="switchDisabled"
    @click="switchValue"
  >
    <input
       
      type="checkbox"
      @change="handleChange"
      ref="input"
      : 
      :name="name"
      :true-value="activeValue"
      :false-value="inactiveValue"
      :disabled="switchDisabled"
      @keydown.enter="switchValue"
    >

    <span
      :class="['el-switch__label', 'el-switch__label--left', !checked ? 'is-active' : '']"
      v-if="inactiveIconClass || inactiveText">
      <i :  v-if="inactiveIconClass"></i>
      <span v-if="!inactiveIconClass && inactiveText" :aria-hidden="checked">{{ inactiveText }}</span>
    </span>

    <span   ref="core" :style="{ 'width': coreWidth + 'px' }"></span>

    <span
      :class="['el-switch__label', 'el-switch__label--right', checked ? 'is-active' : '']"
      v-if="activeIconClass || activeText">
      <i :  v-if="activeIconClass"></i>
      <span v-if="!activeIconClass && activeText" :aria-hidden="!checked">{{ activeText }}</span>
    </span>
  </div>
</template>
<script>
  import Focus from 'element-ui/src/mixins/focus';
  import Migrating from 'element-ui/src/mixins/migrating';

  export default {
    name: 'ElSwitch',
    mixins: [Focus('input'), Migrating],
    //  注入elForm对象,防止不和el-form使用时对象不存在的问题。
    inject: {
      elForm: {
        default: ''
      }
    },
    props: {
      value: {
        type: [Boolean, String, Number],
        default: false
      },
      disabled: { //是否禁用
        type: Boolean,
        default: false
      },
       { //switch 的宽度(像素)
        type: Number,
        default: 40
      },
      activeIconClass: { //switch 打开时所显示图标的类名,设置此项会忽略 active-text
        type: String,
        default: ''
      },
      inactiveIconClass: { //switch 关闭时所显示图标的类名,设置此项会忽略 inactive-text
        type: String,
        default: ''
      },
      activeText: String, //switch 打开时的文字描述
      inactiveText: String, //switch 关闭时的文字描述
      activeColor: { //switch 打开时的背景色
        type: String,
        default: ''
      },
      inactiveColor: { //switch 关闭时的背景色
        type: String,
        default: ''
      },
      activeValue: { //switch 打开时的值
        type: [Boolean, String, Number],
        default: true
      },
      inactiveValue: { //switch 关闭时的值
        type: [Boolean, String, Number],
        default: false
      },
      name: { //switch 对应的 name 属性
        type: String,
        default: ''
      },
      id: String
    },
    data() {
      return {
        coreWidth: this.width
      };
    },
    created() {
      if (!~[this.activeValue, this.inactiveValue].indexOf(this.value)) {
        this.$emit('input', this.inactiveValue);
      }
    },
    computed: {
        //当前的开关组件的状态
        checked() {
            //父组件中v-model绑定的值是否等于switch 打开时的值
            return this.value === this.activeValue;
        },
        //当前组件是否被禁用
      switchDisabled() {
        return this.disabled || (this.elForm || {}).disabled;
      }
    },
    watch: {
      checked() {
        this.$refs.input.checked = this.checked;
        //在用户设置了active-color和inactive-color时,通过setBackgroundColor设置开关的背景色
        if (this.activeColor || this.inactiveColor) {
          this.setBackgroundColor();
        }
      }
    },
    methods: {
      handleChange(event) {
        //!this.checked为true,则表示当前是this.value === this.inactiveValue,即为关着的状态;需要切换为开着的状态,返回this.activeValue
        this.$emit('input', !this.checked ? this.activeValue : this.inactiveValue);
        this.$emit('change', !this.checked ? this.activeValue : this.inactiveValue);
        this.$nextTick(() => {
            //修改value值并不是立即生效,而且为了防止父组件未修改值,这里进行了重复赋值
          this.$refs.input.checked = this.checked;
        });
      },
      //在用户设置了active-color和inactive-color时,点击切换开关时,根据this.checked的值设置开关的背景颜色
      setBackgroundColor() {
        //如果 this.checked为true,即当前switch是打开,开关返回打开时设置的背景色
        let newColor = this.checked ? this.activeColor : this.inactiveColor;
        this.$refs.core.style.borderColor = newColor;
        this.$refs.core.style.backgroundColor = newColor;
      },
      switchValue() {
        //在不禁用的状态下才能点击
        !this.switchDisabled && this.handleChange();
      },
      getMigratingConfig() {
        return {
          props: {
            'on-color': 'on-color is renamed to active-color.',
            'off-color': 'off-color is renamed to inactive-color.',
            'on-text': 'on-text is renamed to active-text.',
            'off-text': 'off-text is renamed to inactive-text.',
            'on-value': 'on-value is renamed to active-value.',
            'off-value': 'off-value is renamed to inactive-value.',
            'on-icon-class': 'on-icon-class is renamed to active-icon-class.',
            'off-icon-class': 'off-icon-class is renamed to inactive-icon-class.'
          }
        };
      }
    },
    mounted() {
      /* istanbul ignore if */
      this.coreWidth = this.width || 40;
      if (this.activeColor || this.inactiveColor) {
        this.setBackgroundColor();
      }
      this.$refs.input.checked = this.checked;
    }
  };
</script>

解析:
(1)组件的html结构

<div class="el-switch">
        <input   type="checkbox">
        <!--显示左边的标签-->
        <span class="el-switch__label el-switch__label--left">
             <i></i>
             <span></span>
        </span>
        <!--中间的开关-->
        <span class="el-switch__core"></span>
        <!--显示右边的标签-->
        <span class="el-switch__label el-switch__label--right">
            <i></i>
            <span></span>
         </span>
</div>

input标签被隐藏掉了,css部分代码如下:

.el-switch__input {
    position: absolute;
     0;
    height: 0;
    opacity: 0;
    margin: 0;
}

如果把上面的样式代码注释掉,如图所示:
element-ui switch组件源码分析整理笔记(二)第1张
通过 <input type="checkbox"> 的checked属性来控制文字显示以及开关的状态切换。最外层包裹的div是为了能够通过点击文字也能切换开关状态。

(2)混入的 mixins: [Focus('input'), Migrating]

主要是migrating.js,该文件主要是用于开发环境下提示一些迁移或者即将修改的属性和方法的。
示例:我用的element-ui v2.4.9,我按下面这样写,off-text属性在我当前的版本中已经被改为inactive-text

<el-switch v-model="value2" off-text="关着"></el-switch>当我运行之后在控制台输出:

element-ui switch组件源码分析整理笔记(二)第2张

所有迁移的属性在组件的getMigratingConfig()方法中:

 getMigratingConfig() {
        return {
          props: {
            'on-color': 'on-color is renamed to active-color.',
            'off-color': 'off-color is renamed to inactive-color.',
            'on-text': 'on-text is renamed to active-text.',
            'off-text': 'off-text is renamed to inactive-text.',
            'on-value': 'on-value is renamed to active-value.',
            'off-value': 'off-value is renamed to inactive-value.',
            'on-icon-class': 'on-icon-class is renamed to active-icon-class.',
            'off-icon-class': 'off-icon-class is renamed to inactive-icon-class.'
          }
        };
      }

(3)created方法

 created() {
    //如果用户传入的v-model的值既不是activeValue也不是inactiveValue时,将inactiveValue传递出去,开关处于关状态
      if (!~[this.activeValue, this.inactiveValue].indexOf(this.value)) {
        this.$emit('input', this.inactiveValue);
      }
    },

~代表按位非运算符,如果[this.activeValue, this.inactiveValue].indexOf(this.value)为-1,则按位非后变为0。

参考博文:https://juejin.im/post/5b861db0e51d4538aa1b5630
http://www.zhuyuntao.cn/2018/10/24/element-ui-focus-js和migrating.js文件源码学习

免责声明:文章转载自《element-ui switch组件源码分析整理笔记(二)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇RocketMQ源码 — 八、 RocketMQ消息重试如何查看SharePoint Server的版本信息下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

弄懂Favicon

当Alec Rust问及HTML5 Boilerplate项目是否可以提供切换成高DPI的favicon的时候,我才意识到我对网站图标(favorite icon),触摸图标(touch icons),和磁贴图标(tile icons)知之甚少。当我决定稍稍深究一下的时候却发现一些有趣的事情。 自从IE在1999年首次引入favicon以来,之后它就没再发...

一千行MySQL学习笔记

以下为本人当年初学MySQL时做的笔记,也从那时起没再更新过,但还是囊括了基本的知识点,有时还翻出来查查。是不是干货,就看亲们了~ 如果哪天笔记有更新了,我还是会更新该文章滴,其实笔记已经放到了GitHub上,只是没告诉你们而已,嚯嚯!  PHP笔记也贴出来了哈~ http://www.cnblogs.com/shockerli/p/2000-plus-l...

C# 获取config文件 实体转换

随着项目的扩展,单独的key,value配置文件已经不能满足需求了 这里需要自定义配置节点,例如 1 <!--自定义 具体实体类配置问节点信息--> 2 <School Name="红旗小学" Number="1008" Address="北京市,西城区……"></School> 当然,这样的节点可以有多重获取...

python爬虫(二十) select方法

有时候需要css选择器 1、通过标签名查找: <style type="text/css"> p{ background-color:pink; } </style> <body> <div class="box"> <p&...

网页仿 Office 2003 的工具条

网页仿 Office 2003 的工具条   [ 日期:2005-01-27 ]   [ 来自:网上摘录 ]<html><head><meta http-equiv="Content-Language" content="zh-cn"><meta http-equiv="Content-Type" content=...

Reactive Spring实战 -- WebFlux使用教程

WebFlux是Spring 5提供的响应式Web应用框架。 它是完全非阻塞的,可以在Netty,Undertow和Servlet 3.1+等非阻塞服务器上运行。 本文主要介绍WebFlux的使用。 FluxWeb vs noFluxWeb WebFlux是完全非阻塞的。 在FluxWeb前,我们可以使用DeferredResult和AsyncRestTe...