jsp网站建立,沂源网站开发,昆明建设网站哪家好,天津响应式网页建设公司本教程用的Next.js 是 13 版本
Next.js 简介
完善的React项目#xff0c;搭建轻松自带数据同步#xff0c;解决服务端渲染最大难点丰富的插件灵活配置
创建第一个项目
手动创建
初始化
npm init安装所需要的依赖包
npm install --save react react-don next增加快捷命…本教程用的Next.js 是 13 版本
Next.js 简介
完善的React项目搭建轻松自带数据同步解决服务端渲染最大难点丰富的插件灵活配置
创建第一个项目
手动创建
初始化
npm init安装所需要的依赖包
npm install --save react react-don next增加快捷命令
scripts: {test: echo \Error: no test specified\ exit 1,dev: next,build: next build,start: next start},创建测试文件
在根目录下创建pages文件夹并在该文件下创建 index.js
pages 文件夹是Next 规定的在这个文件夹下写入的文件Next.js 会自动创建对应的路由
function Index() {return (divHalo Next.js/div)
}export default Index运行 npm run dev
creact-next-app 脚手架创建Next.js 项目
创建项目
npx create-next-applatest第一次创建项目若没有安装nextjs 会提示是否安装
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? /* // 配置什么导入别名运行 npm run dev
Next.js 的page和component
创建一个新的页面
在page目录下创建 about.js
function About () {return (divAbout nextjs/div)
}export default About访问 http://localhost:3000/about
在 Next.js 中一个 page页面 就是一个从 .js、jsx、.ts 或 .tsx 文件导出export的 React 组件 这些文件存放在 pages 目录下。每个 page页面都使用其文件名作为路由route
创建二级目录页面
在page目录下创建 home 文件 并在该文件下创建 home.js
function Home () {return (divhome nextjs/div)
}export default Home访问 http://localhost:3000/home/home
Component组件的制作
创建组件
在src目录下创建 components 目录并在该目录下创建 buttonComponent.js 文件
export default ({children})button{children}/button引用
在home.js 引入
import dynamic from next/dynamicconst ButtonComponent dynamic(() import(/components/buttonComponent),
// { ssr: false } // 是否关闭 ssr服务端渲染 默认是开启
)使用
ButtonComponent按钮/ButtonComponent路由
标签式跳转
在home页面新增两个页面
homeA.js
import React from react;
import Link from next/link;const HomeA () {return (div我是HomeA 页面/divdivLink href/home/homediv去Home页面/div/Link/div/)
}export default HomeAhomeB.js
import React from react;
import Link from next/link;const HomeB () {return (div我是HomeB 页面/divdivLink href/home/homediv去Home页面/div/Link/div/)
}export default HomeB修改home页面内容
import React from react
import Link from next/linkfunction Home () {return (divdivhome nextjs/divdivLink href/home/homeAdiv去homeA页面/div/Link/divdivLink href/home/homeBdiv去homeB页面/div/Link/div/div)
}export default Home早期版本 Link标签下是要接上a标签的当前版本13.4.19如果加上a标签会报错
Router模块进行跳转编程式跳转
修改home.js页面
import React from react
import Router from next/routerconst goHomeA () {Router.push(/home/homeA)
}const goHomeB () {Router.push(/home/homeB)
}function Home () {return (divdivhome nextjs/divdiv onClick{goHomeA}去homeA页面/divdiv onClick{goHomeB}去homeB页面/div/div)
}export default Home传参与接收
Next.js 只能通过 query 来传递参数
标签式
修改home.js页面
import React from react
import Link from next/linkfunction Home () {return (divdivhome nextjs/divdivLink href/home/homeA?name张三age18div张三/div/Link/divdivLink href/home/homeA?name李四age20div李四/div/Link/div/div)
}export default Home修改homeA.js页面
withRouter 是 Next.js 框架的高级组件用来处理路由用的
import React from react;
import Link from next/link;
import { withRouter } from next/router;function Home () {return (divdivhome nextjs/divdivLink href/home/homeA?name张三age18div写法一/div/Link/divdivLink href{{pathname: /home/homeA,query: {name: 李四,age: 20}}}div写法二/div/Link/div/div)
}export default withRouter(HomeA)编程式
import React from react
import Router from next/routerconst goHomeA () {Router.push(/home/homeA?name张三age18)
}const goHomeA2 () {Router.push({pathname: /home/homeA,query: {name: 李四,age: 20}})
}function Home () {return (divdivhome nextjs/divdiv onClick{goHomeA}写法一/divdiv onClick{goHomeA2}写法二/div/div)
}export default Home钩子函数
History
import React from react
import Router from next/routerRouter.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张三age18)
}const goHomeA2 () {Router.push({pathname: /home/homeA,query: {name: 李四,age: 20}})
}function Home () {return (divdivhome nextjs/divdiv onClick{goHomeA}写法一/divdiv onClick{goHomeA2}写法二/div/div)
}export default HomeHash
Router.events.on(hashChangeStart, (...args) {console.log(hashChangeStart - 路由开始变化, ...args)
})Router.events.on(hashChangeComplete, (...args) {console.log(hashChangeComplete - 路由结束变化, ...args)
})在getInitialProps中获取远端数据
getInitialProps 是挂在 React 组件上的静态方法
如果你使用的是 Next.js 9.3 或更高版本我们建议你使用 getStaticProps 或 getServerSideProps 来替代 getInitialProps。
官方推荐的是fetch
fetch 请求
在page目录新建一个request.js 页面
import { withRouter } from next/router;function Request ({router, data}) {return (div{router.name}/divdiv请求页面 {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/routerconst goRequest () {Router.push({pathname: /request,query: {name: 李四,age: 20}})
}export default function Home() {return (div首页/divdiv onClick{goRequest}去Request页面/div/)
}运行页面可以发现getInitialProps 会在服务端渲染时执行也会在客户端渲染时执行
当页面通过页面刷新等直接形式访问时会触发 Nextjs 使用服务端渲染的方式返回页面数据
此时 getInitialProps 会在服务端执行浏览器端不会执行
当页面通过浏览器端路由跳转的形式访问时如浏览器前进后退该页面渲染不会触发 Nextjs 服务端渲染
所以实际上 getInitialProps 方法会根据当前页面渲染时的端侧不同自主地选择在 Node 端还是 Client 端执行
getStaticProps
getStaticProps 会在每次页面访问时被请求
修改request.js
import { withRouter } from next/router;function Request ({router, content}) {return (div{router.name}/divdiv请求页面 {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是用于在构建时预先执行getInitialProps进行的处理并预先生成静态文件的API。 不会在客户端上运行。 始终在服务器端运行。
getServerSideProps
import { withRouter } from next/router;function Request ({router, content}) {return (div{router.name}/divdiv请求页面 {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)通过 next.js 的 getServerSideProps我们在开发中可以很好的协调前后端数据一些页面初始化数据、页面鉴权可以直接在 getServerSideProps 中进行处理这样可以大大简化页面逻辑还保障前后端的统一性。
JSX 编写页面的CSS样式
基础写法
新建style.js 页面
const Style () {return (divstyle 页面/divdiv classNamebase基础/divstyle jsx{.base {color: blue;font-size: 16px;margin: 40px;display: block;}}/style/)
}export default Style要注意style 后面要jsx next.js 会自动加入一个随机类名这样就防止CSS的全局污染如上述代码 base 会变成 base-xxxxxx
动态样式
修改style.js 页面
import React, {useState} from reactconst 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 (divstyle 页面/divdiv classNamebase基础/divbutton onClick{changeColor}改颜色/buttonbutton onClick{changeFontSize}改字体大小/buttonbutton onClick{changeMargin}改边距/buttonstyle jsx{.base {color: ${color};font-size: ${fontSize}px;margin: ${margin}px;display: block;}}/style/)
}export default Style模块懒加载
新建 import.js 页面
引入 dayjs 库
npm i dayjs如果我们在页面直接引入那它就会以公共库的形式进行打包发布就算项目第一个页面不使用moment也会进行加载这就是资源浪费
懒加载引入的第三方库
import.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 (divimport 页面/divdiv当前时间为{time}/divbutton onClick{changeTime}获取当前时间/button/)
}export default Import可以看到我们是在需要的地方才引入
要注意 使用 default 才能生效
懒加载组件
利用 dynamic 引入组件实现
import dynamic from next/dynamicconst ButtonComponent dynamic(() import(/components/buttonComponent))const Import () {return (divimport 页面/divButtonComponent按钮/ButtonComponent/)
}export default Import自定义组件是懒加载的只有在jsx里用到ButtonComponent/时才会被加载进来如果不使用就不会被加载
head 组件
那为了更好的进行SEO优化可以自己定制Head标签
创建header.js页面
Next.js已经把Head封装好了本身就是一个组件可以直接
import Head from next/headconst Header (){return (Headtitle 头部 /title /Head/)
}export default HeaderNext.js框架下使用Ant Design UI
Ant Design是一款阿里开源的前端组件库
从React的角度来讲它就是一个组件库里边封装了开发中最常用的一些组件让我们可以通过简单的配置就可以使用他们
让Next.js 支持引入CSS文件
首先创建一个 pages/_app.js如果不存在的话。 然后import 该 styles.css 文件。
样式表的全局特性
旧版本可以通过 zeit/next-sass 支持css这个在新版本中已移除
Next.js 通过 [name].module.css 文件命名约定来支持 CSS 模块
CSS 模块通过自动创建唯一的类名从而将 CSS 限定在局部范围内。 这使您可以在不同文件中使用相同的 CSS 类名而不必担心冲突。
此行为使 CSS 模块成为包含组件级 CSS 的理想方法。 CSS 模块文件 可以导入import到应用程序中的任何位置
不加module next.js框架会误以为是全局样式会引发冲突报错
import styles from /styles/test.module.cssconst Ant () {return (divAnt 页面/divp className{styles.default}测试/p/)
}export default Ant支持scss
安装scss
npm install sass用法与 css一致
import styles from /styles/test.module.scssconst Ant () {return (divAnt 页面/divp className{styles.default}测试/p/)
}export default Ant安装 ant
npm install antd --save引入 ant 并使用
新建react.js 页面
import React from react;
import { DatePicker } from antd;const App () {return DatePicker /;
};export default App;babel
为了不让webpack 把整个Ant Design的包都进行打包到生产环境
我们需要你用到 babel
npm install --save babel-plugin-import在项目根目录建立.babelrc文件
{presets:[next/babel], //Next.js的总配置文件相当于继承了它本身的所有配置plugins:[ //增加新的插件这个插件就是让antd可以按需引入包括CSS[import,{libraryName:antd}]]
}这样我们使用那个组件就打包那个组件,同样CSS也是按需打包的
Next.js生产环境打包
配置package.json 文件夹
start: next start -p 8088 运行打包
npm run build运行打包好的文件
npm run start