在看完上面几种炫酷的弹框效果后,我们还是按照惯例研究下如此强大的弹框组件的源码。在研究弹框部分源码之前有必有分析一下一套完整UI框架所需要注意的框架级别的整体架构
如何使用less工程化处理样式
处理样式是所有UI框架比不可忽略的核心逻辑之一,在vant-weapp中对样式的处理主要分为以下三部分;源码对应结构如下图所示,使用less的mixins复用实现主题变量控制、公共样式抽离等。
主题变量
在var.less文件定义了框架所用到的全部的样式控制相关的变量,其中与弹框相关的部分源码如下:
// Dialog @dialog-width: 320px; @dialog-small-screen-width: 90%; @dialog-font-size: @font-size-lg; @dialog-border-radius: 16px; @dialog-background-color: @white; @dialog-header-font-weight: @font-weight-bold; @dialog-header-line-height: 24px; @dialog-header-padding-top: @padding-lg; @dialog-header-isolated-padding: @padding-lg 0; @dialog-message-padding: @padding-lg; @dialog-message-font-size: @font-size-md; @dialog-message-line-height: 20px; @dialog-message-max-height: 60vh; @dialog-has-title-message-text-color: @gray-7; @dialog-has-title-message-padding-top: @padding-sm;
源码: var.less
此文件中的最终会转换成 css变量 ,并非像antd、iview等网页端框架中的样式处理那样编译成变量指向的值。根据css变量作用域的特性,可以在自定义组件的外部样式类中局部覆盖样式变量来改变组件内部的样式。
通用样式
像清除浮动、文字省略、1像素边框等通用的样式类的处理在mixin文件夹下
清除浮动
.clearfix() { &::after { display: table; clear: both; content: ''; } }
使用常见的after伪类来实现清除浮动
文件省略
.multi-ellipsis(@lines) { display: -webkit-box; overflow: hidden; text-overflow: ellipsis; -webkit-line-clamp: @lines; /* autoprefixer: ignore next */ -webkit-box-orient: vertical; } .ellipsis() { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
使用less的函数封装了两个处理文字省略方法:单行省略、多行省略
BEM命名
如何工程化的注册自定义组件
微信小程序官方提供了 Component构造方法 注册自定义组件,为了结合typescript给自定义组件提供更灵活强大的组件注册器对Component进行了下面的功能封装处理
封装通用组件构造方法
function VantComponent<Data, Props, Methods>( vantOptions: VantComponentOptions< Data, Props, Methods, CombinedComponentInstance<Data, Props, Methods> > = {} ): void { const options: any = {}; mapKeys(vantOptions, options, { data: 'data', props: 'properties', mixins: 'behaviors', methods: 'methods', beforeCreate: 'created', created: 'attached', mounted: 'ready', relations: 'relations', destroyed: 'detached', classes: 'externalClasses' }); const { relation } = vantOptions; if (relation) { makeRelation(options, vantOptions, relation); } // 给所有组件添加默认外部样式类custom-class options.externalClasses = options.externalClasses || []; options.externalClasses.push('custom-class'); // 给所有组件添加默认behaviors options.behaviors = options.behaviors || []; options.behaviors.push(basic); // map field to form-field behavior if (vantOptions.field) { options.behaviors.push('wx://form-field'); } // 默认启用多slot支持、组件中允许全局样式修改 options.options = { multipleSlots: true, addGlobalClass: true }; // 最终使用官网构造方法构造组件 Component(options); }
源码:component.ts
behaviors复用共享逻辑
behaviors 是微信小程序官方用于组件复用 data、methods 等属性方法的一种方式,和vue中的 mixins 小作用一致,vant-weapp中定义的 mixins 如下图所示:
其中basic是所有自定义组件都复用的一个mxin,给所有自定义的组件提供了三个方法: $emit 、 set 和 getRect 。
$emit 封装了 triggerEvent 方法;
set 封装 setData 方法为Promise形式;
getRect 采用Promise方法用查找对应节点的boundingClientRect。
源码如下: