-
Notifications
You must be signed in to change notification settings - Fork 321
UI 组件自定义样式
Yan edited this page May 9, 2013
·
20 revisions
arale 的 UI 组件使用模版机制,代码有一套默认的模版,如果使用者想要修改模版样式我们提供了以下方案
方案来源于讨论 #135
采用更换前缀的方式来支持自定义样式,组件需要有一个约定的属性 classPrefix
来定义样式的前缀,此属性要由组件开发者添加。
组件
var Overlay = Widget.extend({
attrs: {
classPrefix: 'ui-overlay'
}
})
模版
<div class="{{classPrefix}} {{classPrefix}}-focused">
<div class="{{classPrefix}}-header"></div>
<div class="{{classPrefix}}-content"></div>
<div class="{{classPrefix}}-footer"></div>
</div>
样式
.ui-overlay {}
.ui-overlay-header {}
.ui-overlay-content {}
.ui-overlay-footer {}
.ui-overlay-focused .ui-overlay-content {}
组件开发者需要注意的是:每次渲染模版的时候 model 上都要有 classPrefix,尤其是重复渲染的时候。
如果要使用自定义样式,在实例化时只需要指定 classPrefix: 'ui-overlay2'
,将样式的前缀也改成 ui-overlay2。
new Overlay({
classPrefix: 'ui-overlay2'
})
.ui-overlay2 {}
.ui-overlay2-header {}
.ui-overlay2-content {}
.ui-overlay2-footer {}
.ui-overlay2-focused .ui-overlay-content {}
如果不使用模版,使用者可直接传 DOM元素,这样就不用设置 classPrefix
。
<div id="overlay" class="ui-overlay3 ui-overlay3-focused">
<div class="ui-overlay3-header"></div>
<div class="ui-overlay3-content"></div>
<div class="ui-overlay3-footer"></div>
</div>
new Overlay({
element: $('#overlay')
});
此方案跟样式的整体方案相关,支付宝的样式架构为一个样式池,所有的样式组件都对应一个唯一的 id,为了页面上不冲突允许代码适量冗余,所以 classPrefix 是对应这个 id 的。
好处:基于模板构建的组件,不同皮肤间可以做到彻底绝缘,彼此互不影响。
坏处:模板写起来比较麻烦,要注意传 classPrefix
;无法复用任何已有皮肤的样式,必须全新写。
备选方案采用在根节点增加一个样式的方式,而不修改模版的 class。
这种方式下,组件模版的样式是写死的,不需要额外的处理。如果要自定义样式,可指定 className 来覆盖原来的样式。
<div class="ui-overlay ui-overlay-focused">
<div class="ui-overlay-header"></div>
<div class="ui-overlay-content"></div>
<div class="ui-overlay-footer"></div>
</div>
new Overlay({
className: 'custom'
})
.ui-overlay .ui-overlay-header {}
.ui-overlay .ui-overlay-content {}
.ui-overlay .ui-overlay-footer {}
.custom .ui-overlay-header {}
注意:
- className 由 widget 提供,所以组件不用增加此参数。
- 写 css 的时候要注意使用命名空间,防止命名冲突
好处:皮肤自定义,由用户决定,不想用默认皮肤时,不引入就好,直接用默认的 class 重写一套就好,如果要复用,则引入默认的皮肤,再写需要覆盖的部分就好。
坏处:如果一个页面有同一个组件的多套皮肤,容易引起冲突(因此在实现时,都可能走捷径采取了覆盖默认 class 的策略)。