首页 > 其他分享 >React-Router V6

React-Router V6

时间:2024-09-03 08:55:16浏览次数:6  
标签:function return React let location V6 Router const

React-Router V6

React 路由原理

  • 不同的路径渲染不同的组件
  • 有两种实现方式
    • HashRouter:利用 hash 实现路由切换
    • BrowserRouter:实现 h5 Api 实现路由的切换

HashRouter

HashRouter

  • 利用 hash 实现路由切换

public\index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #root{
            border:1px solid red;
        }
    </style>
</head>
<body>
    <div id="root"></div>
    <ul>
        <li><a href="#/a">/a</a></li>
        <li><a href="#/b">/b</a></li>
    </ul>
    <script>
        // 当地址栏中路径中的hash值发生变化时,会执行回调函数
        window.addEventListener('hashchange',()=>{
            console.log(window.location.hash);
            let pathname = window.location.hash.slice(1);//把最前面的那个#删除
            root.innerHTML = pathname;
        });

    </script>
</body>
</html>

BrowserRouter

  • 利用 h5 Api 实现路由的切换
history

浏览器的 history 对象是 JavaScript BOM(Browser Object Model)的一部分,它提供了与浏览器历史记录进行交互的方法和属性。这个对象可以让你在用户的浏览历史中移动,类似于在浏览器中点击前进和后退按钮。

注意,由于安全原因,大多数浏览器都限制了 history 对象的使用。例如,你不能查看用户的历史记录(只能知道历史记录的数量),也不能跨域修改历史记录。此外,pushStatereplaceState 方法可能会受到浏览器的限制,防止你过于频繁地调用它们。

history.length

返回浏览器历史列表中的 URL 数量。这个数量包括当前页面。

history.back()

与在浏览器中点击后退按钮相同,使用户导航到前一个历史记录。

history.forward

与在浏览器中点击前进按钮相同,使用户导航到下一个历史记录。

history.go(n)

使用户导航到他们的历史记录中的特定点。这个 n 参数是一个整数,表示相对于当前页面的位置。例如,history.go(1) 相当于 history.forward()history.go(-1) 相当于 history.back()

history.pushState(state, title, url)

向历史堆栈添加一个新的状态和 URL,而不会刷新页面state 参数是一个与添加的历史记录相关联的状态对象,title 参数是新页面的标题(但大多数浏览器目前都忽略这个参数),url 参数是新历史记录的 URL。

history.replaceState(state, title, url)

更新当前历史记录的状态对象、标题和 URL,而不需要重新加载页面。参数的含义与 pushState 方法相同。

案例
  • 浏览器针对每个页面维护一个History栈,执行pushState函数可压入设定的url至栈顶,同时修改当前指针
  • 当执行backforward操作时,history 栈大小并不会改变(history.length 不变),仅仅移动当前指针的位置
  • 若当前指针在 history 栈的中间位置(非栈顶),此时执行 pushState 会在指针当前的位置添加此条目,并成为新的栈顶
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #root {
        border: 1px solid red;
        height: 20px;
        padding: 10px;
      }
    </style>
  </head>
  <body>
    <div id="root"></div>
    <script>
      var historyObj = window.history;
      var root = document.getElementById("root");
      function updateContent(pathname) {
        root.innerHTML = pathname;
      }
      window.addEventListener("popstate", (event) => {
        updateContent(window.location.pathname);
      });
      (function (historyObj) {
        let oldPushState = history.pushState;
        historyObj.pushState = function (state, title, pathname) {
          let result = oldPushState.apply(history, arguments);
          updateContent(pathname);
          return result;
        };
      })(historyObj);
      setTimeout(
        () => historyObj.pushState({ page: 1 }, "page1", "/page1"),
        1000
      );
      setTimeout(
        () => historyObj.pushState({ page: 2 }, "page2", "/page2"),
        2000
      );
      setTimeout(
        () => historyObj.pushState({ page: 3 }, "page3", "/page3"),
        3000
      );
      setTimeout(() => historyObj.back(), 4000);
      setTimeout(
        () => historyObj.pushState({ page: 4 }, "page4", "/page4"),
        5000
      );
      setTimeout(() => historyObj.go(1), 6000);
    </script>
  </body>
