一个方便定制及扩展的UI组件库:sheral

sheral是什么

简单来说,sheral是个UI库,目前拥有25+常用移动端组件(如btn, card, media, nav, dialog, toast等),同时允许用户非常方便扩展及定制属于自己的组件。但是sheral决不只限于UI库,它还拥有了30+ Sass 的基础mixin%的封装及其他基础能力,有了这些基础能力,不仅快捷便利,更是拥有了更多扩展可能。下面是sheral的三张UI截图:

Sheral Sheral Sheral

虽然UI部分从效果上看与其他的UI库没有什么特殊区别,都是移动端重构需要面对的一些常见的页面效果。但是表面的相似,并不代表本质的类同,只有深入代码才能发现不一样的惊喜。

sheral的设计思想

虽然目前网上的UI库众多,但是下定决心再造个轮子,也并非等闲之事,当然更不能生搬硬套为了UI而UI,于是在创造sheral的同时,更要赋予其一个思想灵魂。

sheral整体设计思想主要分为基础功能部分和UI组件部分,其中基础功能部分由sandal来承载,而UI组件就是基于sandal提供的基础能力实现的UI(一如jQuery和插件的关系,sandal就如jQuery,而一个个组件就如一个个扩展的jQuery插件),如下图:

Sheral

sandal负责基础通用兼容等基础能力处理,犹如人体的心脏,而components为一个个UI组件,如人体的四肢百骸。由心脏sandal向components四肢百骸提供动力,这样就激活了整个sheral的生机。

所以要理解sheral,首先要解决的是基础通用的sandal这块,只有了解了这块如心脏般的奠基石,后面的所有都是添砖加瓦的水到渠成。

基础能力搭建

因为整个基础能力部分都由sandal来负责,如变量,mixin,reset等,所以sandal的搭建既要保证基础能力充足又要保证不至于臃肿,整体设计图如下:

Sheral

首先sandalcoreext两部分组成,core是核心部分,ext是属于扩展部分(提供的一些额外的能力,根据需要引用)。

其中core的五个文件,分别负责基础的变量,mixin,媒体查询,动画,重置。这五个文件最终构成两个集合文件_function.scss_core.scss,而我们对外的接口就是这两个集合文件,其中_function.scss中导入了除重置之外的四个文件,保证了所有的基础功能,并且不输出任何样式,而_core.scss则在function的基础上加入了重置样式;而ext部分则是根据项目需要引用的,分别为一些帮助的class,一些绘制的Icon class,以及网格系统。

与其他多数UI库不同,这里设计的sandal本身就是独立的,sandal中的变量,mixin等只负责基础常用的,所有与基础常用无关的都不应该存在(如组件的变量或mixin)。正因为sandal的独立,所以完全可以脱离sheral作为移动端的基础库使用,而这正是设计的最初目的。如下是抽取的几个mixin定义截图(所有mixin定义可见_mixin.scss):

Sheral

有了这些基础能力保证,在写具体的UI效果时就会如虎添翼,如.header{@include fixed;}, .title{@extend %ellipsis}, .img-wrap{@include object-wrap($child: '.img')}等等,更多sandal的介绍及使用请参考sandal 文档

了解了这个具备良好接口设计及丰富功能调用的奠基石sandal之后,就轮到下一个遍地开花的UI组件扩展了

UI组件扩展

常用的UI效果,90%的前端都可以搞定,并且满足跟设计图一样。但是当面对各种机型的兼容处理,代码如何高效重用,各种可能的修改及扩展这三大问题的时候,也许就是个问题了。

所以UI组件不再是简单的实现效果,而是必须满足以下条件:

  • 各种兼容,让你无后顾之忧;
  • 方便使用,可以根据需求修改定制;
  • 满足更多的使用场景,毕竟设计说变就变;
  • 克制大于放肆,不能因为满足各种场景,就不加以控制地去成倍制造代码。

有了上面条件的限制,一个好的UI组件就会浴火而成,而一个好的UI组件除了解决上述的三大问题,还可以帮助我们轻松面对一个所有人都必须面对的终极大问题,赶时间。

下面以sheral card 的demo为例,简单说下一个UI组件的精雕细琢的考虑,效果图截图如下:

Sheral

先对我们要实现的效果分析如下:

  • 卡片的形式:一种是边框分割的;一种是背景色分割的,无边框
  • 每行显示的数量,2个或3个
  • 卡片的图片是否要默认占位高度,具体说明可参考移动端重构实战系列6——icon与图片
  • 样式的控制,一般来说只会使用一种卡片样式,所以要设置开关控制样式输出
  • 布局的控制,毕竟不是每个人都需要兼容低端安卓机,所以flexfloat可以自由切换,也方便以后直接升级

具体源码实现如下:

@charset "UTF-8";

//-----------------------------------------------------
// card list
//-----------------------------------------------------

$cardFlexSwitch:       false !default; // 默认使用float布局
$cardGap:              10px !default; // 默认间距10px
$cardImgRation:        1 !default; // 图片比例
$carLineNum:           2 !default; // 目前只支持2 或 3 等分

$cardBorderSwitch:     true !default; // 启用border分割

$cardGapSwitch:        true !default; // 启用背景分割

