路由到另外一個頁面_Nextjs使用解讀一(項目搭建與路由系統)

765b5fe1cb993878092e0366d57b05a8.png
文章說明:
1. 之前想搭建個人博客,由于學習的是react技術棧,所以就到處搜羅資料學了nextjs,配合koa就把博客搭起來了。該系列文章基于我的學習筆記,重新整理了一遍,如果有錯誤之處,還請指正。
2. 個人能力有限,我更注重的是使用,所以對于許多原理也只是簡單理解,并未深究。如果是想研究源碼,或者追求性能深度優化的老鐵,可以不用往下看了
3. 轉載請注明出處

各工具版本:npm v6.10,node v12.13,react v16.12,next v9.1

可能需要的預備知識:React項目經驗、nodejs開發經驗,webpack、npm等常用工具使用經驗。最好會koa(部分地方可能會用到)

一、Nextjs與服務端渲染

Nextjs的官方解釋:Next.js 是一個輕量級的 React 服務端渲染應用框架。

服務端渲染,顧名思義,就是在服務器上就把網頁渲染好了,你請求時,直接發給你渲染好的頁面。知道了原理,ssr的優勢劣勢也就很明顯了:

與客戶端渲染比較

優勢:
1. 更利于SEO,便于搜索引擎收錄。因為大多數爬蟲只會爬源碼,不會爬腳本,當服務端返回渲染好的數據后爬蟲便能直接爬取了。
2. 利于首屏加載。這個簡單,服務端發過來的就是渲染好的,客戶端就省事了,加載也就快了。

劣勢就是:1. 服務器的壓力大了(多了活要干);2. 對開發人員要求也高了
(深有體會,量發而行!這已經不屬純正血統的前端范疇了,因為要成功部署的話,你還不得不心甘情愿地去學點服務器知識、Linux運維、nginx部署等)

特別注意

  1. 當服務端渲染時,服務端是沒有window、document對象的(瀏覽器端才有),直接調用會報錯。想用這倆對象的話最好放在didAmount周期函數里,等組件掛載后再調用(其實從這一點來說,這只能算是半服務端渲染......扯遠了)
  2. 另外,Nextjs自帶的服務器專注于處理ssr部分,但后端往往還需要處理文件、連接數據庫等功能,此時還需要借助其他的node服務器,我這選用了koa2,然后讓nextjs作為koa的一個專門負責ssr的中間件。

二、搭建Nextjs項目

實踐出真知。介紹完了,作為正經的程序員,先上手一個再慢慢研究。我們按照官網的節奏,一步步搭建項目,再一步步解釋每個文件和目錄的作用

1. 搭建環境

  1. 隨便創建個項目目錄,如:demo
  2. 進入該目錄,npm初始化生成package.json:npm init
  3. npm安裝nextjs和其依賴:npm install next react react-dom
  4. 之后再修改package.json的scripts模塊:
{"scripts": {"dev": "next","build": "next build","start": "next start"}
}

說明:和react項目類似,這里的命令build即部署時的打包命令,start運行打包后的文件命令,dev則是開發環境下啟動nextjs服務器。

到這里,環境就算搭建好了。

2. 創建pages目錄

Nextjs的路由系統非常簡單,所有的路由頁面全部存放在pages目錄下,nextjs會自動對應page目錄的文件路徑生成對應路由。

如,我們在pages創建demo.js:

export default () => <div>This is the demo page</div>

然后啟動next服務器:npm run dev
命令行顯示如下時表示啟動成功了

D:webdemo>npm run dev> next_test@1.0.0 dev D:webdemo
> next[ wait ]  starting the development server ...
[ info ]  waiting on http://localhost:3000 ...

此時打開瀏覽器,進入localhost:3000/demo,便能看到頁面了

a8bb895d1f5b2b41a482ffab0898264a.png
路由/demo顯示界面

3._app.js和 _document.js

特別的,pages下有兩個特殊文件:_app.js和_document.js。這兩個文件默認是隱藏的,新建的話就會覆蓋之前的文件。他們分別用來自定義APP和自定義Document

自定義?什么意思?有什么用?簡單來說就是用來定義一些頁面共用的屬性(如設置全局css,通用布局等),或者定義一些通用的動作(如獲取、傳遞數據等), 這個結合nextjs的getInitialProps函數會更好說明,就留著后續講getInitialProps數據獲取和頁面布局的時候再一并解釋吧。

