cube-ui 是滴滴去年末开源的一款基于 Vue.js 2.0 的移动端组件库,主要核心目标是作到体验极致、灵活性强、易扩展以及提供良好的周边生态—后编译。css
自 17 年 11 月开源至今已有 5 个月,在这个过程当中 cube-ui 受到了很多的关注,同时从社区中也收到了不少很好的反馈和建议。咱们也一直在迭代更新,从最初的 1.0 版本到最近发布的 1.7 的版本,除了对原有组件作一些加强优化,咱们也提供了不少新的组件。此外,周边后编译技术生态也作了不少优化,知足于更多场景需求,官网也作了一次升级。 接下来就重点介绍下 cube-ui 在这个过程当中的有哪些成果以及一些设计细节。前端
cube-ui 的组件数已经从最初的 14 个增加了 28 个,足足翻了一倍,已有的组件生态: vue
除了上述的组件外,cube-ui 还对外暴露了三个模块: ● style ● create-api ● better-scrollwebpack
并且 cube-ui 也已经支持了以下特性: ● 自定义主题 ● rem 布局 ● SSR 支持web
此外,cube-ui 的周边生态也有了进一步丰富: ● vue-cli 脚手架模板 cube-template ● 快速上手教程 cube-application-guide ● 后编译 webpack 插件 webpack-post-compile-plugin ● 按需引用 webpack 插件 webpack-transform-modules-plugin,依赖 babel 插件 babel-plugin-transform-modulesvue-cli
针对于上边所介绍的关键成果,咱们来聊聊具体设计上的细节。json
● 滚动 & Picker 类组件 在移动端,因为手机尺寸以及交互特性,咱们须要处理不少滚动类需求:下拉刷新、上拉更多、轮播等以及 Picker 选择等场景。cube-ui 底层滚动类组件以及 Picker 类依赖于咱们团队的移动端利器 better-scroll 实现,基于其出色的体验进而保证了咱们上层封装的滚动类、Picker 类组件的出色的交互体验。 ● 弹出层类组件 在实际开发中咱们会遇到不少弹出层类组件,由于咱们设计了一个基础弹出层组件 Popup,它主要解决移动端最为常见的居中(Tip:文本换行位置也很重要哦)、置底以及是否有蒙层效果,借助于它来实现绝大多数的弹出层组件。 另外一个常见的痛点就是因为弹出类组件每每是全屏的状态,若是咱们按照 Vue 推荐的声明式的语法在子组件里使用弹出层组件,因为嵌套层级问题,很容易受到父级元素的样式影响。为此咱们单独开发了 create-api 模块,经过 API 的形式将实例化的弹出层组件动态挂载到 Body 元素下,所以摆脱了父级元素样式的影响,同时会随着使用它的组件的销毁而自动销毁,且为了下降开销成本,根据须要有些弹出层类组件都被设计成了单例模式。它是一个很通用的能力,咱们把这样的一个便捷的 API 对外暴露出去,开发者也能够根据实际场景将本身开发的组件经过 createAPI 进行注册,进而也可解决上述痛点。 ● 表单类组件 表单类需求每每特应性比较大,交互也很难作到统一,可是仍然能够有主流的表单设计交互,在 cube-ui 中表单能够设置 layout 来决定样式甚至是交互,知足平常场景需求。在表单设计中有两个很重要的组件:Validator 和 Form。Validator 成为独立的组件主要基于校验场景不肯定性,同时还须要知足各类形式的校验,因此 Validator 就只作了两件核心的事情,对数据源进行校验以及对应的错误信息的展现。考虑到开发者开发表单的便利性,咱们参考 vue-form-generator 的设计,把表单设计成了根据 Schema 配置自动生成表单,这样开发表单的成本就下降了不少;同时为了兼顾灵活性,也支持经过插槽来自定义开发者须要的结构交互。 后编译api
后编译是 cube-ui 的一个重要的生态,借助于后编译,整个的 web 应用的开发均可以直接基于 ES2015+ 进行开发,而项目依赖的一些 NPM 包也是能够直接使用 ES2015+ 进行开发,而且无需编译可直接发布到 NPM 平台上(也能够是本身 NPM 私服)。这样,这些组件库或者工具就能够有更多的想象空间、能够作更多有意思的事情。 cube-ui 支持的两个特性自定义主题以及 rem 布局都是基于咱们主推的后编译技术实现。 接下来一块儿来看下这两个特性实现的细节。 自定义主题 通常而言,组件库都是有默认主题的,而每每还会搭配有多套主题(PC 类组件库比较常见)。如今借助于 CSS 预处理器,咱们能够给组件定义一些变量(通常都是颜色值),而后在组件对应的样式中使用。 对于自定义主题这种需求,主流的作法有:样式覆盖和修改变量。babel
若是咱们想要把项目中使用的按钮的背景色该换掉,那么能够修改 theme.styl 的文件内容: // 若是你须要使用 cube-ui 自带的颜色值 须要 require 进来app
@require "~cube-ui/src/common/stylus/var/color.styl"
// button
$btn-bgc := #409eff
$btn-bdc := #409eff
$btn-active-bgc := #66b1ff
$btn-active-bdc := #66b1ff
复制代码
配合咱们的 webpack 配置,刷新后的样子为:
其实对于主题定制,还能够更进一步,将来 cube-ui 会考虑借助于 CSS 自身支持的变量(自定义属性)达到主题定制的目的,例如能够把处理器变量改成原生的变量,编译的话能够经过 post-css-variables 插件把默认变量值作替换,能够实现和现有编译后功能相同的效果,同时在后编译的状况下不失原生 CSS 变量的动态优点。这样,不只能够作到主题定制,也能够作到多主题的自由切换,由于 CSS 原生变量能够直接修改变量值而不须要经过事先写死而后切换 class 覆盖的方式作多主题切换。
在移动端仍是有不少设计师、产品或者开发者偏心用缩放来达到不一样尺寸屏幕适配目的,而缩放的实现通常都是采用 rem 进行布局,业内比较出名的方案就是手机淘宝前端团队开源的 lib-flexible。 如今实际上是不推荐使用 rem 进行布局的,若是真的要缩放的效果,能够考虑 vw vh 等 CSS 单位来实现。 rem 布局有两个核心的点:
能够看出总体的效果,当尺寸较小时,Button 和 Toast 都是比较小的,而当尺寸比较大时,相对应的都会更大,达到了缩放的目的。
这里上层扩展主要是指基于组件库进行二次封装,例如在滴滴内部,咱们的不少业务组件库就是在开源的 cube-ui 组件库之上作加强而来的。 这个能力是很是重要的,由于移动端组件库和 PC 组件库最大的区别是移动端可能是 to C 的业务场景,不一样的业务场景下的设计是不同的,因此 cube-ui 专一于通用组件和基础能力的建设,并不会在布局和业务组件方面大作文章;而 PC 组件库通常都是用于 to B 的场景,如内部 MIS 类的系统,对于设计的要求并无特别苛刻,因此基础的样式,组件都是能够统一的。所以 cube-ui 的定位并非要提供一个“大而全”的组件库,而是提供了二次扩展的能力,目标是任何移动端的业务场景均可以基于 cube-ui 提供的能力作二次扩展。 以咱们的快速上手教程为例,咱们要开发以下图的弹窗组件。
<template>
<div class="subscribe-dialog-view">
<cube-popup ref="popup" @mask-click="hide">
<div class="subscribe-dialog-wrapper">
<span class="close" @click="hide"><i class="cubeic-close"></i></span>
<div class="title">开启推送通知</div>
<img src="./subscribe.png">
<p class="desc">第一时间获取最新鲜出炉的新闻攻略、赛事咨询、数据专题、精彩视频</p>
<cube-button class="button" @click="start">如今开启</cube-button>
</div>
</cube-popup>
</div>
</template>
<script>
export default {
name: 'subscribe-dialog',
methods: {
show () {
this.$refs.popup.show()
this.$emit('show')
},
hide () {
this.$refs.popup.hide()
this.$emit('hide')
},
// ...
}
}
</script>
复制代码
接着使用 createAPI 模块把它变成一个 API 式的组件:
import SubscribeDialog from './components/subscribe-dialog/subscribe-dialog'
createAPI(Vue, SubscribeDialog, [], true)
复制代码
而后调用它就很是方便了:
this.subscribeDialog = this.$createSubscribeDialog()
this.subscribeDialog.show()
复制代码
周边生态 周边生态有两个核心:后编译 + 按需引入。为此,咱们开发了两个 webpack 的插件来帮助咱们更好的去使用、开发。 ● 后编译 webpack 插件 webpack-post-compile-plugin ● 按需引用 webpack 插件 webpack-transform-modules-plugin webpack-post-compile-plugin 这个插件主要是读取应用 package.json 中的 compileDependencies 字段的值(用于指定应用须要后编译哪些依赖包),并且还能解决嵌套后编译包的问题,由于开发者只须要关注本身依赖须要后编译的包,而不须要关注依赖的依赖包,这样就能构成一条生态链。
为何不是一个 NPM 包本身声明需不须要后编译,而是由使用者去声明? 主要考虑整个 NPM 生态,例如 lodash-es 并不在咱们控制范围以内,为了更好的使用整个 NPM 生态圈的包,咱们决定由使用者去声明须要后编译的 NPM 包。 webpack-transform-modules-plugin 这个插件主要解决更方便、友好地使用按需引入的问题,为了更好的统一应用使用后编译和不使用的状况,咱们在本来 babel-transform-imports 的基础上作了升级优化产出了 babel-plugin-transform-modules 插件,可是和后编译的场景相似,这个是不能解决后编译场景下 NPM 包嵌套按需引入的问题的,为此才开发了 webpack-transform-modules-plugin 这个插件,和 compileDependencies 字段相似,咱们新增了 transformModules 字段来声明按需引入的 NPM 包的的转换规则,例如:
"transformModules": {
"cube-ui": {
"transform": "cube-ui/src/modules/${member}",
"kebabCase": true
}
}
复制代码
固然在后编译的场景下,咱们借助于 webpack 4 Tree shaking 中新增的 side-effects 也能够达到目的,这个是将来咱们去优化的方向。
脚手架 & 教程 任何的技术都是有成本的,咱们新增了 webpack 插件,也有一些须要配合的改动,因此为了下降开发者成本,咱们提供了适用于 vue-cli 脚手架的模板 cube-template,固然对应的也会新增一些配置项,感兴趣的能够了解下cube-template wiki。 同时为了初次使用 cube-ui 的开发者快速上手,咱们还有一个简单的上手教程 cube-application-guide。
展望 cube-ui 目前还处于初步的阶段,还缺乏不少组件,可是咱们一直在努力,但愿在很快的将来能够提供更多更好用的组件。不只如此,咱们但愿的是除去组件库自己,额外还会丰富周边的整个生态建设,给开发者一个良好的生态环境,进一步提高开发体验,提高应用性能等。固然,咱们也但愿社区的小伙伴也能参与进来,一块共同建设,共同进步。 将来 cube-ui 会朝着以下方面继续前行: ● 丰富组件 ● 组件优化 ● 文档优化 ● 示例优化 ● 周边建设 但愿感兴趣的同窗能够一块儿共建或者加入咱们团队,一块儿玩技术!