Siêu liên kết đã là một trong những viên ngọc của Web kể từ khi ra đời . Theo MDN, siêu liên kết là thứ tạo nên Web, một trang web. Mặc dù được sử dụng cho các mục đích như liên kết giữa các tài liệu, mục đích chính của nó là tham chiếu đến các trang web khác nhau có thể nhận dạng bằng một địa chỉ web duy nhất hoặc URL.
Định tuyến là một khía cạnh quan trọng của mỗi ứng dụng web cũng giống như siêu liên kết đến Web. Đây là một cơ chế mà qua đó các yêu cầu được định tuyến đến mã xử lý chúng. Liên quan đến định tuyến, các trang Next.js được tham chiếu và có thể nhận dạng bằng một đường dẫn URL duy nhất. Nếu Web bao gồm các trang web điều hướng được kết nối với nhau bằng siêu liên kết, thì mỗi ứng dụng Next.js bao gồm các trang có thể định tuyến (trình xử lý tuyến đường hoặc tuyến đường) được kết nối với nhau bằng bộ định tuyến.
Next.js có hỗ trợ tích hợp cho định tuyến có thể khó sử dụng để giải nén, đặc biệt là khi xem xét kết xuất và truy xuất dữ liệu. Là điều kiện tiên quyết để hiểu định tuyến phía máy khách trong Next.js, cần phải có tổng quan về các khái niệm như định tuyến, kết xuất và truy xuất dữ liệu trong Next.js.
Bài viết này sẽ có ích cho các nhà phát triển React đã quen thuộc với Next.js và muốn tìm hiểu cách xử lý định tuyến. Bạn cần có kiến thức thực tế về React và Next.js để tận dụng tối đa bài viết, bài viết chỉ nói về định tuyến phía máy khách và các khái niệm liên quan trong Next.js.
Điều bạn cần hiểu về việc hiển thị trong Next.js là mỗi trang đều được hiển thị trước cùng với mã JavaScript tối thiểu cần thiết để trang đó có thể tương tác hoàn toàn thông qua một quy trình được gọi là hydrat hóa. Cách Next.js thực hiện điều này phụ thuộc rất nhiều vào hình thức dựng trước: Tạo tĩnh hoặc Kết xuất phía máy chủ, cả hai đều được kết nối chặt chẽ với kỹ thuật truy xuất dữ liệu được sử dụng và được phân tách theo thời điểm HTML cho một trang được tạo.
Tùy thuộc vào yêu cầu truy xuất dữ liệu của bạn, bạn có thể thấy mình đang sử dụng các hàm truy xuất dữ liệu tích hợp như
Kết xuất trước (trước khi kết xuất — đến UI) bổ sung cho Định tuyến và kết hợp chặt chẽ với việc truy xuất dữ liệu — toàn bộ chủ đề của riêng nó trong Next.js. Vì vậy, trong khi các khái niệm này bổ sung cho nhau hoặc có liên quan chặt chẽ, bài viết này sẽ chỉ tập trung vào điều hướng đơn thuần giữa các trang (định tuyến), với các tham chiếu đến các khái niệm liên quan khi cần thiết.
Sau khi giải quyết vấn đề đó, chúng ta hãy bắt đầu với cốt lõi cơ bản: Next.js có bộ định tuyến dựa trên hệ thống tệp được xây dựng trên khái niệm về trang.
Một ứng dụng Next.js thông thường sẽ có cấu trúc thư mục với các thư mục cấp cao nhất như pages, public và styles.
Mỗi trang là một thành phần React:
Lưu ý: Lưu ý rằng các trang cũng có thể được gọi là "trình xử lý tuyến đường".
Thành phần
Các tuyến chỉ mục tự động hoạt động như tuyến mặc định cho mỗi thư mục và có thể loại bỏ sự trùng lặp trong đặt tên. Cấu trúc thư mục bên dưới hiển thị hai đường dẫn tuyến đường:
Việc loại bỏ rõ ràng hơn với các tuyến đường lồng nhau.
Hoặc loại bỏ sự trùng lặp đường dẫn với các tuyến đường chỉ mục và truy cập tuyến đường dành cho sách in tại
Các tuyến động cũng đóng vai trò quan trọng trong việc loại bỏ sự trùng lặp.
rất thừa, không thể mở rộng quy mô và có thể khắc phục bằng các tuyến động như:
Cú pháp ngoặc —
Các phân đoạn động của một tuyến đường được hiển thị dưới dạng tham số truy vấn có thể được truy cập trong bất kỳ thành phần kết nối nào có liên quan đến tuyến đường với đối tượng
Khi chúng ta xem xét ví dụ động, chúng ta đã biết cách nó giúp loại bỏ sự dư thừa khi tạo tệp cho một tuyến duy nhất để truy cập nhiều sách bằng ID của chúng. Nhưng có một điều khác mà chúng ta có thể làm.
Cụ thể, chúng ta có đường dẫn
Nếu chúng ta cập nhật đường dẫn để có nhiều phân đoạn hơn như danh mục, chúng ta có thể kết thúc với thứ gì đó như sau:
Hãy thêm năm phát hành:
Chúng tôi đã thay thế việc sử dụng các tệp được đặt tên cho các tuyến động, nhưng bằng cách nào đó vẫn kết thúc với một hình thức dự phòng khác. Vâng, có một cách khắc phục: Catch All Routes giúp loại bỏ nhu cầu về các tuyến được lồng sâu:
Nó sử dụng cùng cú pháp ngoặc vuông ngoại trừ việc nó được thêm tiền tố là ba dấu chấm. Hãy nghĩ về các dấu chấm như cú pháp lan truyền JavaScript. Bạn có thể tự hỏi: Nếu tôi sử dụng các tuyến catch-all, thì làm thế nào để tôi truy cập vào danh mục (
Sau đây là ví dụ thêm cho tuyến đường
Cũng giống như catch-all route, route
Điều này là do route catch-all là "strict". Nó khớp với slug hoặc trả về lỗi. Nếu bạn muốn tránh tạo các tuyến chỉ mục cùng với các tuyến bắt tất cả, bạn có thể sử dụng tuyến bắt tất cả tùy chọn thay thế.
Trong trường hợp này, tuyến bắt tất cả (slug) là tùy chọn và nếu không khả dụng, tuyến sẽ chuyển sang đường dẫn
Khi cần thiết, Next.js sẽ cho bạn biết về các xung đột tuyến dưới dạng lỗi. Khi không, nó sẽ áp dụng thứ tự ưu tiên cho các tuyến theo tính đặc thù của chúng.
Ví dụ, sẽ là lỗi nếu có nhiều hơn một tuyến động ở cùng một cấp độ.
Nếu bạn xem xét kỹ các tuyến đường được xác định bên dưới, bạn sẽ nhận thấy khả năng xảy ra xung đột.
Ví dụ, hãy thử trả lời câu hỏi này: route nào xử lý đường dẫn
Sau đây là thêm một số ví dụ:
API
API
Thành phần
Property
Có những cơ chế khác của thành phần
Mặc dù điều này cho phép Next.js nội suy href cho các tham số động, nhưng nó rất tẻ nhạt, dễ xảy ra lỗi và có phần bắt buộc, và hiện đã được sửa cho phần lớn các trường hợp sử dụng với bản phát hành Next.js 10.
Bản sửa lỗi này cũng tương thích ngược. Nếu bạn đã sử dụng cả
Các trường hợp sử dụng cho
Hãy xem kỹ đoạn trích dưới đây:
Các prop
Với đối tượng
Nếu bạn bao gồm một phân đoạn động trong
Ví dụ trên có các đường dẫn:

Kiểm tra

Bạn có thể tìm hiểu thêm về các thuộc tính này trong tài liệu mô-đun URL của Node.js.
Một trường hợp sử dụng hàm băm là liên kết đến các phần cụ thể trong một trang.
Siêu liên kết sẽ giải quyết thành
API
Nếu
Đối tượng
Cả hook
Đối tượng router cũng có các phương thức như
Tìm hiểu thêm về đối tượng router.
Cấu hình tuyến tùy chỉnh với
Đây là một mô-đun Node.js thông thường có thể được sử dụng để cấu hình một số hành vi Next.js nhất định.
Những thay đổi này sẽ tự động có hiệu lực trong ứng dụng của bạn với tất cả các đường dẫn
Cả đường dẫn cơ sở và các tính năng trailing slash chỉ có thể sử dụng với Next.js 9.5 trở lên.
Định tuyến là một khía cạnh quan trọng của mỗi ứng dụng web cũng giống như siêu liên kết đến Web. Đây là một cơ chế mà qua đó các yêu cầu được định tuyến đến mã xử lý chúng. Liên quan đến định tuyến, các trang Next.js được tham chiếu và có thể nhận dạng bằng một đường dẫn URL duy nhất. Nếu Web bao gồm các trang web điều hướng được kết nối với nhau bằng siêu liên kết, thì mỗi ứng dụng Next.js bao gồm các trang có thể định tuyến (trình xử lý tuyến đường hoặc tuyến đường) được kết nối với nhau bằng bộ định tuyến.
Next.js có hỗ trợ tích hợp cho định tuyến có thể khó sử dụng để giải nén, đặc biệt là khi xem xét kết xuất và truy xuất dữ liệu. Là điều kiện tiên quyết để hiểu định tuyến phía máy khách trong Next.js, cần phải có tổng quan về các khái niệm như định tuyến, kết xuất và truy xuất dữ liệu trong Next.js.
Bài viết này sẽ có ích cho các nhà phát triển React đã quen thuộc với Next.js và muốn tìm hiểu cách xử lý định tuyến. Bạn cần có kiến thức thực tế về React và Next.js để tận dụng tối đa bài viết, bài viết chỉ nói về định tuyến phía máy khách và các khái niệm liên quan trong Next.js.
Định tuyến và kết xuất
Định tuyến và kết xuất bổ sung cho nhau và sẽ đóng vai trò rất lớn trong suốt bài viết này. Tôi thích cách Gaurav giải thích chúng:Hãy dành năm phút để suy nghĩ về điều đó.Định tuyến là quá trình mà người dùng được điều hướng đến các trang khác nhau trên một trang web.
Kết xuất là quá trình đưa các trang đó vào UI. Mỗi khi bạn yêu cầu một tuyến đường đến một trang cụ thể, bạn cũng đang hiển thị trang đó, nhưng không phải mọi lần hiển thị đều là kết quả của một tuyến đường.
Điều bạn cần hiểu về việc hiển thị trong Next.js là mỗi trang đều được hiển thị trước cùng với mã JavaScript tối thiểu cần thiết để trang đó có thể tương tác hoàn toàn thông qua một quy trình được gọi là hydrat hóa. Cách Next.js thực hiện điều này phụ thuộc rất nhiều vào hình thức dựng trước: Tạo tĩnh hoặc Kết xuất phía máy chủ, cả hai đều được kết nối chặt chẽ với kỹ thuật truy xuất dữ liệu được sử dụng và được phân tách theo thời điểm HTML cho một trang được tạo.
Tùy thuộc vào yêu cầu truy xuất dữ liệu của bạn, bạn có thể thấy mình đang sử dụng các hàm truy xuất dữ liệu tích hợp như
getStaticProps
, getStaticPaths
hoặc getServerSideProps
, các công cụ truy xuất dữ liệu phía máy khách như SWR, react-query hoặc các phương pháp truy xuất dữ liệu truyền thống như fetch-on-render, fetch-then-render, render-as-you-fetch (với Suspense).Kết xuất trước (trước khi kết xuất — đến UI) bổ sung cho Định tuyến và kết hợp chặt chẽ với việc truy xuất dữ liệu — toàn bộ chủ đề của riêng nó trong Next.js. Vì vậy, trong khi các khái niệm này bổ sung cho nhau hoặc có liên quan chặt chẽ, bài viết này sẽ chỉ tập trung vào điều hướng đơn thuần giữa các trang (định tuyến), với các tham chiếu đến các khái niệm liên quan khi cần thiết.
Sau khi giải quyết vấn đề đó, chúng ta hãy bắt đầu với cốt lõi cơ bản: Next.js có bộ định tuyến dựa trên hệ thống tệp được xây dựng trên khái niệm về trang.
Trang
Trang trong Next.js là các Thành phần React có sẵn tự động dưới dạng các tuyến. Chúng được xuất dưới dạng xuất mặc định từ thư mục trang với các phần mở rộng tệp được hỗ trợ như.js
, .jsx
, .ts
hoặc .tsx
.Một ứng dụng Next.js thông thường sẽ có cấu trúc thư mục với các thư mục cấp cao nhất như pages, public và styles.
Mã:
next-app├── node_modules├── pages│ ├── index.js // đường dẫn: base-url (/)│ ├── books.jsx // đường dẫn: /books│ └── book.ts // đường dẫn: /book├── public├── styles├── .gitignore├── package.json└── README.md
Mã:
// pages/books.js — `base-url/book`export default function Book() { return [HEADING=1]Sách[/HEADING]}
Các trang tùy chỉnh
Đây là các trang đặc biệt nằm trong thư mục pages nhưng không tham gia vào định tuyến. Chúng được thêm tiền tố là ký hiệu gạch dưới, như trong_app.js
và _document.js
.-
_app.js
Đây là một thành phần tùy chỉnh nằm trong thư mục pages. Next.js sử dụng thành phần này để khởi tạo các trang. -
_document.js
Giống như_app.js
,_document.js
là một thành phần tùy chỉnh mà Next.js sử dụng để tăng cường các thẻvà
của ứng dụng của bạn. Điều này là cần thiết vì các trang Next.js bỏ qua định nghĩa của đánh dấu tài liệu xung quanh.
Mã:
next-app├── node_modules├── pages│ ├── _app.js // ⚠️ Trang tùy chỉnh (không khả dụng dưới dạng tuyến đường)│ ├── _document.jsx // ⚠️ Trang tùy chỉnh (không khả dụng dưới dạng tuyến đường)│ └── index.ts // đường dẫn: base-url (/)├── public├── styles├── .gitignore├── package.json└── README.md
Liên kết giữa các trang
Next.js hiển thị thành phầnLink
từ API next/link
có thể được sử dụng để thực hiện chuyển đổi tuyến đường phía máy khách giữa các trang.
Mã:
// Nhập thành phần
[*] import Link from "next/link";// Đây có thể là một thành phần trangexport default function TopNav() { return ( Home Publications About )}// Đây có thể là một thành phần không phải trangexport default function Publications() { return ( {/* ... */} )}
Link
có thể được sử dụng bên trong bất kỳ thành phần nào, trang hoặc không. Khi được sử dụng ở dạng cơ bản nhất như trong ví dụ trên, thành phần Link
sẽ chuyển thành siêu liên kết có thuộc tính href
. (Thông tin thêm về Liên kết
trong phần tiếp theo/liên kết bên dưới.)Định tuyến
Hệ thống định tuyến dựa trên tệp Next.js có thể được sử dụng để xác định các mẫu định tuyến phổ biến nhất. Để phù hợp với các mẫu này, mỗi tuyến được phân tách dựa trên định nghĩa của nó.Các tuyến chỉ mục
Theo mặc định, trong ứng dụng Next.js của bạn, tuyến ban đầu/mặc định làpages/index.js
tự động đóng vai trò là điểm bắt đầu của ứng dụng của bạn dưới dạng /
. Với URL cơ sở là localhost:3000
, tuyến chỉ mục này có thể được truy cập ở cấp URL cơ sở của ứng dụng trong trình duyệt.Các tuyến chỉ mục tự động hoạt động như tuyến mặc định cho mỗi thư mục và có thể loại bỏ sự trùng lặp trong đặt tên. Cấu trúc thư mục bên dưới hiển thị hai đường dẫn tuyến đường:
/
và /home
.
Mã:
next-app└── pages ├── index.js // path: base-url (/) └── home.js // path: /home
Các tuyến đường lồng nhau
Một tuyến đường nhưpages/book
có độ sâu một cấp. Để đi sâu hơn là tạo các tuyến đường lồng nhau, đòi hỏi phải có cấu trúc thư mục lồng nhau. Với url cơ sở là https://www.smashingmagazine.com
, bạn có thể truy cập tuyến đường https://www.smashingmagazine.com/printed-books/printed-books
bằng cách tạo cấu trúc thư mục tương tự như bên dưới:
Mã:
next-app└── pages ├── index.js // tuyến đường chỉ mục hàng đầu └── printed-books // tuyến đường lồng nhau └── printed-books.js // đường dẫn: /printed-books/printed-books
https://www.smashingmagazine.com/printed-books
.
Mã:
next-app└── pages ├── index.js // tuyến chỉ mục hàng đầu └── printed-books // tuyến lồng nhau └── index.js // đường dẫn: /printed-books
Các tuyến động
Từ ví dụ trước, chúng ta sử dụng tuyến chỉ mục để truy cập tất cả các sách đã in. Để truy cập từng cuốn sách, cần tạo các tuyến khác nhau cho từng cuốn sách như sau:
Mã:
// ⚠️ Đừng làm như vậy.next-app└── trang ├── index.js // tuyến chỉ mục hàng đầu └── printed-books // tuyến lồng nhau ├── index.js // đường dẫn: /printed-books ├── typesript-in-50-lessons.js // đường dẫn: /printed-books/typesript-in-50-lessons ├── checklist-cards.js // đường dẫn: /printed-books/checklist-cards ├── ethical-design-handbook.js // đường dẫn: /printed-books/ethical-design-handbook ├── inclusive-components.js // đường dẫn: /printed-books/inclusive-components └── click.js // đường dẫn: /printed-books/click
Mã:
// ✅ Hãy thực hiện thao tác này thay thế.next-app└── pages ├── index.js // tuyến chỉ mục hàng đầu └── printed-books ├── index.js // đường dẫn: /printed-books └── [book-id].js // đường dẫn: /printed-books/:book-id
[book-id]
— là phân đoạn động và không chỉ giới hạn ở các tệp. Nó cũng có thể được sử dụng với các thư mục như ví dụ bên dưới, làm cho tác giả có sẵn tại tuyến đường /printed-books/:book-id/author
.
Mã:
next-app└── pages ├── index.js // top index route └── printed-books ├── index.js // path: /printed-books └── [book-id] └── author.js // path: /printed-books/:book-id/author
query
của hook useRouter()
— (Thông tin thêm về điều này trong API next/router section).
Mã:
// printed-books/:book-idimport { useRouter } from 'next/router';export default function Book() { const { query } = useRouter(); return ( [HEADING=1] book-id [I]{query['book-id']}[/I] [/HEADING] );}
Mã:
// /printed-books/:book-id/authorimport { useRouter } from 'next/router';export default function Author() { const { query } = useRouter(); return ( [HEADING=1] Lấy tác giả với book-id [I]{query['book-id']}[/I] [/HEADING] );}
Mở rộng các phân đoạn tuyến động với Catch All Routes
Bạn đã thấy cú pháp ngoặc phân đoạn tuyến động như trong ví dụ trước với[book-id].js
. Điểm tuyệt vời của cú pháp này là nó đưa mọi thứ đi xa hơn nữa với Catch-All Routes. Bạn có thể suy ra tác dụng của cú pháp này từ tên: nó bắt tất cả các tuyến.Khi chúng ta xem xét ví dụ động, chúng ta đã biết cách nó giúp loại bỏ sự dư thừa khi tạo tệp cho một tuyến duy nhất để truy cập nhiều sách bằng ID của chúng. Nhưng có một điều khác mà chúng ta có thể làm.
Cụ thể, chúng ta có đường dẫn
/printed-books/:book-id
, với cấu trúc thư mục:
Mã:
next-app└── pages ├── index.js └── printed-books ├── index.js └── [book-id].js
/printed-books/design/:book-id
, /printed-books/engineering/:book-id
hoặc tốt hơn nữa là /printed-books/:category/:book-id
.Hãy thêm năm phát hành:
/printed-books/:category/:release-year/:book-id
. Bạn có thấy một mẫu không? Cấu trúc thư mục trở thành:
Mã:
next-app└── pages ├── index.js └── printed-books └── [category] └── [release-year] └── [book-id].js
Mã:
next-app└── pages ├── index.js └── printed-books └── [...slug].js
[category]
) và năm phát hành ([release-year]
). Có hai cách:- Trong trường hợp ví dụ về printed-books, mục tiêu cuối cùng là cuốn sách và mỗi thông tin về cuốn sách sẽ có siêu dữ liệu được đính kèm hoặc
- Các phân đoạn "slug" được trả về dưới dạng một mảng các tham số truy vấn.
Mã:
import { useRouter } from 'next/router';export default function Book() { const { query } = useRouter(); // Có một khoảnh khắc ngắn mà `slug` không được xác định // vì vậy chúng ta sử dụng Optional Chaining (?.) và toán tử hợp nhất Nullish (??) // để kiểm tra xem slug có được xác định không, sau đó quay lại một mảng trống const [category, releaseYear, bookId] = query?.slug ?? []; trả về ( [TABLE] [TR] [TH]Mã số sách[/TH] [TD]{bookId}[/TD] [/TR] [TR] [TH]Thể loại[/TH] [TD]{category}[/TD] [/TR] [TR] [TH]Năm phát hành[/TH] [TD]{releaseYear}[/TD] [/TR] [/TABLE] );}
/printed-books/[…slug]
:Đường dẫn | Tham số truy vấn |
---|---|
/printed-books/click.js | { “slug”: [“click”] } |
/printed-books/2020/click.js | { “slug”: [“2020”, “click”] } |
/printed-books/design/2020/click.js | { “slug”: [“design”, “2020”, “click”] } |
/printed-books
sẽ trả về lỗi 404 trừ khi bạn cung cấp route index dự phòng.
Mã:
next-app└── pages ├── index.js └── printed-books ├── index.js // path: /printed-books └── [...slug].js
Mở rộng các phân đoạn tuyến động bằng các tuyến bắt tất cả tùy chọn
Cú pháp giống như catch-all-routes, nhưng thay vào đó là dấu ngoặc vuông đôi.
Mã:
next-app└── pages ├── index.js └── printed-books └── [[...slug]].js
/printed-books
, được hiển thị bằng tuyến [[…slug]].js
handler, không có bất kỳ tham số truy vấn nào."Sử dụng catch-all cùng với các tuyến chỉ mục hoặc chỉ sử dụng các tuyến catch-all tùy chọn. Tránh sử dụng các tuyến catch-all và các tuyến catch-all tùy chọn cùng nhau."
Thứ tự ưu tiên của các tuyến
Khả năng có thể xác định các mẫu định tuyến phổ biến nhất có thể là một "thiên nga đen". Khả năng xảy ra xung đột giữa các tuyến là một mối đe dọa đang rình rập, đặc biệt là khi bạn bắt đầu xử lý các tuyến động.Khi cần thiết, Next.js sẽ cho bạn biết về các xung đột tuyến dưới dạng lỗi. Khi không, nó sẽ áp dụng thứ tự ưu tiên cho các tuyến theo tính đặc thù của chúng.
Ví dụ, sẽ là lỗi nếu có nhiều hơn một tuyến động ở cùng một cấp độ.
Mã:
// ❌ Đây là lỗi// Không tải lại được các tuyến động: Lỗi: Bạn không thể sử dụng các tên slug khác nhau cho // cùng một đường dẫn động ('book-id' !== 'id').next-app└── pages ├── index.js └── printed-books ├── [book-id].js └── [id].js
Mã:
// Cấu trúc thư mục được làm phẳng để đơn giản hơnnext-app└── pages ├── index.js // tuyến đường chỉ mục (cũng là tuyến đường được xác định trước) └── printed-books ├── index.js ├── tags.js // tuyến đường được xác định trước ├── [book-id].js // xử lý tuyến đường động └── [...slug].js // xử lý catch all route
/printed-books/inclusive-components
?-
/printed-books/[book-id].js
, hay -
/printed-books/[…slug].js
.
- Có trình xử lý tuyến đường được xác định trước có thể xử lý tuyến đường không?
true
— xử lý yêu cầu tuyến đường.-
false
— chuyển đến 2.
- Có trình xử lý tuyến đường động có thể xử lý tuyến đường không?
true
— xử lý yêu cầu tuyến đường.-
false
— chuyển đến 3.
- Có trình xử lý tuyến đường catch-all có thể xử lý tuyến đường không?
true
— xử lý yêu cầu tuyến đường.-
false
— đưa ra lỗi 404 không tìm thấy trang.
/printed-books/[book-id].js
thắng.Sau đây là thêm một số ví dụ:
Tuyến đường | Trình xử lý tuyến đường | Loại tuyến đường |
---|---|---|
/printed-books | /printed-books | Tuyến đường chỉ mục |
/printed-books/tags | /printed-books/tags.js | Tuyến đường được xác định trước |
/printed-books/inclusive-components | /printed-books/[book-id].js | Động route |
/printed-books/design/inclusive-components | /printed-books/[...slug].js | Catch-all route |
API next/link
API next/link
trình bày thành phần Link
như một cách khai báo để thực hiện chuyển đổi tuyến đường phía máy khách.
Mã:
import Link from 'next/link'function TopNav() { return (
[*] Smashing Magazine Articles Guides Books )}
Link
sẽ giải quyết thành một siêu liên kết HTML thông thường. Nghĩa là, Smashing Magazine
sẽ giải quyết thành [URL=/]Smashing Magazine[/URL]
.Property
href
là prop duy nhất bắt buộc đối với thành phần Link
. Xem docs để biết danh sách đầy đủ các prop có sẵn trên thành phần Link
.Có những cơ chế khác của thành phần
Link
mà bạn cần lưu ý.Các tuyến đường có phân đoạn động
Trước Next.js 9.5.3,Liên kết
với các tuyến đường động có nghĩa là bạn phải cung cấp cả prop href
và as
cho Link
như trong:
Mã:
import Link from 'next/link';const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' },];export default function PrintedBooks() { return printedBooks.map((printedBook) => ( {printedBook.name} ));}
Bản sửa lỗi này cũng tương thích ngược. Nếu bạn đã sử dụng cả
as
và href
, không có gì bị hỏng. Để áp dụng cú pháp mới, hãy loại bỏ href
prop và giá trị của nó, rồi đổi tên as
prop thành href
như trong ví dụ bên dưới:
Mã:
import Link from 'next/link';const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' },];export default function PrintedBooks() { return printedBooks.map((printedBook) => ( {printedBook.name} ));}
Các trường hợp sử dụng cho passHref
Prop
Hãy xem kỹ đoạn trích dưới đây:
Mã:
import Link from 'next/link';const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' },];// Giả sử có một số kiểu dáng cơ sở được đính kèmfunction CustomLink({ href, name }) { return {name};}export default function PrintedBooks() { return printedBooks.map((printedBook) => ( ));}
passHref
buộc thành phần Link
truyền prop href
xuống thành phần con CustomLink
. Điều này là bắt buộc nếu thành phần Link
bao quanh một thành phần trả về thẻ siêu liên kết
. Trường hợp sử dụng của bạn có thể là do bạn đang sử dụng một thư viện như styled-components hoặc nếu bạn cần truyền nhiều phần tử con cho thành phần Link
vì nó chỉ mong đợi một phần tử con duy nhất.“Xem docs để tìm hiểu thêm.”
Đối tượng URL
Thuộc tínhhref
của thành phần Link
cũng có thể là một đối tượng URL có các thuộc tính như query
được định dạng tự động thành chuỗi URL.Với đối tượng
printedBooks
, ví dụ bên dưới sẽ liên kết đến:/printed-books/ethical-design?name=Ethical+Design
và-
/printed-books/design-systems?name=Design+Systems
.
Mã:
nhập Liên kết từ 'next/link';const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' },];export default function PrintedBooks() { return printedBooks.map((printedBook) => (
[*] {printedBook.name} ));}
pathname
, thì bạn cũng phải bao gồm nó như một thuộc tính trong đối tượng truy vấn để đảm bảo truy vấn được nội suy trong pathname
:
Mã:
import Link from 'next/link';const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' },];// Trong trường hợp này, phân đoạn động `[book-id]` trong pathname// ánh xạ trực tiếp đến tham số truy vấn `book-id`export default function PrintedBooks() { return printedBooks.map((printedBook) => ( {printedBook.name} ));}
/printed-books/ethical-design
và-
/printed-books/design-systems
.
href
trong VSCode, bạn sẽ tìm thấy loại LinkProps
, với thuộc tính href
là loại Url
, có thể là string
hoặc UrlObject
như đã đề cập trước đó.
Kiểm tra
UrlObject
dẫn đến giao diện với các thuộc tính:
Bạn có thể tìm hiểu thêm về các thuộc tính này trong tài liệu mô-đun URL của Node.js.
Một trường hợp sử dụng hàm băm là liên kết đến các phần cụ thể trong một trang.
Mã:
nhập Liên kết từ 'next/link';const printedBooks = [{ name: 'Thiết kế đạo đức', id: 'thiết kế đạo đức' }];export default function PrintedBooks() { return printedBooks.map((printedBook) => (
[*] {printedBook.name} ));}
/printed-books/ethical-design#faq
.“Tìm hiểu thêm trong tài liệu.”
API next/router
Nếu next/link
là khai báo, thì next/router
là bắt buộc. Nó hiển thị một hook useRouter
cho phép truy cập vào đối tượng router
bên trong bất kỳ thành phần hàm nào. Bạn có thể sử dụng hook này để thực hiện định tuyến thủ công, đặc biệt là trong một số trường hợp nhất định khi next/link
không đủ hoặc khi bạn cần "hook" vào định tuyến.
Mã:
import { useRouter } from 'next/router';export default function Home() { const router = useRouter(); function handleClick(e) { e.preventDefault(); router.push(href); } return ( Click me )}
useRouter
là một hook của React và không thể sử dụng với các lớp. Cần đối tượng router
trong các thành phần lớp? Sử dụng withRouter
.
Mã:
import { withRouter } from 'next/router';function Home({router}) { function handleClick(e) { e.preventDefault(); router.push(href); } return ( Click me )}export default withRouter(Home);
Đối tượng router
Cả hook useRouter
và thành phần bậc cao withRouter
đều trả về một đối tượng router với các thuộc tính như pathname
, query
, asPath
và basePath
cung cấp cho bạn thông tin về trạng thái URL của trang hiện tại, locale
, locales
và defaultLocale
cung cấp thông tin về ngôn ngữ mặc định đang hoạt động, được hỗ trợ hoặc hiện tại.Đối tượng router cũng có các phương thức như
push
để điều hướng đến một URL mới bằng cách thêm một Mục nhập URL vào ngăn xếp lịch sử, replace
, tương tự như push nhưng thay thế URL hiện tại thay vì thêm mục nhập URL mới vào ngăn xếp lịch sử.Tìm hiểu thêm về đối tượng router.
Cấu hình tuyến tùy chỉnh với next.config.js
Đây là một mô-đun Node.js thông thường có thể được sử dụng để cấu hình một số hành vi Next.js nhất định.
Mã:
module.exports = { // tùy chọn cấu hình}
“Nhớ khởi động lại máy chủ của bạn bất cứ khi nào bạn cập nhậtnext.config.js
. Tìm hiểu thêm.”
Đường dẫn cơ sở
Có đề cập rằng tuyến đường ban đầu/mặc định trong Next.js làpages/index.js
với đường dẫn /
. Điều này có thể định cấu hình và bạn có thể biến tuyến đường mặc định của mình thành đường dẫn phụ của miền.
Mã:
module.exports = { // đường dẫn mặc định cũ: / // đường dẫn mặc định mới: /dashboard basePath: '/dashboard',};
/
được định tuyến đến /dashboard
.“Tính năng này chỉ có thể sử dụng với Next.js 9.5 trở lên. Tìm hiểu thêm.”
Dấu gạch chéo theo sau
Theo mặc định, dấu gạch chéo theo sau sẽ không khả dụng ở cuối mỗi URL. Tuy nhiên, bạn có thể chuyển đổi bằng cách:
Mã:
module.exports = { trailingSlash: true};
Mã:
# trailingSlash: false/printed-books/ethical-design#faq# trailingSlash: true/printed-books/ethical-design/#faq
Kết luận
Định tuyến là một trong những phần quan trọng nhất của ứng dụng Next.js của bạn và nó phản ánh trong bộ định tuyến dựa trên hệ thống tệp được xây dựng trên khái niệm về các trang. Các trang có thể được sử dụng để xác định các mẫu định tuyến phổ biến nhất. Các khái niệm về định tuyến và kết xuất có liên quan chặt chẽ với nhau. Hãy áp dụng các bài học trong bài viết này khi bạn xây dựng ứng dụng Next.js của riêng mình hoặc làm việc trên cơ sở mã Next.js. Và hãy xem các tài nguyên bên dưới để tìm hiểu thêm.Tài nguyên liên quan
- Tài liệu chính thức của Next.js dành cho Pages
- Tài liệu chính thức của Next.js dành cho việc tìm nạp dữ liệu
- Tài liệu chính thức của Next.js dành cho next.config.js
- Next.js 10: Tự động giải quyết
href
- Tài liệu chính thức của Next.js dành cho next/link
- Tài liệu chính thức của Next.js cho next/router
Đọc thêm
- Giới thiệu về khả năng kết hợp toàn bộ ngăn xếp
- Tạo số ngẫu nhiên duy nhất trong JavaScript bằng cách sử dụng các tập hợp
- GraphQL toàn bộ ngăn xếp với Next.js, Neo4j AuraDB và Vercel
- Cách trở thành diễn giả giỏi hơn tại các hội nghị