VUE 给大家带来了组件化,这个功能给开发人员带来了强大并且简洁的复用组件能力。设计精美,扩展良好的组件无疑会让产品效果更加统一,带来更好的观看感觉,减少大量重复性工作,提高代码的可维护性。带着这些个目的我准备研读大厂源码,京东的 nutui 是我比较中意的一款,大量小巧漂亮的动画让我爱不释手。这篇文章就是我为大家奉上的阅读 nutui 源码心得
目前已经重复实现的组件
- picker
- actionsheet
- radio
- checkbox
- switch
- button
- buttongroup
- backtop
- toast
- cell
目录结构的划分
目前里面我特别崇拜的就是对于目录结构的划分,非常清晰。(这里主要说的是 src 目录下的代码。)
|-- src
|-- config.json // 配置文件
|-- nutui.js // 入口文件
|-- assets // 静态资源
| |-- svg
|-- locales // 多语言支持文件
| |-- index.js
| |-- lang
| |-- en-US.js
| |-- zn-CH.js
|-- mixins // 混合函数
| |-- findCptUpward
| | |-- index.js
| |-- locale
| |-- index.js
|-- packages // 主要的组件代码都放到了这里面
| |-- actionsheet
| |-- backtop
| |-- badge
| |-- button
|-- styles // 样式代码
| |-- index.scss
| |-- variable.scss // 定义的全局默认样式文件
| |-- animation // 全部都是动画样式
| |-- mixins // 使用了 sass 的 mixins 的样式
|-- utils // 工具类
|-- date.js
注意源代码里面要比这些文件多的多,我为了让文章看起来简短所以进行了删减
一目了然的目录结构,直接建立起了我宏观上对项目的了解,很舒服
picker 详解
就目前来说我看到的 picker 插件效果最好的就专属 nutui 的了(如果你看到过比这更好地欢迎评论留言),他好在了加入了一个滚轮效果不是一个平面的,感觉非常细节。
如何实现的 3d 滚轮效果?
主要用到了俩个 CSS3 的新特性 transform 中的 rotate3d, translate3d。
属性名 | 作用 |
---|---|
rotate3d(x,y,z,angle) | 定义 3D 旋转。 |
translate3d(x,y,z) | 定义 3D 转换。 |
只使用 rotate3d 不配置 translate3d, 元素会围绕着自己的中心点进行旋转。所以需要配合 translate3d 修改元素 z 轴的位置。 z 轴设置的值相当于旋转的时候的半径。了解了这些,只需要给一组元素设置相同 z 轴的值,设置不同的围绕 x 轴旋转的角度就实现了一个静态滚轮的效果。监听用户的 touchstart, touchmove, touchend 事件进行相关的计算即可。
比较经典的部分我觉得是用到了 CSS3 的 transition 过度效果。判断用户是手指滑动状态就去掉这个属性,否则的话就加入这个属性进行一个动画的过渡效果。
这里面需要注意的地方有俩点:
- 是在某些浏览器中用户触摸的时候会导致整个页面进行滚动,体验效果非常插件。 解决方式也很简单在 touchstart 事件中取消事件的默认动作就可以了。代码如下
event.preventDefault()
- 3d 效果不理想,因为少了一个 3d 属性
transform-style: preserve-3d
不了解的可以看这篇文章 http://blog.sina.com.cn/s/blog_65c2ec5e0101fm8u.html
radio, checkbox, button 样式的重置
radio, checkbox
appearance:button;
-moz-appearance:button; /* Firefox */
-webkit-appearance:button; /* Safari 和 Chrome */
上面的是去掉浏览器自带样式的核心样式,唯一问题是存在兼容问题需要IE9+。不过这里是手机端 UI 库,就无需担心了。
input[type=checkbox] {
appearance:none;
-moz-appearance:none; /* Firefox */
-webkit-appearance:none; /* Safari 和 Chrome */
width: 18px;
height: 18px;
border-radius: 6px;
background: #f0250f;
outline: 0;
}
input[type=checkbox]:checked {
background-image: url("data:image/svg+xml, %3Csvg width='20' height='15' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 8l2.5-2.5 5 4.5 10-9.5L20 3 8 15H7z' fill='%23FFFFFF' fill-rule='evenodd'/%3E%3C/svg%3E");
background-color: #f0250f;
background-repeat: no-repeat;
background-position: center;
border-color: #f0250f;
background-size: 60%;
box-shadow: 0 4px 6px 0 rgba(240,37,15,0.15);
}
以上代码就实现了京东无动画版的 checkbox, 修改一下 border 的圆角就实现了 radio。上面的 outline 样式很重要,input 标签会有焦点事件,焦点会给元素生成一个轮廓。所以需要重置轮廓属性
有同学可能要说了,我最想要的是选中时放大的渐变消失效果,这个效果让我的组件贼上档次。其实这个效果很简单,他用了元素的伪元素当选中的时候执行一个大小变大,透明度消失的动画效果。为了保持文章的可读性,这里就不贴代码了。欢迎大家阅读 nutui 的源码。
button
button 的样式重置我本以为会跟 radio, checkbox 会差不多,但是我发现我错了。button 你只需要将 border 去掉你就发现他看其实没有多高大上了。而且设置了 appearance 也没用。这里我蛮想知道官方的这套默认的 button 样式是如何设置的,因为他除了样式丑一点,其他的真的是非常棒的。它本身实现的那种单机效果的交互操作是非常完美的,针对这一点 nutui 框架的 button 并不算出众。
toast 与 VUE 的 extend 的结合感悟
写这个其实我是有点迷糊的,并不是我不理解,也不是他的设计多么复杂。而是因为好像就应该这么设计,一个就应该这么设计的东西写他干嘛呢,这就是我迷糊的地方。可是反过来说你如果不知道 VUE 的 extend 方法我相信你也依然能够实现一样功能。这里就引发了我的思考:多学不如专精
意思就是你掌握了十种技能,可是你却不会组合他就只是纯粹的十种技能。另一个人可能只会八种技能,可是他专精其中的四种技能。这四种技能他能够通过俩俩组合,三三组合衍生出来 12 种可能性。这种人写的代码读起来行云流水,对其了解显浅易懂。这种人难道不更应该值得钦佩么?
强调一点,这个观点并不是让你故步自封,而且我也支持技多不压身的观点,但是一定要有自己的核心优势
总结
上面几个是对我感触最深的,像没有说的 toggle 他用到了 VUE 的 .sync 使得父子组件之间的数据双向绑定的优雅写法。做按钮组的时候 nth-child,nth-last-child 的运用都是很不错的思考。这些个东西你去菜鸟教程,w3c 上是找不到的。他们更多的像是 API 查询文档。而对于这些平常不常用的属性,方法运用得当总会给人一种惊艳的感觉