开始动手
前端搭建
首先我们最主要的就是前端的项目,ok,那就让我们创建一个空项目,使用next
yarn create next-app
//使用TS
yarn create next-app --typescript
之后按照提示选择自己的需求,如果没有什么需求完全可以疯狂点击回车😄😄😄,然后我们就看到了项目的基本目录
我们可以看到blog_fe就是我们的项目名称,以及下面的各级目录
node_modules: 项目所依赖的包
public: 放一些公共的资源,图片或图标。
src/page: 这个就相当于项目的路由,page下的index文件就是首页,我们可以在下面新建文件夹,这就是一个新的路由,文件夹中的index文件就是页面
src/styles:这里面放着一些我们项目的CSS文件
next.config.js: 这是next项目的配置文件,可以参考官网,中有具体的详细API
现在要做什么:动代码
参考package.json文件,我们打开终端,cd 到我们的blog_fe目录中,执行yarn dev命令,把这个项目跑起来。
这就是跑起来的样子,这个页面就是在page/index.tsx中所写的代码,我们删掉所有代码,替换成以下代码
export default function Home() {
return (
<>111111</>
)
}
现在页面内容就变成11111了,ok你现在可以自由的编写你的代码了
样式编写
由于我们在代码中是一定要写样式的,UI框架我使用的是Chakra,便于后期做一些自适应,CSS我使用的是CSS-IN-JS的方案,用的styled-components,你可以随便选用,这里我只写一下我的流程。
First 安装
//安装chakra
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
//安装styled-components
yarn add styled-components
然后我们删掉styles/Home.module.css文件创建一个Home.styled.js文件,添加代码如下
import { Box } from "@chakra-ui/react";
import styled from "styled-components";
//html的标签要用 stlyled.
export const YellowBox = styled.div`
background-color: yellow;
width: 100px;
height: 100px;
`;
//第三方组件的标签要用 stlyled()
export const BlueBox = styled(Box)`
background-color: blue;
width: 100px;
height: 100px;
`;
然后在page/index.tsx中引入他们
import { YellowBox, BlueBox } from "../styles/Home.styled";
export default function Home() {
return (
<>
<YellowBox />
<BlueBox />
</>
);
}
Ok,你先在以及掌握了Chakra 和 styled-components的用法,然后我们简简单单写一些自己想写的内容,他现在变成了这个样子
那么现在,问题来了
现在我们发现了一个很大的问题,在页面多次刷新,或者URL改变的时候样式会失效 emm........,费劲千辛万苦之力,终于找到了解决的办法
问题原因:Next是一个SSR的框架,他会在服务端渲染出HTML,然后返回给客户端,在服务端并没有样式给他渲染。
解决办法:参考styled-components官网,我们将_document.tsx文件的代码改成官方给的方法
import Document, { DocumentContext, DocumentInitialProps } from "next/document";
import { ServerStyleSheet } from "styled-components";
export default class MyDocument extends Document {
static async getInitialProps(
ctx: DocumentContext
): Promise<DocumentInitialProps> {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
}
那么现在,问题解决了,我们又可以愉快的编程了。