</html>

使用基本路由

安装

react-router-dom 是 React 中一个非常重要的库,它可以用于在你的 React 应用程序中添加路由功能。基本上,你可以使用它在你的应用程序中的不同部分之间导航,就像在不同的页面之间导航一样,但不需要重新加载整个应用程序。

  1. HashRouter:和 BrowserRouter 类似,HashRouter 是一个顶层的路由组件,它会为你的应用程序创建一个路由环境。不同之处在于,HashRouter 使用 URL 的 hash(#)部分来保持 UI 和 URL 的同步。它在历史记录管理上,所有的页面跳转、后退都可以通过 hash 实现,可以用于那些不能使用 HTML5 history API 的老式浏览器。
  2. Routes:在React Router v6中,Routes取代了v5中的Switch组件。它用于包含多个 Route 组件,并且只渲染与当前路径最匹配的 Route。注意,在 v6 中,RoutesRoute 的使用方式有所变化,所有的 Route 都需要作为 Routes 的子组件。
  3. Route:这是最基本的组件,用于在应用程序中定义不同的路由。每个 Route 都有一个 path 属性,表示当 URL 与此路径匹配时应该渲染哪个组件。

在这个例子中,首先我们使用 HashRouter 包裹我们的应用程序。然后我们定义了 Routes 组件,所有的 Route 组件都被包含在其中。注意 Route 组件的新用法,我们将要渲染的组件作为 element 属性传递进去。当 URL 的路径与 Routepath 属性匹配时,就会渲染对应的 element

npm i react-router-dom history --save

src\index.js

Routes就是React-Router V5中的switch,有一组匹配上了,后面的就不匹配了

// 引入React核心库
import React from "react";
// 引入ReactDOM,用于DOM操作
import ReactDOM from "react-dom/client";
// 引入react-router-dom中的HashRouter, BrowserRouter, Routes, Route组件
import { HashRouter, BrowserRouter, Routes, Route } from "./react-router-dom";
// 引入Home组件
import Home from "./components/Home";
// 引入User组件
import User from "./components/User";
// 引入Profile组件
import Profile from "./components/Profile";
// 创建并渲染根组件
ReactDOM.createRoot(document.getElementById("root")).render(
  // 使用HashRouter包裹整个应用,实现哈希路由功能
  <HashRouter>
    // 定义路由规则
    <Routes>
      // 定义主页路由,当URL为'/'时渲染Home组件
      <Route path="/" element={<Home />} />
      // 定义用户页面路由,当URL为'/user'时渲染User组件
      <Route path="/user" element={<User />} />
      // 定义个人资料页面路由,当URL为'/profile'时渲染Profile组件
      <Route path="/profile" element={<Profile />} />
    </Routes>
  </HashRouter>
);

这段代码包括了React的引入,React DOM的引入,以及react-router-dom中的路由组件的引入。接着,它引入了三个自定义组件(Home、User、Profile),并使用ReactDOM.createRoot来渲染一个包含了HashRouterRoutes的React组件树。这为应用程序提供了基于哈希的路由功能,允许应用程序根据URL的不同部分来显示不同的组件。

Home.js

src\components\Home.js

import React from "react";
function Home(props) {
  console.log(props);
  return <div>Home</div>;
}
export default Home;

User.js

src\components\User.js

import React from "react";
function User() {
  return <div>User</div>;
}
export default User;

Profile.js

src\components\Profile.js

import React from "react";
function Profile() {
  return <div>Profile</div>;
}
export default Profile;

实现基本路由

react-router-dom\index.js

src\react-router-dom\index.js

// 导入React
import React from "react"; 
 // 从react-router中导入Router组件
import { Router } from "../react-router";
// 从history库中导入createHashHistory和createBrowserHistory函数
import { createHashHistory, createBrowserHistory } from "history"; 
// 导出react-router中的所有内容
export * from "../react-router"; 
// 定义一个HashRouter函数组件,接收children作为props
export function HashRouter({ children }) {
  // 使用useRef创建一个可变的ref对象,用于存储历史对象的引用
  let historyRef = React.useRef(); 
   // 如果historyRef的current属性为null,表示尚未创建历史对象
  if (historyRef.current == null) {
   // 创建一个哈希历史对象并赋值给historyRef的current属性
    historyRef.current = createHashHistory(); 
  }
  // 获取当前的历史对象
  let history = historyRef.current; 
  // 使用useState创建一个状态,存储当前的动作和位置
  let [state, setState] = React.useState({
    action: history.action,
    location: history.location,
  });
  //使用useLayoutEffect在历史对象发生变化时更新状态
  React.useLayoutEffect(() => history.listen(setState), [history]);
  // 渲染Router组件,并传递children、位置、导航类型和历史对象
  return (
    <Router
      children={children}
      location={state.location}
      navigationType={state.action}
      navigator={history}
    />
  ); 
}
// 定义一个BrowserRouter函数组件,接收children作为props
export function BrowserRouter({ children }) {
  // 使用useRef创建一个可变的ref对象,用于存储历史对象的引用
  let historyRef = React.useRef(); 
   // 如果historyRef的current属性为null,表示尚未创建历史对象
  if (historyRef.current == null) {
    // 创建一个浏览器历史对象并赋值给historyRef的current属性
    historyRef.current = createBrowserHistory();
  }
  // 获取当前的历史对象
  let history = historyRef.current; 
  // 使用useState创建一个状态,存储当前的动作和位置
  let [state, setState] = React.useState({
    action: history.action,
    location: history.location,
  });
   // 使用useLayoutEffect在历史对象发生变化时更新状态
  React.useLayoutEffect(() => history.listen(setState), [history]);
  //渲染Router组件,并传递children、位置、导航类型和历史对象
  return (
    <Router
      children={children}
      location={state.location}
      navigationType={state.action}
      navigator={history}
    />
  );
}

这段代码定义了两个 React 组件:HashRouterBrowserRouter。这两个组件都利用react-routerhistory库来创建和管理路由。HashRouter使用 URL 的哈希部分来处理路由,而BrowserRouter使用 HTML5 的历史 API。两者都通过监听历史对象的变化来更新路由状态,并将更新的状态传递给Router组件以实现路由导航。这种方式为 React 应用程序提供了灵活的路由管理能力。

src\react-router\index.js

src\react-router\index.js

// 导入React库
import React from "react";
// 创建导航上下文
const NavigationContext = React.createContext({});
// 创建位置上下文
const LocationContext = React.createContext({});
// 导出上下文
export { NavigationContext, LocationContext };
// 定义Router函数组件
export function Router({ children, location, navigator }) {
  // 使用useMemo钩子创建导航上下文对象
  const navigationContext = React.useMemo(() => ({ navigator }), [navigator]);
  // 使用useMemo钩子创建位置上下文对象
  const locationContext = React.useMemo(() => ({ location }), [location]);
  // 返回Router组件结构
  return (
    <NavigationContext.Provider value={navigationContext}>
      <LocationContext.Provider value={locationContext} children={children} />
    </NavigationContext.Provider>
  );
}
// 定义Routes函数组件
export function Routes({ children }) {
  // 使用useRoutes钩子创建路由
  return useRoutes(createRoutesFromChildren(children));
}
// 定义useLocation钩子
export function useLocation() {
  // 返回当前位置上下文的位置信息
  return React.useContext(LocationContext).location;
}
// 定义useSearchParams钩子
export function useSearchParams() {
  // 从位置上下文中获取当前位置
  const location = React.useContext(LocationContext).location;
  const pathname = location.pathname;
  // 返回当前URL的查询参数
  return new URLSearchParams(pathname.split("?")[1]);
}
// 定义useRoutes钩子
export function useRoutes(routes) {
  // 获取当前位置
  let location = useLocation(); 
  let pathname = location.pathname || "/"; 
  // 遍历路由数组匹配当前路径
  for (let i = 0; i < routes.length; i++) {
    let { path, element } = routes[i];
    let match = matchPath(path, pathname);
    if (match) {
      return element;
    }
  }
  return null;
}
// 从子元素创建路由数组
export function createRoutesFromChildren(children) {
  let routes = [];
  // 遍历子元素创建路由对象
  // 这是React提供的一个工具方法,可帮助遍历子元素,可以同时兼容单子元素,子元素数组
  React.Children.forEach(children, (element) => {
    let route = {
      path: element.props.path,
      element: element.props.element,
    };
    routes.push(route);
  });
  return routes;
}
// 定义Route函数组件(空实现)
export function Route(props) {}
// 编译路径为正则表达式
function compilePath(path) {
  let regexpSource = "^" + path;
  regexpSource += "$";
  let matcher = new RegExp(regexpSource);
  return matcher;
}
// 匹配路径和当前路径名
export function matchPath(path, pathname) {
  let matcher = compilePath(path);
  let match = pathname.match(matcher);
  if (!match) return null;
  return match;
}

这段代码是一个React路由管理工具的实现,包括创建上下文(NavigationContextLocationContext),定义路由器(Router)和路由(RoutesRoute),以及一些自定义钩子(useLocation, useSearchParams, useRoutes)用于管理路由状态和解析URL参数。核心功能是根据React的子组件定义动态路由,以及提供路径匹配功能。代码风格注重模块化和可复用性,适合用于构建复杂的单页应用程序。

实现 history

createBrowserHistory.js

src\history\createBrowserHistory.js

// 定义 createBrowserHistory 函数
function createBrowserHistory() {
  // 获取全局历史对象
  const globalHistory = window.history;
  // 定义状态变量
  let state;
  // 初始化监听器数组
  let listeners = [];
  // 添加历史监听器
  function listen(listener) {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter(item => item !== listener);
    };
  }
  // 前进或后退指定的历史记录条数
  function go(n) {
    globalHistory.go(n);
  }
  // 后退一条历史记录
  function goBack() {
    globalHistory.go(-1);
  }
  // 前进一条历史记录
  function goForward() {
    globalHistory.go(1);
  }
  // 添加新的历史记录
  function push(pathname, nextState) {
    const action = 'PUSH';
    if (typeof pathname === 'object') {
      state = pathname.state;
      pathname = pathname.pathname;
    } else {
      state = nextState;
    }
    globalHistory.pushState(state, null, pathname);
    let location = { pathname, state };
    notify({ action, location });
  }
  // 替换当前历史记录
  function replace(pathname, nextState) {
    const action = 'REPLACE';
    if (typeof pathname === 'object') {
      state = pathname.state;
      pathname = pathname.pathname;
    } else {
      state = nextState;
    }
    globalHistory.replaceState(state, null, pathname);
    let location = { pathname, state };
    notify({ action, location });
  }
  // 监听浏览器历史变化
  window.addEventListener('popstate', () => {
    let location = {
      state: globalHistory.state,
      pathname: window.location.pathname
    };
    notify({ action: 'POP', location });
  });
  // 通知所有监听器
  function notify({ action, location }) {
    history.action = action;
    history.location = location;
    history.length = globalHistory.length;
    listeners.forEach(listener => {
      listener({ action, location });
    });
  }
  // 初始化 history 对象
  const history = {
    action: 'POP',
    go,
    goBack,
    goForward,
    push,
    replace,
    listen,
    location: {
      pathname: window.location.pathname,
      state: globalHistory.state
    }
  };
  // 返回 history 对象
  return history;
}
// 导出 createBrowserHistory 函数
export default createBrowserHistory;