這篇文章我們主要關注路由系統。

三、路由系統

保證pages目錄的干凈

對于現在的組件化開發,我們通常會有兩種組件,一種作為某個獨立功能的小組件,一種是作為頁面顯示的頁面組件(通常結合了多個小組件),Nexjs同樣適用, 但小組件不能存儲在pages目錄下,這會導致路由系統混亂。我們可以新建一個components目錄(根據自己喜好自定義名字)來存儲小組件,在需要時從該目錄下import使用即可。

多級路由:
如果路由有多級,直接在pages下創立父級目錄,再把最終路由文件放入目錄下即可實現多級路由。如在pages目錄下創建user目錄,user下再創建index.js和home.js,那么路由/user就對應index.js文件,/user/home就對應home.js文件

路由跳轉

Nextjs官方推薦了兩種跳轉方式,一種是Link組件包裹,一種使用Router,我個人是不推薦Link的,原理也是用Router實現的,使用也簡單,但用起來總感覺很冗余。我這里主要介紹Router,想了解Link的老鐵得麻煩移步官網了。

Nextjs提供了一個'next/router'的包,專門用來處理路由。Router便是其中一個對象,Router.push('url')進行跳轉。
實踐一下:
1. pages目錄下,創建index.js文件

import React from 'react'     
import Router from 'next/router'export default () => {return(<><button onClick={()=>Router.push('/demo')} >送我去demo頁</button><div>這里是主頁</div></>)
}

2. 修改demo.js文件

import React from 'react'    
import Router from 'next/router'export default () => {return(<><button onClick={()=>Router.push('/')} >送我去主頁</button><div>這里是demo頁</div></>)
}

3. 運行結果

ef2733a64b18830b3c705bd2e7d92e1a.png

點擊“送我去demo頁”按鈕后

e216e43826da0e16adc367d3b7e65be0.png

路由參數

注意!注意!Nextjs不能使用params傳參數!只能通過query!

像這樣

Router.push('url?id=1')
等價
Router.push({pathname:'url',query:{id:1}})

另外,前面說過,服務端渲染時沒有window對象的,自然不能通過傳統途徑獲取url參數,這里'next/router'里提供了一個withRouter對象,用它包裹組件后,組件會多出router的參數,通過router就能獲取query參數了

import React from 'react'
import Router,{ withRouter } from 'next/router'const Demo = (props) => {return(<><button onClick={()=>Router.push('/')} >送我去主頁</button><div>這里是demo頁</div><div>{props.router.query.id}</div></>)
}
export default withRouter(Demo);

df237e7b065f9cd77c9b12897b9750a5.png
成功顯示id的值:1

路由映射

我們常看到的url是這樣的/url?id=1,而路由映射可以幫我們顯示成為這樣 /url/1,比較美觀友好(其實也就好一點點),這小節講解下路由映射,會涉及到koa使用,不感興趣的小伙伴直接跳過吧,畢竟也不是什么特別重要的

"表面上"的實現方法:

1. Router.push({ pathname: '/demo', query: { id: 1 } },'/demo/1')Router.push的第三個參數即可指定別名
2. Link組件中的as屬性<Link href='/demo?id=1' as='/demo/1'>

這樣看上去的確可以了,初始時也能訪問,但頁面一刷新就會404,為什么?因為當我們點擊按鈕在瀏覽器端跳轉時,是瀏覽器去找頁面,它通過路由映射可以找到。而刷新的時候,是服務器去找,而我們的pages頁面里面沒有/demo/1的文件,所以就報404了。

解決辦法,利用koa處理:

router.get('/demo/:id',async (ctx)=>{cosnt id = ctx.params.id await handle(ctx.req,ctx.res,{pathname:'/demo',query: {id}}),ctx.respond = false            
})

其實就是在服務器處又將路由轉換回來而已。

路由鉤子

Router中還定義了幾個鉤子函數用來獲取路由轉變時的狀態,方便我們在轉換路由時進行操作

// routeChangeStart     history模式路由改變剛開始  
// routeChangeComplete  history模式路由改變結束
// routeChangeError     路由改變失敗
// hashChangeStart      hash模式路由改變剛開始
// hashChangeComplete   hash模式路由改變結束Router.events.on(event,func())  //event即監聽的事件(以上5種),func回調函數
Router.events.off(event,func()) //取消監聽

