前言👋
- 用户就是上帝,站在上帝的角度也就是站在使用者的角度去看待组件。
- 用过不少优秀的
UI
库,用的时候美滋滋,轮到自己搭组件库的时候往往会去参考别人的源码。 - 看完源码后恍然大悟 噢!原来可以这样写,但心里难免会有疑惑别人是怎么想出来这种解决思路的?🤳
- 这一系列文章主要是面向未理解或者有疑惑的同学所以讲的比较基础,就让我们站在用户的角度去思考结构,看看换一种思路去写代码是不是有变化?
关于Switch组件🥽
为什么我们会用到switch
作为用户👨💼
- 想到选择,你们会想到什么,有的人第一时间会想到下拉框,而有的人第一时间会想到
switch
开关。 - 在我记事以来我遇到的第一个
switch
可能就是我那台小小的iphone
飞行模式的开关了,那时候还不是前端工程师,看到那个之后就觉得特别好看简洁,觉得其他的都low
爆了。 - 相信不只是我被
switch
简约的风格给迷住,往往我们在遇到只有两个选项的问题时更多希望遇到的是开关而不是下拉框,比如一个表单属性的(是
、否
)(成功
、失败
)
作为组件库使用者👨💻
- 当我们将组件库的
switch
组件放到我们的页面我们想要的效果是什么?
- 简约
- 可以满足基本的切换需求
- 可以在基本的需求上进行定制增加功能(比如:
颜色属性
大小
是否添加文字
)
- 在某一个方面来说,
switch
也可以规避一个字段是否必填
必选
,相信大家有遇到过这样的需求,在制作表单时往往需要对某一个字段判断'有没有填写'
'是否为空'
然后弹出一行红色的提示说'此项不能为空'
,然而使用了switch
则可以避免用户不选
选错
这种情况发生也不用丑陋的红色提示占了页面位置。
搭建组件⚒️
接下来可能用尽可能少的代码搭配
element
的源码进行结构说明,配合element Switch源码食用更加美味喔
基本架子🔨
- 要设计一个
switch
非常简单,在看element
源码之前我也自己写过一个switch
,要想让上图的开关动起来
其实只是中间白色那块在一个绿色的容器里面改变了定位位置而已然而当点击了开关后背景从绿色会变成其他颜色来给一种视觉上是动了起来
。 - 总结起来总共也只有3个要点
- 准备一个外部的容器
- 准备一个内部的圆圈
- 点击时改变外部容器的颜色和内部圆圈的定位位置顺带加上亿点点的过渡效果
- 根据不同的状态改变不同的
input
值从而实现双向绑定
<template> <div class="el-switch"> <input type="checkbox" class="el-switch__input"> <span ref="core" class="el-switch__core"> </span> </div> </template> 复制代码
- 以上就是
element
最简单的switch
结构,可以看到外部是由一个div
包裹住input
和span
- 这个
input
就是方便我们做双向绑定接收,当然要把他隐藏掉我们不希望他出现在页面中,我们只需要它的功能就好了
- 然后是接下来的
span
,在element
中这个span
就是外部的容器了,然后在这个容器中巧妙地运用了伪元素来制作一个白色的圈圈,上图是该switch
的基本样式,运用了BEM
的命名结构,如果不了解BEM
的可以看到我之前的一篇介绍,这里主要就是将中间的伪元素做了定位处理让它一开始的时候在最左边。
双向绑定🎶
- 当然现在的
switch
是没有动效的,我们要给组件传入v-model
绑定属性
<template> <l-switch v-model="value"></l-switch> </template> <script> export default { data () { return { value: false }; } } </script> 复制代码
- 父组件用
v-model
进行传值,v-model
提供了一个value
值和一个input
方法,子组件props
接收value
数值并增加一个点击事件改变父组件的input
方法即可实现双向绑定。 - 现在点击
switch
是可以让value
动态变化的,上述默认的是一个圆圈在最左边代表未选中的情况,新增一个圆圈在最右边的class
顺便改变背景颜色,接下来只需要为组件动态切换class
就可以了。
template <div class="el-switch" :class="{ 'is-checked': checked }" @click="switchValue" > <input ref="input" type="checkbox" class="el-switch__input" :value="value"> <span ref="core" class="el-switch__core"> </span> </div> script export default { props:{ value: { type: [Boolean, String, Number], default: false } }, computed: { checked() { return this.value; }, }, methods:{ switchValue() { this.handleChange(); }, handleChange() { this.$emit('input', !this.value); }, } }; 复制代码
- 至此一个最简单
switch
就做好了
更多需求🧮
- 往往我们不局限于这一简单的功能,还需要添加禁用,改变大小等功能
- 我们只需要给子组件传入不同的属性,在子组件通过判断该属性值得不同来处理逻辑即可
写在最后👋
- 总的来说
switch
组件相对于其他复杂组件比较简单,一般的处理逻辑就是父组件要想v-model
一个值到子组件,子组件就必须设置一个value
的props
,并且使用$emit
来改变父组件的input
的事件,再相应的做些处理即可。 - 对于组件库的搭建我也在慢慢的摸索,讲的都是我自己得出来的分享所以说可能对于大佬来说会比较基础,但我相信我的不断输出可以帮助到一些有疑惑的同学。
- 如果您觉得这篇文章有帮助到您的的话不妨🍉关注+点赞+收藏+评论+转发🍉支持一下哟~~😛