createBrowserHistory 函数用于创建一个自定义的浏览器历史管理对象。这个对象允许应用程序监听和操作浏览器的历史记录。它提供了几个关键功能:添加新的历史记录(push)、替换当前记录(replace)、前进和后退(gogoBackgoForward)、以及订阅历史变化事件(listen)。这个函数利用了浏览器的 History APIpopstate 事件来实现这些功能。

createHashHistory.js

src\history\createHashHistory.js

// 定义一个函数 createHashHistory
function createHashHistory() {
  // 声明一个栈来存储历史记录
  let stack = [];
  // 当前位置的索引
  let index = -1;
  // 当前动作(默认为'POP')
  let action = 'POP';
  // 当前的状态
  let state;
  // 监听函数数组
  let listeners = [];
  // 添加一个监听函数
  function listen(listener) {
    // 将监听器添加到数组中
    listeners.push(listener);
    // 返回一个函数,用于移除监听器
    return () => {
      listeners = listeners.filter(item => item !== listener);
    };
  }
  // 添加一个新的历史记录
  function push(pathname, nextState) {
    // 设置动作为'PUSH'
    action = 'PUSH';
    // 检查 pathname 是否为对象
    if (typeof pathname === 'object') {
      // 从对象中获取 state 和 pathname
      state = pathname.state;
      pathname = pathname.pathname;
    } else {
      // 使用提供的 nextState
      state = nextState;
    }
    // 更新浏览器的哈希值
    window.location.hash = pathname;
  }
  // 移动到历史记录中的某个位置
  function go(n) {
    // 设置动作为'POP'
    action = 'POP';
    // 更新索引
    index += n;
    // 获取新位置的历史记录
    let nextLocation = stack[index];
    // 更新状态
    state = nextLocation.state;
    // 更新浏览器的哈希值
    window.location.hash = nextLocation.pathname;
  }
  // 后退
  function goBack() {
    // 调用 globalHistory.go 函数后退一步
    globalHistory.go(-1);
  }
  // 前进
  function goForward() {
    // 调用 globalHistory.go 函数前进一步
    globalHistory.go(1);
  }
  // 处理哈希值变化的函数
  function handleHashChange() {
    // 获取新的 pathname
    const pathname = window.location.hash.slice(1);
    // 更新历史对象的 action
    history.action = action;
    // 构建新的 location 对象
    const location = {
      pathname,
      state
    };
    // 更新历史对象的 location
    history.location = location;
    // 如果是 PUSH 动作,更新栈和索引
    if (action === 'PUSH') {
      stack[++index] = location;
    }
    // 通知所有监听器
    listeners.forEach(listener => {
      listener({
        action,
        location
      });
    });
  }
  // 监听 hashchange 事件
  window.addEventListener('hashchange', handleHashChange);
  // 创建一个历史对象
  const history = {
    action: 'POP',
    go,
    goBack,
    goForward,
    push,
    listen,
    location: {
      pathname: undefined,
      state: undefined
    }
  };
  // 初始化历史对象
  if (window.location.hash) {
    action = 'PUSH';
    handleHashChange();
  } else {
    window.location.hash = '/';
  }
  // 返回创建的历史对象
  return history;
}
// 导出 createHashHistory 函数
export default createHashHistory;
  • createHashHistory 函数创建了一个自定义的历史对象,用于管理网页应用中的导航状态。
  • 使用栈结构来存储历史记录,通过 pushgo 方法来添加和移动历史记录。
  • listen 方法允许其他部分的代码注册监听器,这些监听器在历史记录改变时被调用。
  • handleHashChange 方法监听浏览器的 hashchange 事件,以响应 URL 的哈希部分的变化。
  • 最后,函数返回这个自定义历史对象,允许其他代码通过这个对象
  • react-router-dom V5 里当使用HashRouter的时候,如果没有默认hash会添加默认hash
  • 但是在react-router-dom V6里,里当使用HashRouter的时候,如果没有默认hash不会添加默认hash

