阅读 789

来迎接一款让你心动的UI框架

作者|冰山工作室--沙翼

今天要为大家安利的是冰山工作室出即将推出的前端框架CMUI,本文会抽取框架的一部分进行介绍(布局,列表,动态辅助),让你了解一下这款框架的强大与便捷,但这只是框架的冰山一角。如果你想了解更加详细的信息,可以破解本文底部的二维码,加入我们的群聊来获取。

起源

2011左右的时候我开始着手研究响应式网页设计,并基于less语言设计了一套CSS布局框架,起初的设计包括12列,15列,16列三种结构,最终确定了12+15差值双列的结构,并考虑申请相应的专利,意外的是几个月之后推特发布了前端界家喻户晓的bootstrap框架。后来我进入一家建站公司并基于这套样式框架开发了一个高速建站系统feebless(一款Windows下的应用程序),为了防止以后有新的想法做出来之后没有推广而落后于人的情况发生,还在系统上线后对响应式结构申请了对应专利保护(点击了解一下),这是现在要为大家介绍的CMUI最早的雏形,值得庆幸的是我在准备这篇文章的时候竟然翻到了9年前的手稿,当你了解CMUI之后再后头看这些手稿的时候你会发现很多当年残留的影子或者一些思想雏形,包括组件化,异步组件,高速布局,组合,继承等。

14年左右的时候我基于模板引擎封装了一套UI系统,取名为CMUI,后用VUE重新封装为组件库用于我们的项目,在我们的实际使用中发现这套结构的开发效率非常之高,并且能够精准匹配设计稿,现在我们决定将其重新封装并开源,希望更多的开发者能够参与其中。

九年前的手稿

2011年双列差值网格系统手稿

重要说明

真假美猴王

CMUI是框架的简称,GitHub上的CMUI并不是本次介绍的框架。

专利保护

CMUI以MIT协议进行开源,你可以随意使用到你的项目中,但是其内部的部分结构(如布局系统,组合样式)依旧受专利保护,如果你需要应用到你的框架并再次发布,请提前联系我们,以免引起对应法律纠纷。

PC端还是移动端

CMUI主要用于移动端,但是样式部分完全适用于PC端,组件方面PC端使用的组件目前提供的还不全面。

为什么要自己写一套组件库?

虽然目前市面上有非常多的组件库,其中也有一很多非常优秀的代表,但是存在一些非技术性的问题

糟糕的C端应对方案

你所知的大部分框架大量保留了bootstrap的思想,这一点从栅格系统和按钮及表单的描述就能看出来,我始终不认为用success表示绿色,用primary代表主色是一个优秀的方案,这种结构的优势在于开发没有设计师参与的项目时(如中台系统)可以达到风格的高度统一并且实现主题变色,但是如果针对C端开发,设计稿千变万化,尤其是你的设计团队并不十分严格的情况下就会变得非常尴尬。

完善不代表适用

提供了完善的组件系统,小到一个按钮,大到完善的表单,首先要承认这是非常优秀的设计,但并不是最实用的。因为你可能只需要用到一种样式上的展示,却要引入一个完整的组件,当然你可以只引入它的样式文件,但是如果你这么做,你就需要记忆大量的class命名,并且在很多情况下根据你的需要去重写默认的样式。比如下面这样

  1. <button type="button" class="xx-button xx-button--text" style="float: right;padding: 3px 0px;"><span>操作按钮</span></button>
    复制代码

我一眼就知道你是谁

如果你使用了一套UI框架,在你不进行海量修改的的情况下几乎一眼就能看出是哪个框架搭建的,就像所有使用bootstrap搭建的网站几乎都长得差不多。

API是个头痛的问题

记忆API和使用方式是一件非常麻烦的事情,当你使用一套UI框架进行页面开发的时候,脱离了官网的DEMO和API文档,你可能寸步难行,当你想实现一个类似的效果的时候,你也许会经常把代码来回复制,以防止写错。

你只是个使用者而非创造者

如果你使用了一款UI框架,而在这套框架里没有提供你所需的UI功能,这就变的非常尴尬,如果你再次封装,可能你的结构可能和原有的结构完全不搭,甚至完全没有关系,换句话讲,你只是一款工具的使用者,而非基于一款工具的创造者。

抛砖引玉的开始

简介