.card-list {
    @if $cardFlexSwitch {
        display: flex;
        flex-wrap: wrap;
    } @else {
        overflow: hidden;
    }

    .card-item {
        position: relative;
        width: 100% / $carLineNum;

        @if not $cardFlexSwitch {
            float: left;
        }

        .item-img-wrap{ // 设置图片默认占位高度
            @include object-wrap(percentage($cardImgRation), '.item-img'); // 调用sandal中定义的基础mixin
        }
        .item-img{
            width: 100%;
        }
        .item-tt {
            line-height: 30px;
        }
    }
}
@if $cardBorderSwitch{ // border 分割样式
    .card-list--border{
        background: #fff;
        position: relative;
        &::before{
            content: "";
            @include retina-one-px-border(top); // 调用sandal中定义的基础mixin
        }
        .card-item{
            padding: $cardGap !important;
            &::after{
                content: "";
                @include retina-one-px-border(bottom); // 调用sandal中定义的基础mixin
            }

            &::before{
                content: "";
                @include retina-one-px-border(right);
            }

            $type: if($carLineNum == 2, '2n', '3n'); // 2栏 3栏判断

            &:nth-of-type(#{$type}){
                &::before{
                    display: none;
                }
            }
        }
    }
}
@if $cardGapSwitch{ // 背景分割样式
    .card-list--gap{
        padding-left: $cardGap / 2;
        padding-right: $cardGap / 2;
        .card-item{
            margin-bottom: $cardGap;
            padding-left: $cardGap / 2;
            padding-right: $cardGap / 2;
        }
    }
}

如这样考虑周全的UI组件,sheral有25+(全部组件可见sheral components),同时还在不断加入新的好用组件,除了直接使用这些提供的组件外,用户还可以基于sandal提供的丰富基础能力,轻松高效扩展出自己所需组件,具体如何扩展可以参考上面的card组件。

总体优势

正是上面说的sandal的基础能力及UI组件的扩展,最后汇集成sheral的四大优点:

  • 优秀的设计思想——基础通用 + UI组件
  • 有了sandal作为基础能力的保证,提供了良好的接口设计及丰富的功能调用
  • 众多的组件数量及丰富的组件形态,并加上克制的思想,以及方便定制和扩展的能力
  • 组件不针对特定的业务,都是移动端基础常见效果,更通用

所有的这些优点最终导向一个愿景:方便,快捷,高效!

整体了解了sheral的设计思想及优点之后,下面介绍下如何使用sheral。

如何使用sheral

因为篇幅有限,这里仅以实现iOS的设置列表为例(从飞行模式到运营商),如下图:

Sheral

HTML结构如下:

<ul class="line-list line-list--indent line-list--flex list--setting">
    <li class="line-item">
        <i class="item-icon icon-plane"></i>
        <p class="item-tt">飞行模式</p>
        <i class="icon-switch"></i>
    </li>
    <li class="line-item">
        <i class="item-icon icon-wifi"></i>
        <p class="item-tt">Wi-Fi</p>
        <span class="item-append">Tencent-StaffWiFi</span>
        <i class="icon-v-right"></i>
    </li>
    <li class="line-item">
        <i class="item-icon icon-bluetooth"></i>
        <p class="item-tt">蓝牙</p>
        <span class="item-append">关闭</span>
        <i class="icon-v-right"></i>
    </li>
    <li class="line-item">
        <i class="item-icon icon-cellular"></i>
        <p class="item-tt">蜂窝移动网络</p>
        <i class="icon-v-right"></i>
    </li>
    <li class="line-item">
        <i class="item-icon icon-hotspot"></i>
        <p class="item-tt">个人热点</p>
        <i class="icon-v-right"></i>
    </li>
    <li class="line-item">
        <i class="item-icon icon-carrier"></i>
        <p class="item-tt">运营商</p>
        <span class="item-append">中国移动</span>
        <i class="icon-v-right"></i>
    </li>
</ul>

SCSS代码如下:

@import "sheral/sandal/core";
@import "sheral/sandal/ext/icons"; // 引入所有的自定义icon 或者 把右箭头拷贝过来(如下注释的右箭头样式)
@import "sheral/components/line-list";

// 拷贝右箭头样式
// .icon-v-right {
//     position: relative;
//     &::after {
//         content: "";
//         @include v-arrow;
//         position: absolute;
//         left: 50%;
//         top: 50%;
//         margin-left: -2px;
//         transform: translate(-50%, -50%) rotate(45deg);
//         box-sizing: border-box;
//     }
// }

// 特殊化class
.list--setting{
    .item-icon{
        width: 30px;
        height: 30px;
    }
    // 特殊化左右为15px,默认为10px
    .line-item{
        padding-left: 15px;
        padding-right: 15px;
        &::before{
            left: 60px;
        }
        .icon-v-right{
            width: 40px;
        }
    }
}

最后,移动端重构实战系列文章可以帮助你更多的了解sheral及移动端的重构,文章列表如下:

欢迎使用sheral,如有问题或建议可以在github上反馈,或在imweb群(179045421),w3cplus群(1041263),Sass群(78142855)中进行交流,谢谢!

结一

常用昵称“结一”。资深前端工程师,Drupal Themer,拥有丰富的前端实战经验。目前和大漠一起管理 W3CPlus站点,为 CSS3 的推广贡献自己的力量,是广大的 Drupal 爱好者之一。擅长于布局架构、浏览器兼容,CSS3研究。请关注我:新浪微博

如需转载,烦请注明出处:http://www.w3cplus.com/mobile/sheral-intro.html

返回顶部