history\index.js

src\history\index.js

export { default as createBrowserHistory } from "./createBrowserHistory";
export { default as createHashHistory } from "./createHashHistory";

react-router-dom\index.js

src\react-router-dom\index.js

import React from 'react'
import { Router } from '../react-router';
+import { createHashHistory, createBrowserHistory } from "../history";
export * from '../react-router';

export function HashRouter({ children }) {
    let historyRef = React.useRef();
    if (historyRef.current == null) {
        historyRef.current = createHashHistory();
    }
    let history = historyRef.current;
    let [state, setState] = React.useState({
        action: history.action,
        location: history.location
    });
    React.useLayoutEffect(() => history.listen(setState), [history]);
    return (
        <Router
            children={children}
            location={state.location}
            navigationType={state.action}
            navigator={history}
        />
    );
}

export function BrowserRouter({ children }) {
    let historyRef = React.useRef();
    if (historyRef.current == null) {
        historyRef.current = createBrowserHistory();
    }
    let history = historyRef.current;
    let [state, setState] = React.useState({
        action: history.action,
        location: history.location
    });
    React.useLayoutEffect(() => history.listen(setState), [history]);
    return (
        <Router
            children={children}
            location={state.location}
            navigationType={state.action}
            navigator={history}
        />
    );
}

