微信小程序 MiniProgram
样式共享与隔离
全局样式
在根目录下有一个app.wxss,该文件用于放置全局样式,写在这里面的样式将影响所有页面及组件(配置了样式隔离的除外)
页面样式
有三种隔离模式,isolated(默认),apply-shared,shared
Page({
options: {
styleIsolation: 'isolated',
}
})
个人经验
一般第三方组件都会设置apply-shared,以便于页面实现样式覆盖,这里注意,只有页面可以实现样式覆盖,组件不行
在自定义组件中用了另一个组件(例如第三方的vant),如果想要实现样式覆盖,则需要是用shared,但是使用shared后容易使得页面的其他组件也被影响,所以最佳实践是在进行样式覆盖的时候,将覆盖的样式控制在某个元素中。
如需要覆盖.van-popup,则在使用组件的外围包裹一层view,最终的覆盖样式应该是如下:
.shops .van-popup {
background-color: #fff !important;
}
.shops 是外围view的class
<view class="shops">
<van-popup></van-popup>
</view>
原理猜测
当打开(或者编译?)时,以page为单位,将所有组件的样式根据隔离选项重新进行合并生成
方式是,先根据自定义组件的隔离方式从下往上传递,然后再根据自定义组件的隔离方式从上往下传递
举个例子,页面上有自定义组件A、组件B、组件C、组件D
组件A是isolated
组件B是apply-shared
组件C是shared
组件D是shared
首先是从下往上传递,那么Page的样式=组件C+组件D+Page
接着是从上往下传递,那么
最终组件A = 组件A
最终组件B = 最终Page样式+组件B = 组件C+组件D+Page+组件B (也就是 组件C,组件D以及页面的样式都会影响组件B)
最终组件C = 最终Page样式 = 组件C+组件D+Page(也就是 组件D以及页面的样式都会影响组件C)
最终组件D= 最终Page样式= 组件C+组件D+Page(也就是 组件C以及页面的样式都会影响组件D)
下面是一些官方的文档片段
styleIsolation
选项从基础库版本 2.6.5 开始支持。它支持以下取值:
isolated
表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值);apply-shared
表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;shared
表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了apply-shared
或shared
的自定义组件。(这个选项在插件中不可用。)
使用后两者时,请务必注意组件间样式的相互影响。
如果这个 Component 构造器用于构造页面 ,则默认值为 shared
,且还有以下几个额外的样式隔离选项可用:
page-isolated
表示在这个页面禁用 app.wxss ,同时,页面的 wxss 不会影响到其他自定义组件;page-apply-shared
表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式不会影响到其他自定义组件,但设为shared
的自定义组件会影响到页面;page-shared
表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式会影响到其他设为apply-shared
或shared
的自定义组件,也会受到设为shared
的自定义组件的影响。
从小程序基础库版本 2.10.1 开始,也可以在页面或自定义组件的 json 文件中配置 styleIsolation
(这样就不需在 js 文件的 options
中再配置)。例如:
{
"styleIsolation": "isolated"
}
此外,小程序基础库版本 2.2.3 以上支持 addGlobalClass
选项,即在 Component
的 options
中设置 addGlobalClass: true
。 这个选项等价于设置 styleIsolation: apply-shared
,但设置了 styleIsolation
选项后这个选项会失效。