为什么要集成
如果做服务器端渲染,那就需要拿到css的文本,然后在把它放入body的head中,一起变成html模板传递给客户端。
集成步骤
第一步,安装styled-components和babel-plugin-styled-components
npm install styled-components babel-plugin-styled-components -s
第二步,添加babel配置
.babelrc
{
"presets": ["next/babel"], // 覆盖nextjs的默认babel配置,以本文件的babel配置为准
"plugins": [
[
"styled-components",{ "ssr":true } // 预编译样式
]
]
}
第三步,在_document.js里挂载样式
_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { ServerStyleSheet } from 'styled-components'
class AntDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet()
// 1.这里采用react里High Order Component的方式,可以重新包装APP和所有渲染的组件
const originalRenderPage = ctx.renderPage
try{
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: App => (props) =>
// App挂载样式
sheet.collectStyles(<App {...props} />)
})
// 因为覆盖了Document,所以要重新返回页面的props
const props = await Document.getInitialProps(ctx)
return {
...props,
styles: <>{props.styles}{sheet.getStyleElement()}</>
}
}finally{
sheet.seal()
}
}
render() {
return (
<Html>
<Head>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default AntDocument
第四步,尝试写一个效果
task.js
import { withRouter } from 'next/router'
import styled from 'styled-components'
const Title = styled.h1`
color: yellow;
`
const Task = ({ router,fzr }) => (
<div>
<span>{router.query.taskName} 任务负责人:{fzr}</span>
<Title>试试</Title>
</div>
)
Task.getInitialProps = async (ctx) =>{
const promise = new Promise((resolve)=>{
setTimeout(()=>{
resolve({ fzr: 'chatwei' })
},1000)
})
return await promise
}
export default withRouter(Task)