现在要为大家介绍的框架名为CMUI,这只是一个简称,一共包括三个部分:样式库,组件库,方法库,每个部分都可以独立使用,你甚至可以直接把它直接插入你的项目,和你现在所使用的UI库一起使用。

**样式库:**全称cyan,就是赤橙黄绿青蓝紫中你唯一不会的那个英文单词(这一点非常重要)使用sass对css进行了重新的抽取和封装,基于这套样式库你几乎可以在不书写额外的CSS的情况下,仅凭借样式组合完成页面的拆分。更重要的是所有的命名都简单到令人发指,以至于在你用过一次之后再也不需要去看API文档。

**组件库:**得益于样式库提供了强大的VIEW层展示,因此我们提供的组件也相对较少,仅在单凭样式无法解决的问题上提供对应的组件,其目的也是为了降低开发者的门槛

**方法库:**这里对常用的WEB功能提供了对应的方法,用于减少你的代码量

无图无真相,秀个logo

Cyan不让你思考,不让你写错

我们在开发的过程中为模块起名字是一个非常痛苦而费脑的过程。主要包括以下几个方面:

  • 命名中存在不常用的英文单词,不易理解和阅读(你一定用过百度翻译😁)
  • 模块在经过多次需求修改后名称已经和实际用途不相符
  • 两个样式完全相同的模块使用不同的命名,多次编写样式,比如一个品牌列表和一个用户列表在样式上完全相同,鬼知道你的产品和设计什么时候会修改,那么你该如何复用?
  • 同一个页面存在两个类似的模块时命名混乱,如porductTop productBottom productRecommend productNew
  • 为准确描述而使用过长的名称
  • ...

为了解决这一问题,Cyan在命名上做了大量的调研和优化,我们希望我们用到的单词所有人都能一次理解,所有人都能一次写对,先来看一下样式库默认的的所有关键字。

颜色类:red orange yellow green cyan blue purple coffee
调整类:margin padding top left bottom center full
边框类:border item radius round light shadow pill
尺寸类:big small block
元素类:img form swich btn reverse badge
布局类:flex ratio list item img scroll container
辅助类:disabled square float pos clearfix overflow delete justify limit fixed
复制代码

你看到的这些词就是CMUI样式库整合后的的全部class名称,其中颜色类和尺寸类是用户自定义的,你可能很难想象紧靠这些简单的单词就能完成一个页面的拆分,但事实确实如此。

随手写个京东

我们先用Cyan的结构来还原一个京东首页商品列表作为一个小小的DEMO。

<div class="list list-col2 border">
    <div class="list-item">
        <div class="ratio-container img-container">
            <img src="图片地址" alt="">
        </div>
        <span class=" reverse red badge square pos-a top10 left10"></span>
        <div class="padding10">
            <span class="text-limit2 fs-13">日本进口FaSoLa 瓷砖贴纸对角贴 美缝地板贴防水耐磨地贴客厅装饰墙贴自粘 波西风情(12个/张) 大</span>
            <div class="flex-container margint10">
                <span class="text-delete text-light marginr10">999</span>
                <span class="text-red fs-13 right">222</span>
              	<span class="badge reverse">找相似</span>
            </div>
        </div>
    </div>
    <div class="list-item">
        <!--此处代码和上面的相同-->
    </div>
</div>
复制代码

输出效果

描述型样式库

在这案例中你可以看到我们没有使用任何额外的CSS就完成了样式布局。使用Cyan样式库的一个特点就是你不需要关心你做的是什么,你只需要将你看到的设计稿用class组合描述出来就可以。从另一个角度来说,当你看到HTML结构的时候,你不需要看页面就知道最终的效果是什么样子,因此我们将Cyan称为描述型样式库。

业务逻辑拓展库

虽然我认为起名字是个非常麻烦的事情,但是如果你觉得使用class进行描述不是你的风格,一定要使用标识业务的命名,你还可以直接引用我们的拓展库。

<div class="productList">
    <div class="productItem">
        <div class="productImg">
            <img src="" alt="">
        </div>
        <span class="productName"></span>
        <div class="productInfo">
            <span class="info_oldPrice"></span>      
            <span class="info_newPrice"></span>
            <span class="p_find"></span>
        </div>
    </div>
</div>
复制代码
@import cyan/extend;
.productList{
    @extend list;
    .productItem{@extend list-item;}
    .productImg{ @extend ratio-container img-container;}
    .productName{@extend text-limit2 fs-13;}
    .productInfo{
        @extend flex-container margint10;
        .info_oldPrice{@extend text-delete text-light marginl10}
        .info_newPrice{@extend text-red fs-13 right}
        .p_find{@extend badge reverse}
    }
}
复制代码

