王志远,微医前端技术部
前言
写在前边:本文中 react 组件、页面均使用tsx。
本次项目依赖版本如下
- @zeit/next-css:1.0.1
1. 全局用法
打开 pages 目录下_app.js,这里以引入 antd 的 css 为例
import App from 'next/app';
import 'antd/dist/antd.css'; // 这里的 css 样式直接作用于 Container 组件
const Container = ({ Component, pageProps }) => {
return (
<Component {...pageProps} /
)
}
Container.getInitialProps = async (appContext) => {
const appProps = await App.getInitialProps(appContext);
return {
...appProps,
};
}
export default Container;
nextJS会把_app.js导出的组件作为 page 的父组件,也就是说这里的 Container 实际上是个超级wrapper,每次路由跳转都会先用这个 wrapper 包裹 page 再渲染。
想要 css 按需引入,需要配置babel-plugin-import,请参考 antd 官网
2. css module
这也是我本人最喜欢的一种用法。使用方法如下
前置
这需要 next 支持 css 模块导入,先安装依赖
yarn add @zeit/next-css@^1.0.1
再修改配置文件next.config.js
(没有就新建)
const withCSS = require("@zeit/next-css");
if (typeof require !== "undefined") {
require.extensions[".css"] = (file) => {};
}
module.exports = withCSS({});
使用
根目录下创建 compotents 文件夹,新建Board.tsx、Board.module.css文件。
Board.tsx
import style from './Board.module.css';
interface BoardProps { }
const Board: React.FC<BoardProps> = (props) => {
return (
<div className={style.title}>component Board title</div>
)
}
export default Board;
Board.module.css
.title {
color: red;
}
底层会按 webpack 某个 loader 的配置,为标签生成一个特定的className,由此不会造成 css 冲突
美中不足是 style 没有代码提示,需要自己写.d.ts定义模块,我觉得没多大必要
3. css in js
顾名思义,把 css 和 jsx 写在一起
import { NextComponentType } from 'next';
import { NextRouter } from 'next/router';
import Head from 'next/head';
interface LIstInitialProps { }
interface LIstProps extends LIstInitialProps {
router: NextRouter;
}
const LIst: NextComponentType<any, LIstInitialProps, LIstProps> = (props) => {
return (
<>
<Head>
<title>List Page</title>
</Head>
<div>List Page</div>
<style jsx>{`
div {
color: blue;
}
`}</style>
</>
)
}
LIst.getInitialProps = () => {
return { }
}
export default LIst;
<style jsx>
包裹css,记得 css 用模板字符串