当前位置: 首页 > Web前端 > HTML5

第四集:从头实现一套PC端Vueui组件库(按钮组件2)

时间:2023-04-06 00:12:43 HTML5

Episode4:Realizefromscratch(buttoncomponent2)本集的定位:之前一直在忙其他的事情,现在终于有空来写这个库的文章了。所有功能实现1:给按钮添加图标按钮的图标很重要。现在一般的按键都有图案,因为符合人脑的快速思维,容易理解和记忆。//有点距离从文本计算出realyIconColor图标有一个默认颜色,但是如果按钮被禁用,图标应该变灰相应计算:{reallyIconColor(){if(this.disabled)return"#bbbbbb”;否则返回this.iconColor;}}2:图标的位置很少遇到需要上下左右布局的图标。如有必要。解决方案1:移动标记或命名的插槽标记。方案二:多写图标组件,通过判断决定显示谁3:悬停效果方案1:点击悬停出现灰色遮罩效果,按钮收缩动画&:not(.is-disabled){&:active{box-shadow:none;不透明度:0.7;变换:translateX(2px)translateY(2px)scale(0.9);}&:hover{background-color:rgba(0,0,0,0.1)}}效果图二:悬停出现金属光泽,bulingbuling,金属光泽。点击时,按钮缩小动画综上所述,金属光泽流过可能成为公共属性,所以我直接写一个公共样式“cc-bling”我的想法:尝试使用渐变背景色,然后使用background-position-x控制背景的右移。这个方案在实践中很不爽,也没有达到‘解耦’的设计原则,所以不用伪元素,用一个伪元素来添加背景色,然后把这个元素从左向右滑动,并在同时倾斜30度并带有动画。虽然多了一个元素,但它与父元素是解耦的。值得一提的是,倾斜后高度不全,简单粗暴,最好的办法就是多定位高度,这样旋转就不会出现高度不足的状态。let'gobling:Boolean,//在button.scss中添加了条纹;@at-root{@includecommonType(cc-button--);.is-bling{//这个属性名只有在悬停时才会bling&:hover{@extend.cc-bling;}}};animation.scss定义了一个从左到右的动画@keyframesbling{0%{left:0;}100%{左:300%;}}extend.scss定义特定的styles.cc-bling{&:after{content:'';位置:绝对;背景图像:线性渐变(向右,rgb(232、229、229),白色);左:0;顶部:-20px;//倾斜头部时避免尖角width:15px;高度:计算(100%+30px);//旋转时避免出现如果高度不够transform:rotate(-30deg);动画名称:bling;动画持续时间:1s;//总时间animation-iteration-count:infinite;//无限循环animation-timing-function:linear;//统一速度}}渲染是动态的,从左到右移动。4:防抖和节流介绍:这种节流和防抖都是由用户来完成的,至少按钮是这个集合的组件库使用组件来完成。使用场景:有一次,我写了一个注册登录页面。如果用户在注册时快速点击两次,虽然跳转到了登录成功页面,但是会弹出一个弹框,“手机已注册”,原来是第一次请求注册了手机,所以当然下次点击事件的请求后台返回已注册,所以这里需要这样的处理,每次点击在点击有效后n秒内无效,Preventconnectingpoints,(防止变速齿轮,让我想起了流星蝴蝶剑);我们公司在2019年举办了抢购活动,可能会出现这样的场景,用户守着抢购按钮不断点击,而我们web端每次用户点击都要询问后台‘activity开始了吗?’,在开始前为用户播放tosat(下一章会做这个组件),开始后才进入活动或订单页面。请求会很多,我告诉你:第一:为什么不用后台返回的活动开始时间来和本地事件比较??原因是用户的本地时间不是一个值得信赖的数量,通常可以作为参考,但是对于分秒必争的抢购这种事情,用户和服务器之间的时间是需要同步的。第二:为什么第一次请求后不记录时间戳,在本地用定时器模拟计时??原因是在某些浏览器环境下,当用户切出程序等操作时,会kill定时器,导致计时不准确,暂时无法解决这个问题,也无法监控,所以对于为了安全起见,分秒必争。最后,我们只能如果每次都请求,那么就需要,比如每600毫秒只允许用户点击一次有效。点击事件我们不能简单的写,必须拉出来蹂躏??.domconnectedvalueprops:{...,shake:Number,//防抖秒数throttle:Number,//油门,请输入秒数clickId:[String,Number],//相同id的组件取一组计时。}Eventclick(){//根据用户的输入,决定如何计时。//值得一提的是,如果clickId相同,我们会有一个统一的计时对,//例如:三个按钮,点击其中一个,其他的在指定时间内都无法点击letclickType,num;如果(this.throttle){clickType=1;num=this.throttle;}elseif(this.shake&&this.shake>0){c舔型=2;num=this.shake;}elseif(this.shake&&this.shake<0){clickType=3;num=this.shake*-1;}prevent(this.clickId,()=>{this.$emit("click");},num,clickType);},我在之前的工作中写了一个防抖节流功能,这次直接用了letpreventList={}constprevent=function(id,obj,time,model=1){switch(model){case1:model1(id,obj,time)中断;情况2:model2(id,obj,time)中断;case3:model3(id,obj,time)中断;default:}}//方式一不管点击多少次,每秒触发一个函数model1(id,obj,time){if(preventList['can'+id])returnobj()preventList['can'+id]=truepreventList['time'+id]=setTimeout(()=>{preventList['can'+id]=false},time)}//模式2每次Actions在延时一段时间后执行,也就是说,单击所有内容时执行一个函数。model2(id,obj,time){clearTimeout(preventList['time'+id])preventList['time'+id]=setTimeout(()=>{obj()},time)}//默认模式,模式3,第一次点击触发,之后不再触发functionmodel3(id,obj,time){if(preventList['can'+id]){clearTimeout(preventList['time'+id])}else{obj()preventList['can'+id]=true}preventList['time'+id]=setTimeout(()=>{preventList['can'+id]=false},time)}exportdefaultpreventspecificuse//后续涉及防抖和节流的事件也由本程序跟进;下一个toast包,通过封装toast使我能够巩固许多其他编写“奶酪”组件的方法。这段时间作者辞职了,专心学习源码,练习算法,重新学习js,重新学习node,重做自己的打包工具。不管怎样,我很忙。接下来的时间和精力将主要放在这套组件上。同时会发布一些算法、经验等文章。欢迎同学们互相交流,一起变得更好。github:链接说明个人网站:链接说明