真正的开篇

六大布局容器

Cyan提供了6个布局容器,几乎可以满足你所有的布局需求,一起来看一下

网格容器

类似于bootstrap的栅格系统,同时提供12或15两种阵列方式。

盒容器

与网格容器唯一的区别是没有间距。

网格容器和盒容器是由于历史原因以及今后要在PC端实现实现响应式而保留下来的,在实际的移动端开发中并不常用,当然如果你习惯了使用栅格系统也完全可以使用。

比例容器

在任何宽度内创建任何比例的区域,通常用于制作头像或商品列表,比如上面的案例,视窗宽度不固定,两列之间的的间距甚至列数设计随时有可能调整,使用的图片不一定是正方形,还要保证图片以某种比例(通常是一比一)进行展现,此时你会用到比例容器。

为了方便你理解,我们先用网格系统来创建列,后面会有更好的方式

<div class="container">
  <div class="row">
    <div class="span6 margint20"> 先不用关心这个margint20是干什么用的,虽然你能猜出来
      <div class="ratio-container">此处添加比例容器,内部节点默认会以1:1进行展示
        <img src=""/>
      </div>
    </div>
  </div>
</div>
复制代码

输出效果

你可以看到在无论可视区宽度是多少,图片均已固定比例展示,如果你需要其他的比例尺寸,直接在后面标识出来就可以了

<div class="ratio-container" ratio="2:3">
  这里的节点会以2:3的比例展示
</div>
复制代码

比例容器的作用不光如此,他还可以实现非常多的效果,比如下面这样,你能想到怎么做吗?我们后面再说

图片容器

直接将图片放入比例容器会产生一个问题,就是如果使用的图片不是对应比例的,会被拉伸变形,这一定不是你想要的,因此我们需要图片容器。只需要添加几个额外的class他就能支持非常多的效果,可以满足你的各种需要,

<div class="img-container">
  <img src=""/> 图片默认显示在容器居中的位置
</div>
<div class="img-container round">
  <img src=""/> 图片将以圆形显示
</div>
复制代码

为了方便你理解案例中使用了不同数字来标识位置,选项中蓝色的字就是你可以额外添加的class,而且可以随意组合,你能用到的所有图片展示效果都可以组装出来。

滚动容器

想创建一个如丝般顺滑的滚动展示效果何须那么麻烦,一个class搞定

<div class="scroll-container">默认是横向滚动
  <img src=""/>
  <img src=""/>
  <img src=""/>
	...
</div>

<div class="scroll-container-y">如果是纵向的滚动就加个-y
  ...
</div>
复制代码

效果

flex容器

我想你一定记不住CSS3中flex的具体用法,因此我们对flex进行了细致的封装,形成了这个最为强大的布局容器,他的功能可以说是丧心病狂,但是用法之简单却令人发指。

<div class="flex-container">
  这里填写内部结构,横向排列
</div>
<div class="flex-container-col">
  这里填写内部结构,纵向排列
</div>
复制代码

WTF?这就完了,嗯,完了,你没看错,就是这么简单。下面来看看它都能完成那些操作

你可以额外添加下面4种类别,一共10个辅助class,他可以满足你的任何需求,如果直接添加到外层节点可以对所有子节点统一控制,如果添加到子节点上,可以额外的对子节点进行单独的控制。

间隔类型选择 顺序翻转 位置控制 子节点横纵向填满
round/between reverse top/left/right/bottom/center vfull/hfull

我想这些API的封装已经简单到让我懒得去解释其作用了。妈妈再也不用担心我记不住flex的用法了。

总结

容器类能够实现的布局非常强大,而且使用起来非常简单,所有的关键字class都是非常常用的,更重要的是他们还可以随意组合,来实现更加复杂的布局,从你用上Cyan开始,你已经是一个创造者,限制你的不是框架功能,而是你的想象力。

列表

容器类的功能已经足够强大,但是仍有很大的改进空间。比如我们要实现一个5列的导航,可以使用下面三种方式。

方式一:网格容器或盒容器
<div class="container">
  <div class="row">
    <div class="col3 text-center" v-for="i in  5">
    	<img src="" alt=""><span>导航{{i}}</span>
    </div>
  </div>
