Taro 自定义组件样式不生效及解决方案
一、问题
页面功能太多,想分成多个自定义组件,结果发现自定义组件样式不生效。
二、解决办法(个人推荐第三种)
第一种:外部样式类
利用 externalClasses
定义段定义若干个外部样式类实现
链接:https://taro-docs.jd.com/taro/docs/component-style.html
/* CustomComp.js */ export default class CustomComp extends Component { static externalClasses = ['my-class'] render () { return <View className="my-class">这段文本的颜色由组件外的 class 决定</View> } } /* MyPage.js */ export default class MyPage extends Component { render () { return <CustomComp my-class="red-text" /> } } /* MyPage.scss */ .red-text { color: red; }
缺点:
1、自定义组件里面的每一个className都需要在externalClasses里面定义,然后才能使用;
2、不能使用 id 选择器(#a
)、属性选择器([a]
)和标签名选择器等多种写法限制;
第二种:使用 CSS Modules(通过引入样式变量的方式添加className,哪里需要就在哪里引用即可)
链接:https://taro-docs.jd.com/taro/docs/css-modules.html
import Taro, { Component } from '@tarojs/taro' import { View, Text } from '@tarojs/components' import styles from './Test.module.scss' export default class Test extends Component { constructor(props) { super(props) this.state = { } } render () { return ( <View className={styles.test}> <Text className={styles.txt}>Hello world!</Text> </View> ) } }
Taro 中内置了 CSS Modules 的支持,但默认是关闭的,如果需要开启使用,请先在编译配置中添加如下配置
根目录下的config/index.js:
// 小程序 mini: { postcss: { // css modules 功能开关与相关配置 cssModules: { enable: true, // 默认为 false,如需使用 css modules 功能,则设为 true config: { namingPattern: 'module', // 转换模式,取值为 global/module,下文详细说明 generateScopedName: '[name]__[local]___[hash:base64:5]' } } } }
// h5
h5: { postcss: { // css modules 功能开关与相关配置 cssModules: { enable: true, // 默认为 false,如需使用 css modules 功能,则设为 true config: { namingPattern: 'module', // 转换模式,取值为 global/module,下文详细说明 generateScopedName: '[name]__[local]___[hash:base64:5]' } } } }
需要注意文件取名需要在中间加上 .module.
,因为namingPattern配置的'module'模式,只有文件名中包含 .module.
的样式文件会经过 CSS Modules 转换处理。
缺点:如果项目中引用了taroUI,发现部分taroUI样式失效了,而且不能通过样式覆盖的方式自定义样式了。
第三种:全局样式类
希望组件外样式类能够完全影响组件内部,可以将组件构造器中的 options.addGlobalClass
字段置为 true。(只需要在自定义组件添加 static options = {addGlobalClass: true};父页面的样式就能作用到自定义组件。)
链接:http://taro-docs.jd.com/taro/docs/component-style.html
/* CustomComp.js */ export default class CustomComp extends Component { static options = { addGlobalClass: true } render () { return <View className="red-text">这段文本的颜色由组件外的 class 决定</View> } } /* 组件外的样式定义 */ .red-text { color: red; }
全局样式虽然可能造成不同页面样式干扰,但只要在最外层起个不一样命名空间,还是很容易就能避免这种失误的,相对而言,全局样式类书写方便,效果最佳。