likes
comments
collection
share

Next.js的创建与使用

作者站长头像
站长
· 阅读数 516

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

使用路由

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编程式导航, 例如:

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文件夹中:

Next.js的创建与使用

这样的配置就说明我们注册了5个常规路由一个错误时显示的路由

也可以使用*路由

在对应的文件夹中使用[...all].tsx

在本项目我使用了

Next.js的创建与使用

这样就相当于注册了article中的所有路由在访问blogweb.cn/article/*

中凡是article的路由都会进入此文件

异步请求

在Next中最大的特点是会渲染异步请求的结果

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标签跳转

<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.js的创建与使用

以上基本就是Next不同于React的点,更多知识点还是要参考于文档