function kai(){
return (kai)
}
export default kai;
只要写完上面的代码,Next
框架就自动作好了路由,这个也算是Next的一个重要优点,给我们节省了大量的时间。
现在要作一个更深的页面,比如把有关博客的界面都放在这样的路径下http://localhost:3000/blog/nextBlog
,其实只要在pages
文件夹下再建立一个新的文件夹blog
,然后进入blog
文件夹,新建一个nextBlog.js
文件,就可以实现了。
nextBlog.js文件内容,我们这里就用最简单的写法了
export default ()=>
写完后,就可以直接在浏览器中访问了,是不是发现Next框架真的减轻了我们大量的工作。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-puLO2BAo-1628340314382)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210807084832562.png)]
- Component组件的制作
制作组件也同样方便,比如要建立一个kai组件,直接在components
目录下建立一个文件kai.js
,然后写入下面代码:
export default ({children})=>{children}
组件写完后需要先引入,比如我们在Index页面里进行引入:
import kai from ‘…/components/kai’
使用就非常简单了,直接写入标签就可以。
按钮
=====================================================================
页面跳转一般有两种形式,第一种是利用标签<Link>
,第二种是用js编程的方式进行跳转,也就是利用Router
组件。
- 标签式导航
在编写代码之前,先删除index.js
中的代码,保证代码的最小化。使用标签式导航需要先进行引入,代码如下:
import Link from ‘next/link’
然后新建两个页面kaiA.js
和kaiB.js
,新建后写个最简单的页面,能标识出来A、B两个页面就好。
// kaiA
import React from ‘react’
import Link from ‘next/link’
export default () => (
<>
返回首页
</>
)
写完A页面后,可以直接复制A页面的内容,然后修改一下就是B页面。
// kaiB
import React from ‘react’
import Link from ‘next/link’
export default () => (
<>
返回首页
</>
)
有了两个页面后,可以编写首页的代码,实现跳转了。
import React from ‘react’
import Link from ‘next/link’
const Home = () => (
<>
去kaiA界面
去kaiB界面
</>
)
export default Home
用<Link>
标签进行跳转是非常容易的,但是又一个小坑需要你注意一下,就是他不支持兄弟标签并列的情况。
去kaiA页面
前端博客
如果这样写会直接报错,报错信息如下
client pings, but there’s no entry for page: /_error
Warning: You’re using a string directly inside . This usage has been deprecated. Please add an tag as child of
但是你可以把这两个标签外边套一个父标签,就可以了,比如下面的代码就没有错误。
去kaiA页面
前端博客
通过标签跳转非常的简单,跟使用<a>
标签几乎一样。那再来看看如何用编程的方式进行跳转。
- Router模块进行跳转
在Next
框架中还可以使用Router模块进行编程式的跳转,使用前引入Router
,代码如下:
import Router from ‘next/router’
然后在Index.js
页面中加入,直接使用Router进行跳转就可以了。
<button onClick={()=>{Router.push(‘/kaiA’)}}>去kaiA页面
这样写只是简单,但是还是耦合性太高,跟Link标签没什么区别,你可以修改一下代码,把跳转放到一个方法里,然后调用方法。
import React from ‘react’
import Link from ‘next/link’
import Router from ‘next/router’
const Home = () => {
function gotoA(){
Router.push(‘/kaiA’)
}
return(
<>
去kaiA页面
前端博客
去kaiA页面
</>
)
}
export default Home
这样也是可以实现跳转的,而且耦合性也降低了,所以个人更喜欢这种跳转方式。
===============================================================================
项目开发中一般都不是简单的静态跳转,而是需要动态跳转的。动态跳转就是跳转时需要带一个参数或几个参数过去,然后在到达的页面接受这个传递的参数,并根据参数不同显示不同的内容。比如新闻列表,然后点击一个要看的新闻就会跳转到具体内容。这些类似这样的需求都都是通过传递参数实现的。
- 只能用query传递参数
这节课作一个“找小姐姐”的例子,通过这个例子来通俗易懂的讲解一下路由带参数的知识。在Next.js
中只能通过通过query(?id=1
)来传递参数,而不能通过(path:id
)的形式传递参数,这个一定要记住,在工作中很容易就容易记混。
现在我们改写一下pages文件夹下的index.js
文件。
import React from ‘react’
import Link from ‘next/link’
import Router from ‘next/router’
const Home = () => {
return(
<>
xiaobai
</>
)
}
export default Home
这样编写query参数就可以进行传递过去了,接下来就是要接受参数了。
- 接收传递过来的参数
现在还没有小姐姐对应的页面,所以我们要创建xiaojiejie.js
页面,并写下下面的代码。
import { withRouter} from ‘next/router’
import Link from ‘next/link’
const Xiaojiejie = ({router})=>{
return (
<>
</>
)
}
export default withRouter(Xiaojiejie)
withRouter
是Next.js框架的高级组件,用来处理路由用的,这里先学简单用法,以后还会学习的。通过这种方式就获得了参数,并显示在页面上了。
- 编程式跳转传递参数
回了<Link>
这种标签式跳转传递参数的形式,那编程式跳转如何传递那,其实也可以简单使用?加参数
的形式,代码如下:
选xiaohong
// gotoXiaojiejie
function gotoXiaojiejie(){
Router.push(‘/xiaojiejie?name=xiaohong’)
}
这种形式跳转和传递参数是完全没有问题的,但是不太优雅,所以也可以写成Object
的形式。
function gotoXiaojiejie(){
Router.push({
pathname:‘/xiaojiejie’,
query:{
name:‘xiaohong’
}
})
}
嗯,这样写确实优雅很多(我们一定要面向对象编程,有对象比没对象要好)。
其实<Link>
标签也可以写成这种形式,比如我们把第一个修改成这种形式.
在浏览器中预览一下,如果一切正常是可以顺利进行跳转,并接收到传递的值。这节课主要讲解了Next框架的路由跳转时带参数过去,然后用withRouter
进行接收。
=======================================================================
routerChangeStart
路由发生变化时
在监听路由发生变化时,我们需要用Router组件,然后用on
方法来进行监听,在pages
文件夹下的index.js
,然后写入下面的监听事件,这里我们只打印一句话,就不作其他的事情了。代码如下:
Router.events.on(‘routeChangeStart’,(…args)=>{
console.log(‘1.routeChangeStart->路由开始变化,参数为:’,…args)
})
这个时路由发生变化时,时间第一时间被监听到,并执行了里边的方法。
routerChangeComplete
路由变化开始时可以监听到,那结束时也时可以监听到的,这时候监听的事件是routerChangeComplete
。
Router.events.on(‘routeChangeComplete’,(…args)=>{
console.log(‘routeChangeComplete->路由结束变化,参数为:’,…args)
})
beforeHistoryChange
浏览器history触发前
history就是HTML中的API,如果这个不了解可以百度了解一下,Next.js
路由变化默认都是通过history进行的,所以每次都会调用。 不适用history的话,也可以通过hash
Router.events.on(‘beforeHistoryChange’,(…args)=>{
console.log(‘3,beforeHistoryChange->在改变浏览器 history之前触发,参数为:’,…args)
})
routeChangeError
路由跳转发生错误时
Router.events.on(‘routeChangeError’,(…args)=>{
console.log(‘4,routeChangeError->跳转发生错误,参数为:’,…args)
})
需要注意的是404找不到路由页面不算错误,这个我们就不演示了。
- 转变成hash路由模式
还有两种事件,都是针对hash的,所以现在要转变成hash模式。hash模式下的两个事件hashChangeStart
和hashChangeComplete
,就都在这里进行编写了。
Router.events.on(‘hashChangeStart’,(…args)=>{
console.log(‘5,hashChangeStart->hash跳转开始时执行,参数为:’,…args)
})
Router.events.on(‘hashChangeComplete’,(…args)=>{
console.log(‘6,hashChangeComplete->hash跳转完成时,参数为:’,…args)
})
在下面的jsx语法部分,再增加一个链接,使用hash来进行跳转,代码如下:
为了方便你学习,我这里给出index.js
的全部代码,你可以在练习时进行参考。
import React from ‘react’
import Link from ‘next/link’
import Router from ‘next/router’
const Home = () => {
function gotoXiaojiejie(){
Router.push({
pathname:‘/xiaojiejie’,
query:{
name:‘井空’
}
})
}
Router.events.on(‘routeChangeStart’,(…args)=>{
console.log(‘1.routeChangeStart->路由开始变化,参数为:’,…args)
})
Router.events.on(‘routeChangeComplete’,(…args)=>{
console.log(‘2.routeChangeComplete->路由结束变化,参数为:’,…args)
})
Router.events.on(‘beforeHistoryChange’,(…args)=>{
console.log(‘3,beforeHistoryChange->在改变浏览器 history之前触发,参数为:’,…args)
})
Router.events.on(‘routeChangeError’,(…args)=>{
console.log(‘4,routeChangeError->跳转发生错误,参数为:’,…args)
})
Router.events.on(‘hashChangeStart’,(…args)=>{
console.log(‘5,hashChangeStart->hash跳转开始时执行,参数为:’,…args)
})
Router.events.on(‘hashChangeComplete’,(…args)=>{
console.log(‘6,hashChangeComplete->hash跳转完成时,参数为:’,…args)
})
return(
<>
选井空
选井空
</>
)
}
export default Home
这节主要学习了路由的钩子事件,利用钩子事件是可以作很多事情的,比如转换时的加载动画,关掉页面的一些资源计数器…。
========================================================================================
在Next.js
框架中提供了getInitialProps
静态方法用来获取远端数据,这个是框架的约定,所以你也只能在这个方法里获取远端数据。不要再试图在声明周期里获得,虽然也可以在ComponentDidMount
中获得,但是用了别人的框架,就要遵守别人的约定。
- 安装和引入Axios插件
Axios
是目前最或的前端获取数据的插件了,也是由大神首推的数据接口请求插件,我在工作中也是一直在使用它,所以这里依然使用Axios
来进行远端数据请求。在请求前需要先安装Axios
插件。
打开终端,直接使用yarn命令进行安装。
yarn add axios
我使用的版本是0.19.0
,可能你学习的时候会稍有变化。安装完成后,在需要的页面中用import
引入axios
,代码如下:
import axios from ‘axios’
引入后,就可以使用getInitialProps
进行获取后端接口数据了。
getInitialProps
中获取数据
在xiaojiejie.js
页面中使用getInitialProps
,因为是远程获取数据,所以我们采用异步请求的方式。数据存在了Easy Mock
中,地址如下:
https://www.easy-mock.com/mock/5cfcce489dc7c36bd6da2c99/xiaojiejie/getList
(你可以自己作一个数据源,因为这个可能也不稳定,不过半年内应该是可以的)
Xiaojiejie.getInitialProps = async ()=>{
const promise =new Promise((resolve)=>{
axios(‘https://www.easy-mock.com/mock/5cfcce489dc7c36bd6da2c99/xiaojiejie/getList’).then(
(res)=>{
console.log(‘远程数据结果:’,res)
resolve(res.data.data)
}
)
})
return await promise
}
获得数据后,我们需要把得到的数据传递给页面组件,用{}
显示出来就可以了。
const Xiaojiejie = ({router,list})=>{
return (
<>
{list}
</>
)
}
这样我们就利用Axios从远端获取了数据,为了方便你学习,这里给出xiaojiejie.js
的所有代码。
import { withRouter} from ‘next/router’
import Link from ‘next/link’
import axios from ‘axios’
const Xiaojiejie = ({router,list})=>{
return (
<>
{list}
</>
)
}
Xiaojiejie.getInitialProps = async ()=>{
const promise =new Promise((resolve)=>{
axios(‘https://www.easy-mock.com/mock/5cfcce489dc7c36bd6da2c99/xiaojiejie/getList’).then(
(res)=>{
console.log(‘远程数据结果:’,res)
resolve(res.data.data)
}
)
})
return await promise
}
export default withRouter(Xiaojiejie)
================================================================================
在Next.js
中引入一个CSS样式是不可以用的,如果想用,需要作额外的配置。因为框架为我们提供了一个style jsx
特性,也就是把CSS用JSX的语法写出来。如果你以前学过Vue,那这种写法你是非常熟悉的。
- 初识
Style JSX
语法 把字体设成蓝色
在pages
文件夹下,新建一个kai.js
文件。然后写入下面的代码:
//kai.js
function kai(){
return (
<>
</>
)
}
export default kai
这个是一个最简单的页面,只在层中写了一句话。这时候我们想把页面中字的颜色变成蓝色,就可以使用Style JSX
语法。直接在<></>
之间写下如下的代码:
主要所有的css样式需要用{}
进行包裹,否则就会报错。这时候你打开浏览器进行预览,字体的颜色就变成了蓝色。
- 自动加随机类名 不会污染全局CSS
加入了Style jsx
代码后,Next.js
会自动加入一个随机类名,这样就防止了CSS的全局污染。比如我们把代码写成下面这样,然后在浏览器的控制台中进行查看,你会发现自动给我们加入了类名,类似jsx-xxxxxxxx
。
function kaikai(){
return (
<>
</>
)
}
export default kai
- 动态显示样式
Next.js
使用了Style jsx
,所以定义动态的CSS样式就非常简单,比如现在要作一个按钮,点击一下,字体颜色就由蓝色变成了红色。下面是实现代码。
import React, {useState} from ‘react’
function kai(){
//关键代码----------start-------
const [color,setColor] = useState(‘blue’)
const changeColor=()=>{
setColor(color==‘blue’?‘red’:‘blue’)
}
//关键代码----------end-------
return (
<>
</>
)
}
export default kai
这样就完成了CSS的动态显示,是不是非常容易。这节课主要学习了Style jsx
的一些知识,有了这些知识,可以让我们的页面开始漂亮起来了。
==============================================================================
当项目越来越大的时候,模块的加载是需要管理的,如果不管理会出现首次打开过慢,页面长时间没有反应一系列问题。这时候可用Next.js
提供的LazyLoading
来解决这类问题。让模块和组件只有在用到的时候在进行加载,一般我把这种东西叫做“懒加载”.它一般分为两种情况,一种是懒加载(或者说是异步加载)模块,另一种是异步加载组件。他们使用的方法也稍有不同,下面我们就来分别学习一下。
- 懒加载模块
这里使用一个在开发中常用的模块Moment.js
,它是一个JavaScript日期处理类库,使用前需要先进行安装,这里使用yarn
来进行安装。
yarn add momnet
然后在pages
文件夹下,新建立一个time.js
文件,并使用刚才的moment
库来格式化时间,代码如下:
import React, {useState} from ‘react’
import moment from ‘moment’
function Time(){
const [nowTime,setTime] = useState(Date.now())
const changeTime=()=>{
setTime(moment(Date.now()).format())
}
return (
<>
</>
)
}
export default Time
这个看起来很简单和清晰的案例,缺存在着一个潜在的风险,就是如何有半数以上页面使用了这个momnet
的库,那它就会以公共库的形式进行打包发布,就算项目第一个页面不使用moment
也会进行加载,这就是资源浪费,对于我这样有代码洁癖的良好程序员是绝对不允许的。下面我们就通过Lazy Loading
来进行改造代码。
import React, {useState} from ‘react’
//删除import moment
function Time(){
const [nowTime,setTime] = useState(Date.now())
const changeTime= async ()=>{ //把方法变成异步模式
const moment = await import(‘moment’) //等待moment加载完成
setTime(moment.default(Date.now()).format()) //注意使用defalut
}
return (
<>
</>
)
}
export default Time
这时候就就是懒加载了,可以在浏览器中按F12,看一下Network
标签,当我们点击按钮时,才会加载1.js
,它就是momnet.js
的内容。
- 懒加载自定义组件
懒加载组件也是非常容易的,我们先来写一个最简单的组件,在components
文件夹下建立一个one.js
文件,然后编写如下代码:
export default ()=>
有了自定义组件后,先要在懒加载这个组件的文件中引入dynamic
,我们这个就在上边新建的time.js
文件中编写了。
import dynamic from ‘next/dynamic’
引入后就可以懒加载自定义模块了,代码如下:
import React, {useState} from ‘react’
import dynamic from ‘next/dynamic’
const One = dynamic(import(‘…/components/one’))
function Time(){
const [nowTime,setTime] = useState(Date.now())
const changeTime= async ()=>{
const moment = await import(‘moment’)
setTime(moment.default(Date.now()).format())
}
return (
<>
</>
)
}
export default Time
写完代码后,可以看到自定义组件是懒加载的,只有在jsx
里用到<One/>
时,才会被加载进来,如果不使用就不会被加载。
当我们作的应用存在首页打开过慢和某个页面加载过慢时,就可以采用Lazy Loading
的形式,用懒加载解决这些问题。
============================================================================
既然用了Next.js
框架,你就是希望服务端渲染,进行SEO操作。那为了更好的进行SEO优化,可以自己定制<Head>
标签,定义<Head>
一般有两种方式,这节课都学习一下。
- 方法1:在各个页面加上
<Head>
标签
先在/pages
文件夹下面建立一个header.js
文件,然后写一个最简单的Hooks
页面,代码如下:
function Header(){
return (
}
export default Header
写完后到浏览器中预览一下,可以发现title部分并没有任何内容,显示的是localhost:3000/header
,接下来就自定义下<Head>
。自定义需要先进行引入next/head
。
import Head from ‘next/head’
引入后你就可以写一些列的头部标签了,全部代码如下:
import Head from ‘next/head’
function Header(){
return (
<>
</>
)
}
export default Header
这时候再打开浏览器预览,你发现已经有了title
。
- 方法2:定义全局的
<Head>
这种方法相当于自定义了一个组件,然后把<Head>
在组件里定义好,以后每个页面都使用这个组件,其实这种方法用处不大,也不灵活。因为Next.js
已经把<Head>
封装好了,本身就是一个组件,我们再次封装的意义不大。
比如在components
文件夹下面新建立一个myheader.js
,然后写入下面的代码:
import Head from ‘next/head’
结束
一次完整的面试流程就是这样啦,小编综合了腾讯的面试题做了一份前端面试题PDF文档,里面有面试题的详细解析,分享给小伙伴们,有没有需要的小伙伴们都去领取!