NextJs是React的服务器渲染框架,区别于官方SSRNext最大的特点是可以渲染出Ajax异步请求渲染出来的结果,本网站目前使用的前端框架就是NextJs
本文章默认你已将学会了React,如果你不会React可以去搜索页面去搜索React相关的文章来学习一下React
下面我讲一下NextJs和React的区别,Reac他和其他两个框架的主要区别就是官方只会提供核心库剩余的像:路由(react-router),状态管理(redex),或者css(css in js、scss)方案都由社区提供,而Next和React最大的区别就是路由以及成果物的渲染方式,核心库基本没有区别因为在NextJs官网声明了NextJs是兼容React17的
创建项目
区别于React 这里创建项目是使用yarn create next-app create-next-app name(项目名字)(推荐使用yarn因为npm创建项目会遇到一些网络问题,尤其是安装node-sass的时候,建议使用淘宝源)
安装插件
通常我自己喜欢安装ts和sass,使用命令 yarn add typescript sass
!!:sass版本一定要与node的版本对应
启动项目
cd name(项目名)
yarn dev
使用路由
代码语言:javascript复制import React, { useState, useEffect, useRef } from "react";
import style from "./index.module.scss";
import Link from "next/link";
// import router from "next/router";
import { Col, Row, BackTop, Button } from "antd";
import {
HomeOutlined,
SearchOutlined,
UserOutlined,
DeploymentUnitOutlined,
MenuUnfoldOutlined,
} from "@ant-design/icons";
import axios from "axios";
export default function Header() {
const [html, setHtml] = useState<string>("占位的一个注释");
const header = React.useRef(null);
useEffect(() => {
// console.log(header.current);
axios.get("/message").then(res => {
const index: number = Math.floor(Math.random() * res.data.data.length);
setHtml(res.data.data[index].message);
});
}, []);
const setAnimation = e => {
console.log(e);
};
const [active, setActive] = useState<boolean>(false);
return (
<header
className={style.header ` ${active && style.header_active}`}
ref={header}
onLoad={(e: any) => setAnimation(e)}
onClick={(e: any) => setAnimation(e)}
>
<Button
type="primary"
className={`phone ${style.header_switch_ico}`}
onClick={() => setActive(!active)}
>
<MenuUnfoldOutlined />
</Button>
<span dangerouslySetInnerHTML={{ __html: `<!--${html}-->` }}></span>
<Row justify="space-between" className={style.nav}>
<Col sm={8} className={style.logo}>
<h1>
<a href="/">刘润霖</a>
</h1>
<span>
前端<span style={{ textDecoration: "line-through" }}>大佬</span>小白
</span>
</Col>
<Col sm={6}>
<nav>
<Link href="/">
<a>
<HomeOutlined />
首页
</a>
</Link>
<Link href="/search">
<a>
<SearchOutlined /> 搜索文章
</a>
</Link>
<Link href="/about">
<a>
<UserOutlined /> 关于作者
</a>
</Link>
<Link href="/rss">
<a className="phone">
<DeploymentUnitOutlined /> 订阅
</a>
</Link>
</nav>
</Col>
</Row>
<BackTop />
</header>
);
}
这是我首页的源码
大家也注意到了每次我们在路由中导入变量是不在是from react-router-dom,而是变成了next/router,next/link等
router事件基本也是想react中一样不同的是因为是在服务器渲染的所以在next中新加了一个功能:预加载
router.prefetch('/path')
主要适用于js编程式导航, 例如:
代码语言:javascript复制importReactfrom'react'
import{ withRouter }from'next/router'
classMyLinkextendsReact.Component{
componentDidMount(){
const{ router }=this.props
router.prefetch('/dynamic')
}
render(){
const{ router }=this.props
return(
<div>
<a onClick={()=>setTimeout(()=> router.push('/dynamic'),100)}>
A route transition will happen after 100ms
</a>
</div>
)
}
}
exportdefault withRouter(MyLink)
适用setTimeout进行延迟跳转路由时就是预加载的最佳适用环境。
在Next中没有单独的文件去配置path和components对应
Next中遵循组件及路由的原则
在page文件夹中:
这样的配置就说明我们注册了5个常规路由一个错误时显示的路由
也可以使用*路由
在对应的文件夹中使用[...all].tsx
在本项目我使用了
这样就相当于注册了article中的所有路由在访问blogweb.cn/article/*
中凡是article的路由都会进入此文件
异步请求
在Next中最大的特点是会渲染异步请求的结果
代码语言:javascript复制import axios from "axios";
export default function Home({ data }) {
return (
<>
<div>{data ''}</div>
</>
);
}
Home.getInitialProps = async () => {
let data;
await axios
.get("/article-page/1", {
params: { key: "router,title,type,introduce,article,time" },
})
.then(res => {
data = res.data.data;
});
return {
data: data,
};
};
例如这个demo,官方提供了getInitialProps生命周期(现在推荐使用getServerSideProps),在这个生命周期中我们可以返回变量作为函数的props,axios注意使用async和await
Link标签跳转
代码语言:javascript复制<Link href="/">
<a>
<HomeOutlined />
首页
</a>
</Link>
Link必须有子元素包裹,并且有className或者事件绑定只能绑定到子元素上,如果你的子元素不使用a使用其他标签也可以,相当于为你的字元素添加了一个onclick事件,相当于Vue中router-link的tag属性
CSS解决方案
想React一样NextJs支持CSS in Js和CSS模块化引入,但是与React不同的是import './index.css'必须在_app.js中引入
使用@代替src文件夹 原本Next.js创建之后是不会有src文件夹的但是我们可以创一个(相关文档),然后将样式、模块、组件路由等文件放进去(总之就是关于项目配置的不要放,关于页面的可以) TS:
以上基本就是Next不同于React的点,更多知识点还是要参考于文档