liangliangshuo 2019-11-04
使用 Taro 开发微信小程序的时候,将原来的main.js
页面拆分为多个函数式组件的时候,发现main.js
已经引入的scss
文件里面的类,在自定义组件中不生效
自定义组件对应的样式文件,只对该组件内的节点生效。编写组件样式时,需要注意以下几点:
id 选择器(#a)
、属性选择器([a])
和标签名选择器
,请改用 class 选择器
。后代选择器(.a .b)
在一些极端情况下会有非预期的表现,如遇,请避免使用。(.a > .b)
只能用于 View 组件与其子节点之间,用于其他组件可能导致非预期的情况。继承样式
,如 font
、 `color ,会从组件外(父组件)继承到组件内。但是引用组件时在组件节点上书写的 className 无效。 (具体解决方案请参见下面的外部和全局样式介绍。)app.scss
中的样式、引入组件所在页面的样式,均对自定义组件无效。#a { } /* 在组件中不能使用 */ [a] { } /* 在组件中不能使用 */ button { } /* 在组件中不能使用 */ .a > .b { } /* 除非 .a 是 view 组件节点,否则不一定会生效 */
真香,原来是第2点的原因,本人使用了后代选择器,父类
是在原页面
,而子类
是在自定义组件
中,所以子类样式并不会生效。
组件可以指定它所在节点的默认样式,使用 :host
选择器。只需要在样式文件中输入该选择器,立即生效,非常好用,亲测有效
/* 该自定义组件的默认样式 */ :host { color: red; font-weight: bold; font-size: 30PX; }
MyPage.js
export default class MyPage extends Component { render () { return <CustomComp my-class="red-text" /> } }
MyPage.scss
.red-text { color: red; }
CustomComp.js
export default class CustomComp extends Component { static externalClasses = ['my-class'] render () { return <View className="my-class">这段文本的颜色由组件外的 class 决定</View> } }
上面的 CustomComp 使用了ES6 extends来创建了组件,那么问题来了,如果是函数式组件
,那该如何写呢?哈哈很简单
export default function CustomComp (props){ CustomComp.externalClasses = ['my-class'] render () { return <View className="my-class">这段文本的颜色由组件外的 class 决定</View> } }
注意:externalClasses
需要使用短横线命名法 (kebab-case)
,而不是 React 惯用的 驼峰命名法 (camelCase)。否则无效。
使用外部样式类可以让组件使用制定的组件样式类,如果希望组件外样式类能够完全影响组件内部吗可以将组件构造器中的options.addGlobalClass
字段置为 true
CustomComp.js
export default class CustomComp extends Component { static options = { addGlobalClass: true } render () { return <View className="red-text">这段文本的颜色由组件外的 class 决定</View> } }
组件外的样式定义
.red-text { color: red; }
如果使用函数式组件
... CustomComp.options = { addGlobalClass: true } ...
1.解决了自定义组件(引用页面)样式不生效的问题
2.可以使用:host
来写默认样式
3.可以选择使用外部的特定样式类或者全局样式类,不同的组件写法略微不同