好了,路由系統就講解到這了,下一篇文章會講解到nextjs的布局和getInitialProps()函數,順帶會把這期遺留的_app.js和_document.js一并解釋了。
喜歡的話歡迎分享,歡迎討論

歡迎關注我的其他平臺賬號: 【知乎】均遠 【公眾號】佛系前端 【個人博客】http://xujunyuan.com 【GitHub】JunYuanHub

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453748.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453748.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453748.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

微信獲取token -1000

最終翻看微信開發api找到需要去配置IP白名單。只需要配置訪問來源IP即可。 轉載于:https://www.cnblogs.com/yangjinqiang/p/8184663.html

產品技術和管理

為啥純粹為消費者傳遞體驗的活動可以價格不菲&#xff0c;幾為暴利&#xff1f;——談客戶體驗作為客戶價值提升之源 不論產品還是服務&#xff0c;如果能夠為消費者傳遞有益的體驗&#xff0c;其價值就可以在一般的產品服務之上得以體現&#xff1b;附加了體驗的產品&#xff…

Linux 修改系統編碼

linux服務器的字符集設置可能影響到網站頁面出現 “&#xff1f;&#xff1f;&#xff1f;” 等問號亂碼&#xff0c;還有可能導致文件中的漢字部分出現亂碼。有兩個原因 服務器沒有安裝 zh_CN.UTF-8 字符集&#xff0c;導致不支持中文&#xff01;服務器雖然裝了 zh_CN.UTF-8…

jquery ztree 設置勾選_047 JAVA-jQuery

jQuery操作元素屬性的值表單:<body><input type"button" name"" id"but1" value"測試獲得屬性值" /><hr />賬號&#xff1a;<input type"text" name"sxtzh" id"zhanghao" value&q…