</div>
方式二:flex容器
<div class="flex-container">
  <div class="flex1 text-center" v-for="i in  5">
  	<img src="" alt=""><span>导航{{i}}</span>
  </div>
</div>
方式三:滚动容器
<div class="scroll-container">
  <div v-for="i in  5" style="width:20%" class="text-center">
  	<img src="" alt=""><span>导航{{i}}</span>
  </div>
</div>
复制代码

但是如果有两排或者更多排呢?网格容器可以无修改继续使用,flex容器需要添加换行属性,并设置每一个的宽度,滚动容器已经不能使用了(除非放置两个滚动容器)

<div class="flex-container">
  <div class="text-center wrap" v-for="i in  10" style="width:20%">
  	<img src="" alt=""><span>导航{{i}}</span>
  </div>
</div>
复制代码

如果此时需要添加分割线呢?你当然可以为使用我们的边框类为节点添加一个border的class,但是这会导致相邻的边框加粗。虽然通过添加我们提供的辅助类完全可以处理这些问题,但是都显得麻烦,因此我们需要list类

基础list

list类可以随意控制列数以及边框的显示,每一列所占的宽度均相等,并且自动在每行的第一个进行浮动的清除,以保证即使在每一项高度不同的时候也能很好的展示。与此同时你可以在将list和前面讲过的布局类容器随意组合,在此基础上没有什么布局结构能够难得住你了。

<div class="list list-col5 border">
  <div class="list-item padding20 text-center" v-for="i in  10">
    <img src="" alt=""><span>导航{{i}}</span>
  </div>
</div>
复制代码

组件list

现在考虑下面几种更复杂的情况:

  • list的每一项宽度不同
  • 每一项之间有间隔
  • 边框颜色不同意,甚至有的有,有的没有
  • list需要分组,形成类似通讯录的页面效果

前三种情况通过list 和flex-container的组合可以解决,但是需要多写一层DIV,第四种情况需要单独开发虽然并不复杂。此时我们可以开始使用我们的组件系统了。

<cmui-list :col='[2,7,5]' :space='20' border='#ab2c4f'>三列2:7:5展示,间距20,边框颜色#ab2c4f
	<cmui-list-item>
    ...
  </cmui-list-item>
</cmui-list>
复制代码

通过组件我们可以随意设置每一列所占的比例,边框,间距,在item上我们同样可以对这些属性进行微调,如果边框贴合,会自动合并,而且可以无限嵌套,如此一来所有的行列结构就都能实现,通常这种结构会在广告位的展示上使用,

虚拟list

现在常规的布局已经没有搞不定的了,我们再把问题升级一下,如果一个列表有1万条数据怎么处理,比如对搜索结果不断分页加载,大量的数据会产生两个问题:

  1. 首次渲染效率降低
  2. 随着数据量不断增大页面越来越卡

此时你需要虚拟列表,它可以将数据保存到缓存中,并且仅对屏幕可视区内进行渲染,即使同时加载数万条数据依旧非常流畅和高效。

<cmui-virtual-list height="500px" :data="Listdata" v-slot="slotProps">
    <p>{{slotProps.item.value}}</p>
</cmui-virtual-list>
复制代码

从案例中你可以看到虽然我们要渲染一万条数据,但实际上仅有很少的节点在不断更新。

动态辅助

布局搞定了,但只是结构相似,想要完美匹配设计稿还需要微调,padding/margin /top/bottom/left/right这些值在不同的设计稿中变数非常大,好在移动端屏幕尺寸较小,只需要将所有可能的值提前在CSS中定义好就可以了。padding12表示12像素响应式填充,paddingh12表示只有水平方向填充。

开玩笑的,CMUI会自动解析你的html结构,并监听符合格式的class定义,当你为一个DOM节点添加paddingXXX的class的时候,会自动在动态样式表中生成对应的样式,并且根据不同的设备响应成不同的值。你只需要直接用就行了。

提前尝鲜

前文说过,CMUI包括三个模块,本文也仅对Cyan中的的布局,组件库中的列表,方法库中的动态辅助做了简介,CMUI的功能远不止如此,我们正在对文档,案例,主题库做最后的完善,如果你想提前尝鲜,可以点击下方链接破解我们官网的二维码,加入我们的讨论群来获取。

有本事来扫个码啊

关注下面的标签,发现更多相似文章
评论