本集定位:
以前一直在忙别的事情, 如今终于闲下来, 好好把这个库的文章写一下
本篇目的是承接上文, 把button组件的功能所有实现css
1: 为button添加icon
按钮的icon很重要, 如今通常的按钮都带个图案,由于这样符合人脑的快捷思惟, 方便理解与记忆.vue
<button class="cc-button" @touchstart='touchstart($event)' :class="[ sizeType, type ? 'cc-button--' + type : '', { 'is-left':left, 'is-right':right, 'is-centre':centre, 'is-disabled':disabled, }]" :type="nativeType" @click="click"> <!-- 图标按钮 --> <ccIcon v-if="icon" // 有没有 :name='icon' // 有什么样的 :color="realyIconColor" // 什么颜色的 style="margin-right:2px" /> // 与文字有点距离 <slot /> </button>
计算realyIconColor
icon有默认的颜色, 可是若是按钮式禁用状态, 那么icon也要相应的置灰node
computed: { realyIconColor() { if (this.disabled) return "#bbbbbb"; else return this.iconColor; } }
2: icon的位置
不多遇到须要上下左右布局的icon, 若是须要的话.
方案一: 移动<slot>标签, 或是具名slot标签
方案二: 多写几个icon组件, 经过判断决定显示谁git
3: hover效果
方案一:github
&:not(.is-disabled) { &:active { box-shadow: none; opacity: 0.7; transform: translateX(2px) translateY(2px) scale(0.9); } &:hover { background-color:rgba(0,0,0,0.1) } }
效果图
方案二:web
综上分析, 金属光泽流过可能成为一个公用属性, 那么我直接写一个公共的样式吧 "cc-bling"
个人思路:算法
let'go浏览器
<button class="cc-button" :class="[ { 'is-bling':bling, // 加了一个接受 是否金属光泽的属性 'is-left':left, 'is-right':right, 'is-centre':centre, 'is-disabled':disabled, }]" </button> bling:Boolean, // 条纹
在button.scss;里面添加服务器
@at-root { @include commonType(cc-button--); .is-bling { //此属性名在hover的时候才进行bling操做 &:hover { @extend .cc-bling; } } };
animation.scss
定义一个从左至右的动画dom
@keyframes bling{ 0% { left: 0; } 100% { left: 300%; } }
extend.scss
定义具体的样式把
.cc-bling { &:after { content: ''; position: absolute; background-image: linear-gradient(to right, rgb(232, 229, 229), white); left: 0; top: -20px; // 避免倾斜的时候头部漏出尖角 width: 15px; height: calc(100% + 30px); // 避免旋转时候出现高度不够的状况 transform: rotate(-30deg); animation-name: bling; animation-duration: 1s; // 总用时 animation-iteration-count: infinite; // 无限循环 animation-timing-function: linear; // 匀速 } }
效果图, 是动态的, 从左至右划过.
4: 防抖与节流
介绍: 这种节流与防抖都是用户本身作的, 至少按钮这种东西本套组件库就是要组件来作.
使用场景:
我来讲一下:
第一: 为何不使用后台返回的活动开始时间与本地的事件进行比对??
缘由是用户的本地时间并非一个值得信赖的量, 平时能够做为一个参考, 可是像抢购这种分秒必争的事情, 就要让用户与服务器时间同步起来了.
第二: 为何不在第一次请求以后把时间戳记录下来, 本地用计时器模拟计时??
缘由是某些浏览器环境下, 用户切出程序之类的一些操做, 他会杀掉计时器, 致使计时不许, 而这种问题暂时没法解决, 也监控不到, 因此为了分秒必争保险起见.
最后只能是每次都请求一下, 那就须要, 好比说 每600毫秒内, 只让用户的点击有效一次.
咱们就不能单纯的写click事件了,要抽离出来进行蹂躏☺️.
dom
<button class="cc-button" @click="click"> </button>
接值
props: { ..., shake: Number, // 防抖的秒数 throttle: Number, // 节流, 请输入秒数 clickId: [String, Number], // 相同id的组件走一套计时. }
事件
click() { // 根据用户的输入, 来决定怎么计时. // 值得一提的是, clickId 相同的话咱们是统一计时的, // 好比说: 三个按钮, 点了其中一个, 其余的几个在规定时间内,都会不可点击 let clickType, num; if (this.throttle) { clickType = 1; num = this.throttle; } else if (this.shake && this.shake > 0) { clickType = 2; num = this.shake; } else if (this.shake && this.shake < 0) { clickType = 3; num = this.shake * -1; } prevent( this.clickId, () => { this.$emit("click"); }, num, clickType ); },
在以前的工做中本身写过一个防抖与节流的函数, 此次就直接拿来用了
let preventList = {} const prevent = function(id, obj, time, model = 1) { switch (model) { case 1: model1(id, obj, time) break; case 2: model2(id, obj, time) break; case 3: model3(id, obj, time) break; default: } } // 模式1 无论点多少下每隔time秒,触发一次 function model1(id, obj, time) { if (preventList['can' + id]) return obj() preventList['can' + id] = true preventList['time' + id] = setTimeout(() => { preventList['can' + id] = false }, time) } // 模式2 每次动做都有time的延时再执行,也就是全部点击完事的时候执行一个 function model2(id, obj, time) { clearTimeout(preventList['time' + id]) preventList['time' + id] = setTimeout(() => { obj() }, time) } // 默认的模式, 模式3, 第一下点击触发, 以后时间内不触发 function model3(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) } export default prevent
具体的使用
//后续涉及到防抖与节流的事件也都是走的这套程序;
下一篇
end
这段时间做者辞职, 专心学源码, 练习算法, 重学js, 重学node,重作本身的打包工具, 反正挺忙的,接下来的时间与精力主要放到这套组件上 同时也会出一些算法啊, 心得之类的文章, 欢迎同窗们一块儿交流, 一块儿变得更优秀.