整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          Laravel8系列之路由用法詳解

          Laravel8系列之路由用法詳解

          有 Laravel 路由都定義在位于 routes 目錄下的路由文件中,這些文件通過框架自動加載,相應邏輯位于 app/Providers/RouteServiceProvider 類。

          有時候還需要注冊一個路由響應多個 HTTP 請求動作 —— 這可以通過 match 方法來實現(xiàn)。或者,可以使用 any 方法注冊一個路由來響應所有 HTTP 請求動作:

          Route::match(['get', 'post'], 'foo', function () {
              return 'This is a request from get or post';
          });
          Route::any('bar', function () {
              return 'This is a request from any HTTP verb';
          });

          CSRF 保護

          routes/web.php 路由文件中所有請求方式為 PUTPOSTDELETE 的路由對應的 HTML 表單都必須包含一個 CSRF 令牌字段,否則,請求會被拒絕。

          <form method="POST" action="/profile">
              @csrf
              ...
          </form>

          如果我們不在 VerifyCsrfToken 中間件中排除對它的檢查,那么就需要在表單提交中帶上 csrf_token 字段

          重定向路由

          Route::redirect('/here', '/there', 301);

          視圖路由

          Route::view('hello', 'hello', ['name'=> '學院君']);

          然后在 resources/views 目錄下新建一個視圖模板文件 hello.blade.php,并初始化視圖模板代碼如下:

          <h1>
              Hello, {{ $name }}!
          </h1>

          路由參數(shù)

          Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
              return $postId . '-' . $commentId;
          });

          根據(jù)上面的示例,路由參數(shù)需要通過花括號 {} 進行包裹并且是拼音字母,這些參數(shù)在路由被執(zhí)行時會被傳遞到路由的閉包。路由參數(shù)名稱不能包含 - 字符,如果需要的話可以使用 _ 替代,比如如果某個路由參數(shù)定義成 {post-id} 則訪問路由會報錯,應該修改成 {post_id} 才行。路由參數(shù)被注入到路由回調(diào)/控制器取決于它們的順序,與回調(diào)/控制器名稱無關。

          有必選參數(shù)就有可選參數(shù),這可以通過在參數(shù)名后加一個 ? 標記來實現(xiàn),這種情況下需要給相應的變量指定默認值,當對應的路由參數(shù)為空時,使用默認值:

          Route::get('user/{name?}', function ($name='John') {
              return $name;
          });

          正則約束

          Route::get('user/{id}/{name}', function ($id, $name) {
              // 同時指定 id 和 name 的數(shù)據(jù)格式
          })->where(['id'=> '[0-9]+', 'name'=> '[a-z]+']);

          命名路由

          命名路由為生成 URL 或重定向提供了方便,實現(xiàn)起來也很簡單,在路由定義之后使用 name 方法鏈的方式來定義該路由的名稱:

          Route::get('user/profile', function () {
              // 通過路由名稱生成 URL
              return 'my url: ' . route('profile');
          })->name('profile');

          這樣我們就可以通過以下方式定義重定向:

          Route::get('redirect', function() {
              // 通過路由名稱進行重定向
              return redirect()->route('profile');
          });

          如果命名路由定義了參數(shù),可以將該參數(shù)作為第二個參數(shù)傳遞給 route 函數(shù)。給定的路由參數(shù)將會自動插入到 URL 中:

          Route::get('user/{id}/profile', function ($id) {
              $url=route('profile', ['id'=> 1]);
              return $url;
          })->name('profile');

          如果通過數(shù)組傳入額外參數(shù),這些鍵/值對將會自動添加到生成的 URL 查詢字符串:

          Route::get('user/{id}/profile', function ($id) {
              //todo
          })->name('profile');
          $url=route('profile', ['id'=> 1, 'photos'=> 'yes']); //photos是額外參數(shù)
          // /user/1/profile?photos=yes

          如果你想要判斷當前請求是否被路由到給定命名路由,可以使用 Route 實例上的 named 方法,例如,你可以從路由中間件中檢查當前路由名稱:

          public function handle($request, Closure $next)
          {
              if ($request->route()->named('profile')) {
                  //
              }
              return $next($request);
          }

          路由分組

          中間件

          要給某個路由分組中定義的所有路由分配中間件,可以在定義分組之前使用 middleware 方法。中間件將會按照數(shù)組中定義的順序依次執(zhí)行:

          Route::middleware(['first', 'second'])->group(function () {
              Route::get('/', function () {
                  // Uses first & second Middleware
              });
          
              Route::get('user/profile', function () {
                  // Uses first & second Middleware
              });
          });

          路由前綴

          prefix 方法可以用來為分組中每個路由添加一個給定 URI 前綴,例如,你可以為分組中所有路由 URI 添加 admin 前綴 :

          Route::prefix('admin')->group(function () {
              Route::get('users', function () {
                  // Matches The "/admin/users" URL
              });
          });

          這樣我們就可以通過 http://blog.test/admin/users 訪問路由了。

          兜底路由

          使用 Route::fallback 方法可以定義一個當所有其他路由都未能匹配請求 URL 時所執(zhí)行的路由。通常,未處理請求會通過 Laravel 的異常處理器自動渲染一個「404」頁面,不過,如果你在 routes/web.php 文件中定義了 fallback 路由的話,所有 web 中間件組中的路由都會應用此路由作為兜底,當然,如果需要的話,你還可以添加額外的中間件到此路由:

          Route::fallback(function () {
              //
          });

          注:兜底路由應該總是放到應用注冊的所有路由的最后。

          訪問頻率限制

          頻率限制器通過 RateLimiter 門面的 for 方法定義,該方法接收頻率限制器名稱和一個返回限制配置(會應用到頻率限制器分配到的路由)的閉包作為參數(shù):

          use Illuminate\Cache\RateLimiting\Limit;
          use Illuminate\Support\Facades\RateLimiter;
          
          RateLimiter::for('global', function (Request $request) {
              return Limit::perMinute(1000);
          });

          如果進入的請求量超過了指定的頻率限制上限,則會自動返回一個狀態(tài)碼為 429 的 HTTP 響應,如果你想要自己定義這個頻率限制返回的響應,可以使用 response 方法來定義:

          RateLimiter::for('global', function (Request $request) {
              return Limit::perMinute(1000)->response(function () {
                  return response('Custom response...', 429);
              });
          });

          由于頻率限制器回調(diào)接收的是輸入的 HTTP 請求實例,因此你可以基于用戶請求或者認證用戶動態(tài)構(gòu)建相應的頻率限制:

          RateLimiter::for('uploads', function (Request $request) {
              return $request->user()->vipCustomer()
                          ? Limit::none()
                          : Limit::perMinute(100);
          });

          有時候你可能希望通過特定值進一步對頻率限制進行細分。例如,你可能想要限定每分鐘每個 IP 地址對應的用戶只能訪問給定路由不超過 100 次,要實現(xiàn)這個功能,你可以在構(gòu)建頻率限制時使用 by 方法:

          RateLimiter::for('uploads', function (Request $request) {
              return $request->user()->vipCustomer()
                          ? Limit::none()
                          : Limit::perMinute(100)->by($request->ip());
          });

          如果需要的話,你可以為給定頻率限制器配置返回頻率限制數(shù)組,每個頻率限制都會基于在數(shù)組中的順序進行執(zhí)行:

          RateLimiter::for('login', function (Request $request) {
              return [
                  Limit::perMinute(500),
                  Limit::perMinute(3)->by($request->input('email')),
              ];
          });

          應用頻率限制器到路由

          訪問頻率限制器可以通過 throttle 中間件應用到路由或者路由群組。throttle 中間件接收頻率限制器的名稱作為參數(shù),然后再將其通過中間件的形式應用到路由即可:

          Route::middleware(['throttle:uploads'])->group(function () {
              Route::post('/audio', function () {
                  //
              });
          
              Route::post('/video', function () {
                  //
              });
          });

          來源

          https://gobea.cn/blog/detail/govQVn54.html

          TML 幫助器用于修改 HTML 輸出。


          HTML 幫助器

          通過 MVC,HTML 幫助器類似于傳統(tǒng)的 ASP.NET Web Form 控件。

          就像 ASP.NET 中的 Web Form 控件,HTML 幫助器用于修改 HTML。但是 HTML 幫助器是更輕量級的。與 Web Form 控件不同,HTML 幫助器沒有事件模型和視圖狀態(tài)。

          在大多數(shù)情況下,HTML 幫助器僅僅是一個返回字符串的方法。

          通過 MVC,您可以創(chuàng)建您自己的幫助器,或者直接使用內(nèi)建的 HTML 幫助器。


          標準的 HTML 幫助器

          MVC 包含了大多數(shù)常用的 HTML 元素類型的標準幫助器,比如 HTML 鏈接和 HTML 表單元素。


          HTML 鏈接

          呈現(xiàn) HTML 鏈接的最簡單的方法是使用 HTML.ActionLink() 幫助器。

          通過 MVC,Html.ActionLink() 不連接到視圖。它創(chuàng)建一個連接到控制器操作。

          Razor 語法:

          @Html.ActionLink("About this Website", "About")

          ASP 語法:

          <%=Html.ActionLink("About this Website", "About")%>

          第一個參數(shù)是鏈接文本,第二個參數(shù)是控制器操作的名稱。

          上面的 Html.ActionLink() 幫助器,輸出以下的 HTML:

          <a href="/Home/About">About this Website</a>

          Html.ActionLink() 幫助器的一些屬性:

          屬性描述
          .linkTextURL 文本(標簽),定位點元素的內(nèi)部文本。
          .actionName操作(action)的名稱。
          .routeValues傳遞給操作(action)的值,是一個包含路由參數(shù)的對象。
          .controllerName控制器的名稱。
          .htmlAttributesURL 的屬性設置,是一個包含要為該元素設置的 HTML 特性的對象。
          .protocolURL 協(xié)議,如 "http" 或 "https"。
          .hostnameURL 的主機名。
          .fragmentURL 片段名稱(定位點名稱)。

          注釋:您可以向控制器操作傳遞值。例如,您可以向數(shù)據(jù)庫 Edit 操作傳遞數(shù)據(jù)庫記錄的 id:

          Razor 語法 C#:

          @Html.ActionLink("Edit Record", "Edit", new {Id=3})

          Razor 語法 VB:

          @Html.ActionLink("Edit Record", "Edit", New With{.Id=3})

          上面的 Html.ActionLink() 幫助器,輸出以下的 HTML:

          <a href="/Home/Edit/3">Edit Record</a>


          HTML 表單元素

          以下 HTML 幫助器可用于呈現(xiàn)(修改和輸出)HTML 表單元素:

          • BeginForm()

          • EndForm()

          • TextArea()

          • TextBox()

          • CheckBox()

          • RadioButton()

          • ListBox()

          • DropDownList()

          • Hidden()

          • Password()

          ASP.NET 語法 C#:

          <%=Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>

          <% using (Html.BeginForm()){%>

          <p>

          <label for="FirstName">First Name:</label>

          <%=Html.TextBox("FirstName") %>

          <%=Html.ValidationMessage("FirstName", "*") %>

          </p>

          <p>

          <label for="LastName">Last Name:</label>

          <%=Html.TextBox("LastName") %>

          <%=Html.ValidationMessage("LastName", "*") %>

          </p>

          <p>

          <label for="Password">Password:</label>

          <%=Html.Password("Password") %>

          <%=Html.ValidationMessage("Password", "*") %>

          </p>

          <p>

          <label for="Password">Confirm Password:</label>

          <%=Html.Password("ConfirmPassword") %>

          <%=Html.ValidationMessage("ConfirmPassword", "*") %>

          </p>

          <p>

          <label for="Profile">Profile:</label>

          <%=Html.TextArea("Profile", new {cols=60, rows=10})%>

          </p>

          <p>

          <%=Html.CheckBox("ReceiveNewsletter") %>

          <label for="ReceiveNewsletter" style="display:inline">Receive Newsletter?</label>

          </p>

          <p>

          <input type="submit" value="Register" />

          </p>

          <%}%>


          果您是 React 開發(fā)人員,您很可能正在使用 Next.js,這是一個用于快速構(gòu)建和擴展 Web 應用程序的框架。

          或者,您可能沒有構(gòu)建企業(yè)級應用程序,而是使用 React Router 編寫一個小型 React 應用程序。

          不管怎樣,您可能熟悉路由的概念,但您知道它是如何工作的嗎?

          今天,我將帶頭嘗試重建 React Router 為您提供的路由器機制的一個相當精簡的版本,以及再次重新發(fā)明輪子并了解有關路由的更多信息的借口,所以讓我們開始路由器和我一起訓練和學習一些新東西,因為這是我第一次這樣做!

          如何?

          從現(xiàn)在開始,我所知道的就是 React Router API 的大致樣子,以及我們已經(jīng)可以使用 History API 將路由添加到 JavaScript 應用程序。

          當我必須為學校的項目編寫沒有框架的 JavaScript 應用程序時,我使用這個 Web API 來幫助我們在 JavaScript 應用程序中使用路由,而無需完全重新加載頁面來更改 URL。

          它確實是一個非常簡單的 API:您可以使用 JavaScript 更改 URL,它不會重新加載頁面并且......就是這樣!

          所有關于刷新 UI 的邏輯都將是我們的責任,但為此我們將使用 React,這樣我們就不會過度重新發(fā)明輪子......

          如果你不熟悉 History API,我建議你先停下來,通過閱讀官方文檔來了解一些關于它的知識,然后再回到這篇文章,以便我們可以一起學習如何實現(xiàn)我們自己的路由器組件因為我需要你!

          路由

          我想我們可以首先創(chuàng)建一個Route將路徑作為 prop 的組件,以及一個將是我們想要渲染的 JSX 的子組件。聽起來不錯?

          import { PropsWithChildren, FunctionComponent } from "react";
          
          export interface RouteProps {
            path: string;
          }
          
          export const Route: FunctionComponent<PropsWithChildren<RouteProps>>=({ path, children })=> {
            return null;
          };
          

          到目前為止,一切都很好。但我們立刻遇到了一個問題:我怎么知道我在哪條路線?

          也許,最簡單的方法是向 History API 詢問當前路徑。

          import { PropsWithChildren, FunctionComponent } from "react";
          
          export interface RouteProps {
            path: string;
          }
          
          export const Route: FunctionComponent<PropsWithChildren<RouteProps>>=({ path, children })=> {
            if (path===window.location.pathname) {
              return children;
            }
          
            return null;
          };
          

          這太棒了,如果我們要測試它,它完全可以工作!

          import { Route } from "./components/Route";
          
          export const App=()=> {
            return (
              <Route path="/home">
                <h1>Welcome to the home page!</h1>
              </Route>
            );
          };
          

          重定向

          讓我們嘗試添加一個鏈接,為我們的應用程序添加重定向功能。

          它將依賴該window.history.pushState方法將新頁面“推送”到客戶端的瀏覽器歷史記錄中。就像您點擊電子商務網(wǎng)站上的鏈接一樣。

          import { FunctionComponent, MouseEventHandler, PropsWithChildren, useCallback } from "react";
          
          export interface LinkProps {
            to: string;
          }
          
          export const Link: FunctionComponent<PropsWithChildren<LinkProps>>=({ to, children })=> {
            const onClick: MouseEventHandler<HTMLAnchorElement>=useCallback(event=> {
              event.preventDefault(); 
          
              window.history.pushState(to, to, null);
            }, [to]);
          
            return (
              <a href={to} onClick={onClick}>
                {children}
              </a>
            );
          };
          

          現(xiàn)在我們可以使用它在頁面之間導航。

          import { FunctionComponent, MouseEventHandler, PropsWithChildren, useCallback } from "react";
          
          export interface LinkProps {
            to: string;
          }
          
          export const Link: FunctionComponent<PropsWithChildren<LinkProps>>=({ to, children })=> {
            const onClick: MouseEventHandler<HTMLAnchorElement>=useCallback(event=> {
              event.preventDefault(); 
          
              window.history.pushState(null, to, to);
            }, [to]);
          
            return (
              <a href={to} onClick={onClick}>
                {children}
              </a>
            );
          };
          

          讓我們嘗試使用新的測試應用程序來測試它。

          import { Fragment } from "react";
          import { Route } from "./components/Route";
          import { Link } from "./components/Link";
          
          export const App=()=> {
            return (
              <Fragment>
                <header>
                  <ul>
                    <li>
                      <Link to="/">
                        Home
                      </Link>
                    </li>
                    <li>
                      <Link to="/about">
                        About
                      </Link>
                    </li>
                  </ul>
                </header>
                <main>
                  <Route path="/">
                    <h1>Welcome to the home page!</h1>
                  </Route>
                  <Route path="/about">
                    <h1>Welcome to the about page!</h1>
                  </Route>
                </main>
              </Fragment>
            );
          };
          

          好的,路由似乎在瀏覽器端工作,但在渲染的 React 應用程序上不起作用。為什么?

          因為當我們渲染Route組件時,我們沒有添加任何反應性數(shù)據(jù),也沒有添加反應性道具來反應,所以我們只在頁面加載后渲染它,就是這樣!

          如果您嘗試通過瀏覽器的搜索欄手動引導自己,您將看到渲染工作正常。這意味著我們必須使當前路由成為動態(tài)數(shù)據(jù)才能使路由正常工作。

          語境

          由于我們需要從Link組件傳遞已單擊的路由到Route組件,因此我們可以使用上下文來簡化這些組件之間的通信。

          我們開工吧!我們將從創(chuàng)建一個上下文開始。

          import { createContext } from "react";
          
          export const RouterContext=createContext({
            path: "",
            setPath: (path: string)=> {}
          });
          

          然后,我們將創(chuàng)建我們的提供者。

          import { FunctionComponent, PropsWithChildren, useMemo, useState } from "react";
          import { RouterContext } from "../contexts/RouterContext";
          
          export const RouterProvider: FunctionComponent<PropsWithChildren>=({ children })=> {
            const [path, setPath]=useState(window.location.pathname);
          
            const value=useMemo(()=> {
              return {
                path,
                setPath
              };
            }, [path, setPath]);
          
            return (
              <RouterContext.Provider value={value}>
                {children}
              </RouterContext.Provider>
            );
          };
          

          現(xiàn)在我們可以將此提供程序添加到我們的應用程序中。

          import { Route } from "./components/Route";
          import { Link } from "./components/Link";
          import { RouterProvider } from "./providers/RouterProvider";
          
          export const App=()=> {
            return (
              <RouterProvider>
                <header>
                  <ul>
                    <li>
                      <Link to="/">
                        Home
                      </Link>
                    </li>
                    <li>
                      <Link to="/about">
                        About
                      </Link>
                    </li>
                  </ul>
                </header>
                <main>
                  <Route path="/">
                    <h1>Welcome to the home page!</h1>
                  </Route>
                  <Route path="/about">
                    <h1>Welcome to the about page!</h1>
                  </Route>
                </main>
              </RouterProvider>
            );
          };
          

          我們可以開始在組件中添加新的上下文Link。

          import { FunctionComponent, MouseEventHandler, PropsWithChildren, useCallback, useContext } from "react";
          import { RouterContext } from "../contexts/RouterContext";
          
          export interface LinkProps {
            to: string;
          }
          
          export const Link: FunctionComponent<PropsWithChildren<LinkProps>>=({ to, children })=> {
            const { setPath }=useContext(RouterContext);
          
            const onClick: MouseEventHandler<HTMLAnchorElement>=useCallback(event=> {
              event.preventDefault(); 
          
              window.history.pushState(null, to, to);
              setPath(to);
            }, [to, setPath]);
          
            return (
              <a href={to} onClick={onClick}>
                {children}
              </a>
            );
          };
          

          也在我們的Route組件中。

          import { PropsWithChildren, FunctionComponent, useContext } from "react";
          import { RouterContext } from "../contexts/RouterContext";
          
          export interface RouteProps {
            path: string;
          }
          
          export const Route: FunctionComponent<PropsWithChildren<RouteProps>>=({ path, children })=> {
            const { path: currentPath }=useContext(RouterContext);
          
            if (path===currentPath) {
              return children;
            }
          
            return null;
          };
          

          巨大的成功!現(xiàn)在它運行良好,就像 React Router 一樣。

          訣竅是添加一個上下文,以便我們可以通知我們的組件在組件更改變量時Route對變量的任何更改做出反應。pathLink

          我們將 保留window.history.pushState在組件中Link是因為我們還需要在瀏覽器中反映路徑變化,而這個 API 就是為此目的而設計的。

          Fallback

          嗯,這個很棘手,因為我們無法查看源代碼是什么樣子,我們需要弄清楚這一點才能學習和成長。

          另一個上下文呢?這樣,我們可以創(chuàng)建一個Fallback組件,該組件能夠從父上下文中知道沒有可用的匹配路由,并且應該渲染該組件。

          因此,讓我們創(chuàng)建一個新的上下文,這次僅用于我們的路線。

          import { FunctionComponent, PropsWithChildren, useContext, useMemo, useState } from "react";
          import { RoutesContext } from "../contexts/RoutesContext";
          import { RouterContext } from "../contexts/RouterContext";
          
          export const Routes: FunctionComponent<PropsWithChildren>=({ children })=> {
            const { path }=useContext(RouterContext);
            const [routes, setRoutes]=useState<Array<string>>([]);
          
            const shouldFallback=useMemo(()=> {
              return !routes.some(route=> {
                return route===path;
              });
            }, [routes, path]);
          
            const value=useMemo(()=> {
              return {
                routes,
                setRoutes,
                shouldFallback
              };
            }, [routes, setRoutes, shouldFallback]);
          
            return (
              <RoutesContext.Provider value={value}>
                {children}
              </RoutesContext.Provider>
            );
          };
          

          我們不要忘記更新我們的Route組件,以便它為其父Routes組件注冊一個新的路由。

          import { PropsWithChildren, FunctionComponent, useContext, useEffect } from "react";
          import { RouterContext } from "../contexts/RouterContext";
          import { RoutesContext } from "../contexts/RoutesContext";
          
          export interface RouteProps {
            path: string;
          }
          
          export const Route: FunctionComponent<PropsWithChildren<RouteProps>>=({ path, children })=> {
            const { path: currentPath }=useContext(RouterContext);
            const { setRoutes }=useContext(RoutesContext);
          
            useEffect(()=> {
              setRoutes((routes: Array<string>)=> {
                return [
                  ...routes,
                  path
                ]
              });
            }, [path, setRoutes]);
          
            if (path===currentPath) {
              return children;
            }
          
            return null;
          };
          

          現(xiàn)在,我們可以編寫我們的Fallback組件了。

          import { FunctionComponent, PropsWithChildren, useContext } from "react";
          import { RoutesContext } from "../contexts/RoutesContext";
          
          export const Fallback: FunctionComponent<PropsWithChildren>=({ children })=> {
            const { shouldFallback }=useContext(RoutesContext);
          
            if (shouldFallback) {
              return children;
            }
          
            return null;
          };
          

          讓我們測試一下。

          import { Route } from "./components/Route";
          import { Link } from "./components/Link";
          import { RouterProvider } from "./providers/RouterProvider";
          import { Fallback } from "./components/Fallback";
          import { Routes } from "./components/Routes";
          
          export const App=()=> {
            return (
              <RouterProvider>
                <header>
                  <ul>
                    <li>
                      <Link to="/">
                        Home
                      </Link>
                    </li>
                    <li>
                      <Link to="/about">
                        About
                      </Link>
                    </li>
                    <li>
                      <Link to="/undefined">
                        Undefined
                      </Link>
                    </li>
                  </ul>
                </header>
                <main>
                <Routes>
                  <Route path="/">
                    <h1>Welcome to the home page!</h1>
                  </Route>
                  <Route path="/about">
                    <h1>Welcome to the about page!</h1>
                  </Route>
                  <Fallback>
                    <h1>Page not found</h1>
                  </Fallback>
                </Routes>
                </main>
              </RouterProvider>
            );
          };
          

          驚人的!只要我們位于正確的匹配頁面上,它就會正常工作并顯示我們的頁面,并且在沒有頁面與我們組件中的頁面匹配的情況下顯示后備頁面Route。

          結(jié)束了,各位!

          我們在那里做得非常好。我們有一個基本但功能齊全的路由應用程序,您可能已經(jīng)可以使用我們共同制作的組件了,這些組件是:

          • 組件RouterProvider,用于在組件之間共享當前路徑
          • 一個Routes組件,用于幫助Fallback組件知道何時渲染
          • 一個Fallback組件
          • 一個Link組件,用于更新當前路由
          • 一個Route組件,顯示當前匹配的路徑

          這甚至沒有觸及 React Router 庫的所有組件,本文甚至不是這個精彩而強大的庫的直接替代品!

          如果您想深入挖掘,您可以再次查看 React Router API,并嘗試通過添加更多組件(例如嵌套路由、編程路由、搜索參數(shù)等)來增強此示例...

          我希望您喜歡閱讀您所閱讀的內(nèi)容,并且它激勵您重新發(fā)明輪子,以便更多地了解您正在使用的工具。

          如果您想與我們分享精彩的內(nèi)容,請發(fā)表評論,我們下一篇文章見!


          主站蜘蛛池模板: 久久精品国产一区二区三| 精品国产一区二区三区四区| 日韩精品电影一区亚洲| 中文字幕一区在线观看| 视频精品一区二区三区| 国产一区二区三区在线看片| 久久精品国内一区二区三区| 蜜桃无码一区二区三区| 麻豆一区二区免费播放网站| 国产一区在线mmai| 亚洲国产一区视频| 亚洲码一区二区三区| 中文字幕在线观看一区| 亚洲av成人一区二区三区| 国产精品亚洲一区二区三区在线观看| 精品少妇人妻AV一区二区 | 国产福利一区视频| 日韩一区二区三区免费体验| 人妻AV中文字幕一区二区三区| 无码国产精品一区二区免费式直播 | 一区二区三区在线免费| 国产一区玩具在线观看| 在线视频一区二区三区| 日亚毛片免费乱码不卡一区 | 国模大胆一区二区三区| 国产亚洲欧洲Aⅴ综合一区| 日本内射精品一区二区视频 | 国产SUV精品一区二区88L| 亚洲片国产一区一级在线观看| 国产一区二区电影在线观看| 一区一区三区产品乱码| 农村人乱弄一区二区| 无码人妻精品一区二区蜜桃| 亲子乱AV视频一区二区| 日韩精品人妻av一区二区三区| 国产精品自拍一区| 亚洲熟女少妇一区二区| 国产AV一区二区精品凹凸 | 久久99国产一区二区三区| 精品欧洲av无码一区二区三区 | 人妻AV中文字幕一区二区三区|