Opencv undefined reference to `cv::imread() Ubuntu編譯

Ubuntu下編譯一個C文件&#xff0c;C源程序中使用了opencv&#xff0c;opencv的安裝沒有問題&#xff0c;但是在編譯的過程中出現如下錯誤&#xff1a; undefined reference to cv::imread(std::string const&, int)undefined reference to cv::noArray()undefined referen…

深度學習目標檢測之 YOLO v1

這是繼 RCNN&#xff0c;fast-RCNN 和 faster-RCNN 之后&#xff0c;rbg&#xff08;RossGirshick&#xff09;針對DL目標檢測速度問題提出的另外一種框架。YOLO V1 增強版本GPU中能跑45fps&#xff0c;簡化版本155fps。 論文名&#xff1a; 《You Only Look Once&#xff1a;…

編程珠璣番外篇

1.Plan 9 的八卦 在 Windows 下喜歡用 FTP 的同學抱怨 Linux 下面沒有如 LeapFTP 那樣的方便的工具. 在蘋果下面用慣了 Cyberduck 的同學可能也會抱怨 Linux 下面使用 FTP 和 SFTP 是一件麻煩的事情. 其實一點都不麻煩, 因為在 LINUX 系統上壓根就不需要用 FTP. 為什么呢? 因…

BT下載原理分析

版權聲明&#xff1a;本文為博主原創文章&#xff0c;未經博主允許不得轉載。 BitTorrent協議。 BT全名為BitTorrent,是一個p2p軟件,你在下載download的同時&#xff0c;也在為其他用戶提供上傳upload&#xff0c;因為大家是“互相幫助”&#xff0c;所以不會隨著用戶數的增加而…

表格列求和_excel表格制作,Excel表格的基本操作,包含制作一個表格10方面的知識...

創建表格&#xff0c;插入與刪除一行一列或多行多行&#xff0c;一次移動一行一列或多行多列&#xff0c;拆分與合并單元格&#xff0c;單元格內換行&#xff0c;表格求和與求平均值是Excel表格的基本操作&#xff1b;除此之外&#xff0c;Excel表格的基本操作還包括調整行高列…

深度學習之 FPN (Feature Pyramid Networks)

論文題目&#xff1a;Feature Pyramid Networks for Object Detection論文鏈接&#xff1a;https://arxiv.org/abs/1612.03144論文代碼&#xff1a;Caffe版本 https://github.com/unsky/FPN 《Feature Pyramid Networks for Object Detection》這篇論文主要解決的問題是目標檢…

ISLR—第二章 Statistical Learning

Statistical Learning Y 和X的關系why estimate f 用來預測 預測的時候可以將f^當成一個black box來用&#xff0c;目的主要是預測對應x時候的y而不關系它們之間的關系。用來推斷 推斷的時候&#xff0c;f^不能是一個black box&#xff0c;因為我們想知道predictor和response之…

提高編程思想

虛函數和抽象函數有什么區別 虛函數是有代碼的并明確允許子類去覆蓋&#xff0c;但子類也可不覆蓋,就是說可以直接用&#xff0c;不用重寫 抽象函數是沒有代碼&#xff0c;子類繼承后一定要重寫 ****************************************************************** 在一…

python特效代碼_網頁愛心特效弱爆了,我讓你點擊網頁顯示所有python模塊!

點擊網頁特效上周寫了一篇文章快速搭建個人博客的教程文章&#xff1a;其中說到了一個點擊網頁出現愛心特效的插件 click_heart.js ,當然大家可能也見過其他博客上面&#xff0c;有點擊網頁出現類似 富強、民主、文明、和諧等等&#xff0c;關于代碼在這里不多贅述&#xff0c;…

Python 包管理之 poetry

poetry是一個Python虛擬環境和依賴管理的工具。poetry和pipenv類似&#xff0c;另外還提供了打包和發布的功能。 官方文檔&#xff1a;python-poetry.org/docs/ python項目部署&#xff1a;poetry管理本地環境,上線用docker poetry 安裝 poetry提供多種安裝方式&#xff0c…

Windows數據庫編程接口簡介

數據庫是計算機中一種專門管理數據資源的系統&#xff0c;目前幾乎所有軟件都需要與數據庫打交道&#xff08;包括操作系統&#xff0c;比如Windows上的注冊表其實也是一種數據庫&#xff09;&#xff0c;有些軟件更是以數據庫為核心因此掌握數據庫系統的使用方法以及數據庫系統…

映客都是互刷禮物嗎_映客互刷禮物有什么用_映客守護有什么用

一起直播、互刷禮物、改ID發性感照,趙本山女375x332 - 122KB - PNG一起直播、互刷禮物、改ID發性感照,趙本山女600x893 - 247KB - JPEG一起直播、互刷禮物、改ID發性感照,趙本山女600x448 - 151KB - JPEG土豪互刷禮物嚇壞男主播 即興表演鐵頭功撞墻560x688 - 57KB - JPEG一起直…

Python 之打包工具 setup.py

1. 為什么需要對項目分發打包&#xff1f; 平常我們習慣了使用 pip 來安裝一些第三方模塊&#xff0c;這個安裝過程之所以簡單&#xff0c;是因為模塊開發者為我們默默地為我們做了所有繁雜的工作&#xff0c;而這個過程就是 打包。 打包&#xff0c;就是將你的源代碼進一步封…

周進度----06

周學習進度06 周學習進度06 第16周 所花時間&#xff1a; 60min60min100min100min100min100min90min60min60min 代碼量&#xff08;行&#xff09; 500-800 博客量&#xff08;篇&#xff09; 4 了解到的知識 css樣式表的一些知識 項目流程的初步了解 一周的學習心得…

八個實用的CMD命令及開始→運行→命令集錦

這篇文章是很久前收藏在自己筆記本內的,具體的來源地址不清楚,先謝一下原作者吧. 共享出來大家一起學習一下: 一&#xff0c;ping    它是用來檢查網絡是否通暢或者網絡連接速度的命令。作為一個生活在網絡上的管理員或者黑客來說&#xff0c;ping命令是第一個必須掌握的DO…

2019如何轉換2010_9102年,你還不知道PPT怎么轉換成視頻嗎?小心落伍了

你在刷抖音的時候有沒有刷過這類視頻&#xff1a;成為人生贏家必備的書單、5個讓你看透人性的電影、6個讓你升職加薪的APP...如果你細心觀察的話&#xff0c;會發現這類視頻的做法基本都是一個樣的&#xff0c;像在翻相冊一樣&#xff0c;一頁頁過去&#xff0c;所以它們也叫做…