本文将学习自定义组件样式的4个特性:样式隔离、外部样式、引用页面或父组件样式、虚拟化组件节点。
默认情况下,自定义组件的样式只受到自定义组件 wxss 的影响。除非以下两种情况:
styleIsolation
。app.wxss
或页面的 wxss
中使用标签名选择器(或一些其他特殊选择器)来直接指定样式会影响到页面和全部组件。通常情况下这是不推荐的做法。styleIsolation
在自定义组件的component中设置。
自定义组件的 styleIsolation
选项从基础库版本 2.10.1 开始支持。它支持以下取值:
isolated
表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值);
apply-shared
表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;
shared
表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了 apply-shared
或 shared
的自定义组件。(这个选项在插件中不可用。)
app.wxss
或页面的 wxss
中使用标签名选择器 指定的样式会影响到页面和全部组件。(PS:不推荐这么做) /* app.wxss 设置所有view标签背景色为黄色,text为块元素*/
view {
background: yellow;
}
text {
display: block;
}
/* index.wxss */
.red {
color: red;
}
.blue {
color: blue;
}
<view>这段文本有底色view>
<text class="red">这行字是红的text>
<text class="blue">这行字是蓝的text>
<isolated />
<view>isolated: 这段文本有底色view>
<text class="red">但这行字不是红的text>
<text class="blue">但这行字不是蓝的text>
/* isolated.wxss */
:host {
display: block;
}
.red{
color: green;
}
// isolated.js
Component({
options: {
styleIsolation:"isolated"
}
})
运行结果:
可以看到,虽然设置了"styleIsolation"="isolated"
,isolated组件的text的颜色样式为内部设置的值,但view
标签还是黄色的底色。
默认情况下("styleIsolation"="isolated"
),自定义组件 wxss 的样式仅对内部起作用,且会隔离页面相同样式。
"styleIsolation"="apply-shared"
,页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;外部可以影响内部,但内部不能影响外部;
shared表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了
apply-shared或
shared` 的自定义组件。
本示例中,isolated组件“但这行字不是红的”本来是绿色,但改为shared
后,index.wxss的样式起作用了。说明页面的样式优先级更好。
所以我猜测,小程序的样式的优先级应该是自顶向下的。
有时候自定义组件希望能接受外部传入的样式类。此时可以在 Component
中用 externalClasses
定义若干个外部样式类。
// isolated.js
Component({
options: {
styleIsolation:"isolated"
},
externalClasses: ['my-class'] // 添加外部样式类my-class
})
<view>isolated: 这段文本有底色view>
<text class="my-class">这段文本的颜色由组件外的 class 决定text>
<text class="blue">但这行字不是蓝的text>
/* index.wxss */
.red {
color: red;
}
.blue {
color: blue;
}
.red-text {
color: red;
}
<view>这段文本有底色view>
<text>这行字是红的text>
<text class="blue">这行字是蓝的text>
<isolated my-class="red-text"/>
在“样式隔离”一节中,我们提到自定义组件使用isolated
可以隔离所在页面的类选择器样式;但平台仍然提供了可以在局部引用组件所在页面的样式或父组件的样式。
组件可以使用 ~
来引用页面中类的样式。
组件可以使用^
来引用父组件中类的样式;也可以连续使用多个 ^
来引用祖先组件中的样式。
默认情况下,自定义组件本身的那个节点是一个“普通”的节点,使用时可以在这个节点上设置 class
style
、动画、 flex 布局等。如下图所示,在isolated节点上设置样式:flex布局,字体红色,默认居左,边框红色;在slot中插入。组件内部样式:字体蓝色,居中,边框蓝色。
有些时候,自定义组件并不希望这个节点本身可以设置样式、响应 flex 布局等,而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定。
如下图所示:打开虚拟节点后,index页面的isolated组件上的样式失效了。也就是isolated节点本身设置的样式不起作用了,且只有组件内部的两个view组件能效应index页面的flex布局,且边框颜色采用自己的配置(蓝色)。
前面提到,打开虚拟节点后,“index页面的isolated组件上的样式失效了”,但是,仍然可以在properties中定义style属性获取到“index页面的isolated组件上的样式”。如下图所示:
这个部分有点难理解,需要仔细分析。总结下:就是说一般情况下,虚拟化组件节点可以“阻断”页面上组件的直接指定的style样式;但是凡事都没那么绝对,平台又通过properties+style数据绑定的方式将这种“阻断”又能连通,不一棍子打死。我现在还没遇到需要这种特性的场景,直觉告诉我,这么复杂的东西应该没人用。如果有场景用的话,请评论区告知我,也学习下。顺便看看有没有其他方案可以解决。
本文学习了自定义组件的4个特性:
styleIsolation
选项,设置不同的值,自定义组件的样式与页面的样式会产生不同程度的相互影响。