path-to-regexp

/home 结束

let {pathToRegexp} = require("path-to-regexp");
let regxp = pathToRegexp("/home", [], { end: true });
console.log(regxp);// /^\/home[\/#\?]?$/i
console.log(regxp.test("/home"));
console.log(regxp.test("/home/2"));

image-20240901205652430

这个正则表达式 /^\/home[\/#\?]?$/i 用于匹配特定格式的字符串,具体解释如下:

  1. ^:表示字符串的开始。这个符号确保匹配必须从字符串的开始处进行。
  2. \/:匹配斜杠 /。在正则表达式中,斜杠是一个特殊字符,因此它前面有一个反斜杠用作转义字符。
  3. home:直接匹配文本 “home”。
  4. [\/#\?]:这是一个字符集,用于匹配集合中的任意一个字符。
    • \/:匹配一个斜杠 /
    • #:匹配井号 #
    • \?:匹配问号 ?。问号也是正则表达式中的特殊字符,所以需要用反斜杠进行转义。
  5. ?:表示前面的字符集 [\/#\?] 是可选的,即这个字符集中的字符出现零次或一次。
  6. $:表示字符串的结束。这个符号确保匹配必须在字符串的末尾结束。
  7. i:这是一个修饰符,表示匹配时不区分大小写。

综上所述,这个正则表达式用于匹配以下类型的字符串:

  • 它必须以 /home 开头。
  • /home 后面可以紧跟一个 /#? 中的任意一个字符,但这个字符是可选的。
  • 字符串必须以 /home/home 后紧跟的那个可选字符结束。
  • 匹配时不区分大小写。

例如,它可以匹配 /home/Home/home//home#/home?,但不会匹配 /homepage/home/123

/home 非结束

let {pathToRegexp} = require("path-to-regexp");
let regExp = pathToRegexp("/home", [], { end: false });
console.log(regExp);
// /^\/home(?:[\/#\?](?=[]|$))?(?=[\/#\?]|[]|$)/i   
console.log(regExp.exec("/home"));
console.log(regExp.exec("/home/"));
console.log(regExp.exec("/home//"));
console.log(regExp.exec("/home/2"));
console.log(regExp.exec("/home#"));
console.log(regExp.exec("/home#top"));
console.log(regExp.exec("/home?"));
console.log(regExp.exec("/home?a=1"));
console.log(/^\/home(?:[\/#\?](?=[]|$))?/.exec("/home?a=1"));

这个正则表达式用于匹配特定的 URL 路径。让我们分解并理解它的每个部分:

  1. ^: 这个字符表示正则表达式的开始。它确保匹配必须从字符串的开头开始。
  2. \/home: 这部分匹配字符串 “/home”。斜杠 (/) 被转义(即前面有一个反斜杠 \),这是因为在正则表达式中,斜杠是一个特殊字符,需要转义来表示它的字面值。
  3. (?:[\/#\?](?=[]|$))?: 这是一个非捕获组(由 (?: ... ) 表示),它用于对一组字符进行分组,但不保存该分组用于后续的引用。这个组的内容是:
    • [\/#\?]: 这是一个字符集,匹配一个字符,可以是 /# 或者 ?
    • (?=[]|$): 这是一个零宽正向前瞻断言,表示接下来的位置必须是正则表达式 []|$ 的起始位置。由于 [] 是一个空的字符集,所以这实际上等同于只检查 $(字符串的结尾)。
    • ?: 表示前面的非捕获组是可选的。
  4. (?=[\/#\?]|[]|$): 这又是一个零宽正向前瞻断言,用于确保当前位置后面是 [/#?] 中的一个字符,或者是字符串的结尾。
  5. i: 这是一个修饰符,表示正则表达式的匹配是不区分大小写的。

这个正则表达式用于匹配以 /home 开头的字符串,后面可以选择性地跟着一个 /#? 字符。如果有这些字符之一,它们必须是字符串的结尾或者紧跟着字符串的结尾。由于使用了 i 修饰符,所以匹配是不区分大小写的。

这种模式通常用于路由匹配,如在 web 应用中检测是否导航到了 “/home” 路径,且路径可能附带查询参数或哈希值。

路径参数

let params = [];
let regExp = pathToRegExp("/user/:id", params, { end: true });
console.log(regExp, params);
/**
/^\/user\/(?:([^\/]+?))\/?$/i
[ { name: 'id', optional: false, offset: 7 } ]
**/

正则匹配

  • 是否捕获
表达式含义
()表示捕获分组,()会把每个分组里的匹配的值保存起来,使用$n(n 是一个数字,表示第 n 个捕获组的内容)
(?

标签:function,return,React,let,location,V6,Router,const
From: https://blog.csdn.net/qq_40588441/article/details/141829055

相关文章

  • vue3 vue-router 的基本使用和配置方法
    在 vue3 中使用 vue-router 的基本步骤如下:1.安装vue-router:npminstallvue-router@42.创建一个 vue-router 实例并定义路由:import{createRouter,createWebHistory}from'vue-router';importHomefrom'./components/Home.vue';importAboutfrom'./com......
  • react-hook-form 搭配 next-intl 国际化插件 处理form 表单错误
    useEffect(()=>{ form.clearErrors() if(state&&state.data){ router.push('/') } //后台错误 if(state&&state.errorMessage){ //showErrorToast(t(state.errorMessage)) showErrorToast(state.errorMessage) } ......
  • Vue3 ref 和 reactive 的区别
    Vue3ref和reactive的区别文章目录Vue3ref和reactive的深度解析一、ref和reactive是什么二、vue3中如何使用ref和reactive三、ref和reactive包含哪些属性或方法API四、扩展与高级技巧五、优点与缺点六、对应“八股文”或面试常问问题七、总结与展望Vue3ref和......
  • 【vue、react】前端如何为package.json添加注释
    文章目录前言安装使用方法问题前言写了个项目,想给package.json加注释结果发现加不上去,就在网上查找了相关文章,特意总结记录一下,防止下次使用。参考文章:如何为package.json添加注释众所周知,JSON文件是不支持注释的,除了JSON5/JSONC之外,我们在开发项目特别是前端项目......
  • ReactJs:使用映射函数后我的父数组得到更新
    在React中,使用映射函数后父数组得到更新是正常的行为。映射函数会创建一个新的数组,其中包含了原始数组中每个元素经过映射操作后的结果。如果你希望在映射函数中修改原始数组,你可以使用forEach方法来遍历数组,并在遍历过程中修改元素。以下是一个示例:constparentArray=[1,2,......
  • React Native在移动端落地实践
    在移动互联网产品迅猛发展的今天,技术的不断创新使得企业越来越注重降低成本、提升效率。为了在有限的开发资源下迅速推出高质量、用户体验好的产品,以实现公司发展,业界催生了许多移动端跨平台解决方案。这些方案不仅简化了开发流程,还极大地提升了产品的兼容性和可维护性,确保企业能......
  • React MUI:值选择问题和缺少默认值
    在React和MUI(Material-UI)中,如果你遇到值选择问题或缺少默认值的情况,可能是以下原因导致的:未设置初始值:确保在组件的状态或属性中设置了适当的初始值。如果没有设置初始值,组件可能会显示为空或出现异常。未正确绑定值:在使用表单元素或其他可选择的组件时,确保将值正确地绑定到组件......
  • React Native在移动端落地实践
    在移动互联网产品迅猛发展的今天,技术的不断创新使得企业越来越注重降低成本、提升效率。为了在有限的开发资源下迅速推出高质量、用户体验好的产品,以实现公司发展,业界催生了许多移动端跨平台解决方案。这些方案不仅简化了开发流程,还极大地提升了产品的兼容性和可维护性,确保企业能够......
  • react创建项目&&常见的三大Hook
    react创建项目&&常见的三大Hook创建react脚手架项目全局安装create-react-app工具:npmi-gcreate-react-app查看安装工具的版本号,注意V大写create-react-app-V进入要创建的文件目录创建react项目,名为:react_projectcreate-react-appreact_project启动项目会默认3......
  • router+firewall+switch
    1、网络拓扑图2、核心配置1)端口ip地址intg0/0/0ipaddress10.1.2.224intg1/0/0ipaddress10.1.1.1242)加入trustuntrustdmzfirewallzonetrustaddintg0/0/0firewallzoneuntrustaddintg1/0/03)security-policysecurity-policyrulenameintoout source-zonetru......