Next.js utilizado en este tutorial es la versión 13
Introducción a Next.js
- Proyecto React completo, fácil de construir.
- Viene con sincronización de datos para resolver la mayor dificultad en la renderización del lado del servidor.
- Complementos ricos
- Configuración flexible
Crear primer proyecto
Crear manualmente
inicialización
npm init
Instalar los paquetes de dependencia necesarios
npm install --save react react-don next
Agregar comandos de acceso directo
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "next",
"build": "next build",
"start": "next start"
},
Crear archivo de prueba
Cree la carpeta de páginas en el directorio raíz y cree index.js en este archivo
La carpeta de páginas se especifica en Siguiente. Para los archivos escritos en esta carpeta, Next.js creará automáticamente las rutas correspondientes.
function Index() {
return (
<div>Halo Next.js</div>
)
}
export default Index
Ejecutar npm ejecutar dev
Andamio creact-next-app para crear proyectos Next.js
Crear proyecto
npx create-next-app@latest
Al crear un proyecto por primera vez, si nextjs no está instalado, se le preguntará si desea instalarlo.
What is your project named? my-app // 项目名
Would you like to use TypeScript? No / Yes // TypeScript
Would you like to use ESLint? No / Yes // ESLint
Would you like to use Tailwind CSS? No / Yes // Tailwind CSS
Would you like to use `src/` directory? No / Yes // src 作为根目录
Would you like to use App Router? (recommended) No / Yes // 路由
Would you like to customize the default import alias? No / Yes // 自定义默认导入别名
What import alias would you like configured? @/* // 配置什么导入别名
Ejecutar npm ejecutar dev
Páginas y componentes de Next.js
Crear una nueva página
Cree about.js en el directorio de la página
function About () {
return (
<div>About nextjs</div>
)
}
export default About
Visita http://localhost:3000/about
En Next.js, una página (página) es un componente de React exportado desde .js
, o archivos Estos archivos se almacenan en el directorio. Cada página utiliza su nombre de archivo como ruta.jsx
.ts
.tsx
pages
Crear una página de directorio secundario
Cree un archivo de inicio en el directorio de la página y cree home.js en este archivo
function Home () {
return (
<div>home nextjs</div>
)
}
export default Home
Visita http://localhost:3000/home/home
Producción de componentes.
Crear componente
Cree el directorio de componentes en el directorio src y cree el archivo buttonComponent.js en este directorio
export default ({children})=><button>{children}</button>
Cita
Introducido en home.js
import dynamic from 'next/dynamic'
const ButtonComponent = dynamic(
() => import('@/components/buttonComponent'),
// { ssr: false } // 是否关闭 ssr(服务端渲染) 默认是开启
)
usar
<ButtonComponent>按钮</ButtonComponent>
enrutamiento
Salto con pestañas
Agregue dos páginas a la página de inicio
inicioA.js
import React from "react";
import Link from "next/link";
const HomeA = () => {
return (
<>
<div>我是HomeA 页面</div>
<div><Link href="/home/home"><div>去Home页面</div></Link></div>
</>
)
}
export default HomeA
inicioB.js
import React from "react";
import Link from "next/link";
const HomeB = () => {
return (
<>
<div>我是HomeB 页面</div>
<div><Link href="/home/home"><div>去Home页面</div></Link></div>
</>
)
}
export default HomeB
Modificar el contenido de la página de inicio
import React from "react"
import Link from "next/link"
function Home () {
return (
<div>
<div>home nextjs</div>
<div><Link href="/home/homeA"><div>去homeA页面</div></Link></div>
<div><Link href="/home/homeB"><div>去homeB页面</div></Link></div>
</div>
)
}
export default Home
En versiones anteriores, la etiqueta a debe estar conectada a la etiqueta Link. En la versión actual (13.4.19), si agrega la etiqueta a, se informará un error.
Módulo de enrutador para saltar (salto programático)
Modificar la página home.js
import React from "react"
import Router from "next/router"
const goHomeA = () => {
Router.push('/home/homeA')
}
const goHomeB = () => {
Router.push('/home/homeB')
}
function Home () {
return (
<div>
<div>home nextjs</div>
<div onClick={goHomeA}>去homeA页面</div>
<div onClick={goHomeB}>去homeB页面</div>
</div>
)
}
export default Home
pasar para recibir
Next.js solo puede pasar parámetros a través de consultas
Con pestañas
Modificar la página home.js
import React from "react"
import Link from "next/link"
function Home () {
return (
<div>
<div>home nextjs</div>
<div><Link href="/home/homeA?name=张三&age=18"><div>张三</div></Link></div>
<div><Link href="/home/homeA?name=李四&age=20"><div>李四</div></Link></div>
</div>
)
}
export default Home
Modificar la página homeA.js
withRouter es un componente avanzado del marco Next.js, que se utiliza para manejar el enrutamiento.
import React from "react";
import Link from "next/link";
import { withRouter } from "next/router";
function Home () {
return (
<div>
<div>home nextjs</div>
<div><Link href="/home/homeA?name=张三&age=18"><div>写法一</div></Link></div>
<div><Link href={
{
pathname: '/home/homeA',
query: {
name: '李四',
age: 20
}
}}><div>写法二</div></Link></div>
</div>
)
}
export default withRouter(HomeA)
programático
import React from "react"
import Router from "next/router"
const goHomeA = () => {
Router.push('/home/homeA?name=张三&age=18')
}
const goHomeA2 = () => {
Router.push({
pathname: '/home/homeA',
query: {
name: '李四',
age: 20
}
})
}
function Home () {
return (
<div>
<div>home nextjs</div>
<div onClick={goHomeA}>写法一</div>
<div onClick={goHomeA2}>写法二</div>
</div>
)
}
export default Home
función de gancho
Historia
import React from "react"
import Router from "next/router"
Router.events.on('routeChangeStart', (...args) => {
console.log('routeChangeStart -> 路由开始变化', ...args)
})
Router.events.on('routeChangeComplete', (...args) => {
console.log('routeChangeComplete -> 路由结束变化', ...args)
})
Router.events.on("beforeHistoryChange", (...args) => {
console.log('beforeHistoryChange -> 在改变浏览器 history 之前触发', ...args)
})
Router.events.on('routeChangeError', (...args) => {
console.log('routeChangeError -> 跳转发生错误', ...args)
})
const goHomeA = () => {
Router.push('/home/homeA?name=张三&age=18')
}
const goHomeA2 = () => {
Router.push({
pathname: '/home/homeA',
query: {
name: '李四',
age: 20
}
})
}
function Home () {
return (
<div>
<div>home nextjs</div>
<div onClick={goHomeA}>写法一</div>
<div onClick={goHomeA2}>写法二</div>
</div>
)
}
export default Home
Picadillo
Router.events.on('hashChangeStart', (...args) => {
console.log('hashChangeStart -> 路由开始变化', ...args)
})
Router.events.on('hashChangeComplete', (...args) => {
console.log('hashChangeComplete -> 路由结束变化', ...args)
})
Obtenga datos remotos en getInitialProps
getInitialProps
React
Es un método estático colgado del componente.
Si está utilizando Next.js 9.3 o superior, le recomendamos que utilice getStaticProps
o getServerSideProps
en su lugar getInitialProps
.
La recomendación oficial es buscar
solicitud de recuperación
Cree una nueva página request.js en el directorio de páginas
import { withRouter } from "next/router";
function Request ({router, data}) {
return (
<>
<div>{router.name}</div>
<div>请求页面 {data} </div>
</>
)
}
Request.getInitialProps = async () => {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const json = await res.json()
console.log(json)
return { stars: json.stargazers_count }
}
export default withRouter(Request)
index.js
import Router from "next/router"
const goRequest = () => {
Router.push({
pathname: '/request',
query: {
name: '李四',
age: 20
}
})
}
export default function Home() {
return (
<>
<div>首页</div>
<div onClick={goRequest}>去Request页面</div>
</>
)
}
Cuando ejecuta la página, puede encontrar que getInitialProps
se ejecutará durante la representación del servidor y la representación del cliente.
- Cuando se accede a la página directamente mediante la actualización de la página, etc., se activará el
Nextjs
uso de la representación del lado del servidor para devolver los datos de la página.
En este momento getInitialProps
, se ejecutará en el lado del servidor y no en el lado del navegador.
- Cuando se accede a la página a través de un salto de enrutamiento del lado del navegador (como el navegador avanzando y retrocediendo), la representación de la página no activará la
Nextjs
representación del lado del servidor.
De hecho, getInitialProps
el método elegirá de forma independiente ejecutarse en el lado del Nodo o en el lado del Cliente de acuerdo con los diferentes terminales cuando se represente la página actual.
obtenerPropsEstáticos
getStaticProps
se solicitará en cada visita a la página
Modificar solicitud.js
import { withRouter } from "next/router";
function Request ({router, content}) {
return (
<>
<div>{router.name}</div>
<div>请求页面 {content} </div>
</>
)
}
export const getStaticProps = async () => {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const json = await res.json()
console.log(json)
return {
props: {
content: json.stargazers_count
}
};
};
export default withRouter(Request)
getStaticProps es una API para preejecutar el procesamiento realizado por getInitialProps en el momento de la compilación y pregenerar archivos estáticos. No se ejecutará en el cliente. Ejecute siempre en el lado del servidor.
obtener accesorios del lado del servidor
import { withRouter } from "next/router";
function Request ({router, content}) {
return (
<>
<div>{router.name}</div>
<div>请求页面 {content} </div>
</>
)
}
export const getServerSideProps = async context => {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
// if (!res) {
// notFound 强制页面跳转到 404
// return {
// notFound: true
// };
// redirect 来将页面重定向
// return {
// redirect: {
// destination: '/',
// permanent: false
// }
// };
// }
const json = await res.json()
console.log(json)
return {
props: {
content: json.stargazers_count
}
};
}
export default withRouter(Request)
A través de next.js
, getServerSideProps
podemos coordinar muy bien los datos de front-end y back-end durante el desarrollo. Algunos datos de inicialización de página y autenticación de página se pueden procesar getServerSideProps
directamente en, lo que puede simplificar enormemente la lógica de la página y garantizar la unidad de front-end y back-end. -fin.
JSX escribe el estilo CSS de la página.
Escritura básica
Crear una nueva página style.js
const Style = () => {
return (
<>
<div>style 页面</div>
<div className="base">基础</div>
<style jsx>
{`
.base {
color: blue;
font-size: 16px;
margin: 40px;
display: block;
}
`}
</style>
</>
)
}
export default Style
Cabe señalar que si se requiere jsx después del estilo, next.js agregará automáticamente un nombre de clase aleatorio para evitar la contaminación global de CSS. Por ejemplo, la base del código anterior se convertirá en base-xxxxxx
estilo dinámico
Modificar la página style.js
import React, {useState} from "react"
const Style = () => {
const [color, setColor] = useState('blue')
const [fontSize, setFontSize] = useState('16')
const [margin, setMargin] = useState('40')
const changeColor = () => {
setColor(color === 'blue' ? 'red': 'blue')
}
const changeFontSize = () => {
setFontSize(fontSize === '16' ? '20': '16')
}
const changeMargin = () => {
setMargin(margin === '10' ? '40': '10')
}
return (
<>
<div>style 页面</div>
<div className="base">基础</div>
<button onClick={changeColor}>改颜色</button>
<button onClick={changeFontSize}>改字体大小</button>
<button onClick={changeMargin}>改边距</button>
<style jsx>
{`
.base {
color: ${color};
font-size: ${fontSize}px;
margin: ${margin}px;
display: block;
}
`}
</style>
</>
)
}
export default Style
Carga diferida del módulo
Crear una nueva página import.js
Presentar la biblioteca dayjs
npm i dayjs
Si lo introducimos directamente en la página, se empaquetará y publicará en forma de biblioteca pública, incluso si no se utiliza la primera página del proyecto, se cargará, lo que es un desperdicio de recursos moment
.
Carga diferida de bibliotecas de terceros introducidas
importar.js
import React,{useState} from "react";
const Import = () => {
const [time, setTime] = useState()
const changeTime = async () => {
const dayjs = await import('dayjs')
setTime(dayjs.default(Date.now()).format('YYYY-MM-DD HH:mm:ss'))
}
return (
<>
<div>import 页面</div>
<div>当前时间为:{time}</div>
<button onClick={changeTime}>获取当前时间</button>
</>
)
}
export default Import
Puedes ver que lo introdujimos donde era necesario.
Tenga cuidado al utilizar el valor predeterminado para que surta efecto.
Carga diferida de componentes
Utilice dinámica para introducir la implementación de componentes.
import dynamic from 'next/dynamic'
const ButtonComponent = dynamic(() => import('@/components/buttonComponent'))
const Import = () => {
return (
<>
<div>import 页面</div>
<ButtonComponent>按钮</ButtonComponent>
</>
)
}
export default Import
Los componentes personalizados se cargan de forma diferida. Solo se cargarán cuando se jsx
utilicen . Si no se utilizan, no se cargarán.<ButtonComponent/>
componente de la cabeza
Para realizar mejor la optimización SEO, puede personalizar <Head>
las etiquetas usted mismo.
Crear página header.js
Next.js
Ha sido <Head>
encapsulado, es un componente en sí mismo y puede ser directamente
import Head from 'next/head'
const Header = ()=>{
return (
<>
<Head>
<title> 头部 </title>
</Head>
</>
)
}
export default Header
Uso de Ant Design UI en el marco Next.js
Ant Design es una biblioteca de componentes front-end de código abierto de Alibaba
Desde la perspectiva de React, es una biblioteca de componentes que encapsula algunos de los componentes más utilizados en desarrollo, permitiéndonos usarlos mediante una configuración simple.
Deje que Next.js admita la importación de archivos CSS
Primero cree páginas/_app.js (si no existe). Luego importe el styles.css
archivo.
Propiedades globales de las hojas de estilo.
La versión anterior puede admitir CSS a través de @zeit/next-sass , esto se eliminó en la nueva versión.
Next.js [name].module.css
admite módulos CSS a través de convenciones de nomenclatura de archivos
Los módulos CSS abarcan CSS creando automáticamente nombres de clases únicos. Esto le permite utilizar el mismo nombre de clase CSS en diferentes archivos sin preocuparse por conflictos.
Este comportamiento hace que los módulos CSS sean una forma ideal de incluir CSS a nivel de componente. Los archivos del módulo CSS se pueden importar a cualquier parte de la aplicación.
Si no se agrega el módulo next.js framework, se confundirá con un estilo global, lo que provocará conflictos y errores.
import styles from '@/styles/test.module.css'
const Ant = () => {
return (
<>
<div>Ant 页面</div>
<p className={styles.default}>测试</p>
</>
)
}
export default Ant
apoyo scss
instalar scss
npm install sass
El uso es consistente con CSS.
import styles from '@/styles/test.module.scss'
const Ant = () => {
return (
<>
<div>Ant 页面</div>
<p className={styles.default}>测试</p>
</>
)
}
export default Ant
instalar hormiga
npm install antd --save
Introducir hormiga y usar.
Crear una nueva página reaccionar.js
import React from 'react';
import { DatePicker } from 'antd';
const App = () => {
return <DatePicker />;
};
export default App;
Babel
Para evitar que webpack
todo el Ant Design
paquete se empaquete en el entorno de producción.
Necesitamos que uses babel
npm install --save babel-plugin-import
.babelrc
Cree un archivo en el directorio raíz del proyecto.
{
"presets":["next/babel"], //Next.js的总配置文件,相当于继承了它本身的所有配置
"plugins":[ //增加新的插件,这个插件就是让antd可以按需引入,包括CSS
[
"import",
{
"libraryName":"antd"
}
]
]
}
De esta manera, cuando usamos ese componente, lo empaquetamos. De manera similar, CSS también se empaqueta bajo demanda.
Empaquetado del entorno de producción de Next.js
Configurar la carpeta package.json
"start": "next start -p 8088"
Ejecutar embalaje
npm run build
Ejecute el archivo empaquetado
npm run start