title: 使用 CSS-in-JS

在 React 社区有一个著名的 CSS-in-JS 解决方案: styled-components。但遗憾的是,styled-components 使用 <style> 标签来动态地控制样式,在小程序没有类似的方案。但我们可以通过 linaria 实现同样的功能,linaria 主要提供以下特性:

  • 近似于 styled-components 的 API
  • 完整的 TypeScript 支持
  • 零运行时

使用 linaria 也非常简单,首先通过 NPM 安装依赖:

  1. $ npm i linaria

其次配置项目根目录的 babel.config.js:

  1. module.exports = {
  2. presets: [
  3. ['taro', {
  4. framework: 'react',
  5. ts: true
  6. }],
  7. 'linaria/babel' // 添加到 babel-preset
  8. ]
  9. }

之后配置 config/index.js

  1. const config = {
  2. mini: {
  3. webpackChain(chain, webpack) {
  4. // linaria/loader 选项详见 https://github.com/callstack/linaria/blob/master/docs/BUNDLERS_INTEGRATION.md#webpack
  5. chain.module
  6. .rule('script')
  7. .use('linariaLoader')
  8. .loader('linaria/loader')
  9. .options({
  10. sourceMap: process.env.NODE_ENV !== 'production',
  11. })
  12. }
  13. }
  14. }

最后在项目根目录新建 linaria.config.js

  1. // linaria 配置详见 https://github.com/callstack/linaria/blob/2eaef3f15b/docs/CONFIGURATION.md#options
  2. module.exports = {
  3. ignore: /node_modules[\/\\](?!@tarojs[\/\\]components)/,
  4. }

在业务代码中我们可以这样使用:

  1. import React from 'react'
  2. import { View } from '@tarojs/components'
  3. import { styled } from 'linaria/react'
  4. const Title = styled(View)`
  5. color: ${props => props.color}
  6. `;
  7. const Index = () => {
  8. return <Title color='red'>
  9. Hello World!
  10. </Title>
  11. }
  12. export default Index
  1. import React from 'react'
  2. import { View } from '@tarojs/components'
  3. import { styled } from 'linaria/react'
  4. const Title = styled(View)<{ color: string }>`
  5. color: ${props => props.color}
  6. `;
  7. const Index: React.FC = () => {
  8. return <Title color='red'>
  9. Hello World!
  10. </Title>
  11. }
  12. export default Index