1. 注册路由
路由的注册和vue框架中类似,注册过后需要在地址栏输入你想要进去的页面。
// 引入
import { createRoot } from "react-dom/client";
import { createBrowserRouter,RouterProvider,Route,Link }from "react-router-dom";
// 引入组件
import Home from "./views/home/Home.jsx";
import User from "./views/user/User.jsx";
import Root from "./views/root/Root.jsx";
// 注册路由
const router = createBrowserRouter([
  {
    path: "/",
    element: <Home />,
  },
  {
    path: "user",
    element: <User />,
  },
  {
    path: "root",
    element: <Root />,
  },
]);
createRoot(document.getElementById("root")).render(<RouterProvider router={router} />);在实际中肯定不是通过在地址栏输入不同路由来切换页面的,接下来就通过标签和js语法写代码来实现页面(组件)的切换。
2. 切换路由——换组件
2.1. 利用标签跳<Link to="/路由名"></Link>
2.2. js跳转——useNavigate
// 引入
import { useNavigate } from "react-router-dom"; 
let router = useNavigate();
let fn = () => {
  // router('root');
  router({ pathname: "root" });
}3. 页面跳转传参
3.1. state传参——{state:传的参数}
传参:state中可以穿字符串、对象等等。
获取:目标页面通过官方提供的useLocation方法来接收传过来的参数,通过useLocation().state取到数据
// 传参
router({ pathname: "/root" },{state:{goodsname:"隔离",price:159}});
// 目标页面接收
import { useLocation } from "react-router-dom";
  let obj = useLocation();
  useEffect(() => {
    console.log(obj.state);
  }, []);
传的参数在网址中看不见。
3.2. url传参——?参数或search:'字符串参数'
传参:Link标签跳转:<Link to="/user?userid=12&username=rosy">user</Link>
js语法传参: router({ pathname: "/user", search:'userid=12&username=rosy' })
获取:useLocation().search
需要注意的是,这种传参方式,目标页面接收到的参数是query字符串,我们需要将这个字符串处理成对象的行,才能通过对象点语法取到数据。
import React from "react";
import { useLocation } from "react-router-dom";
export default function User() {
  let routes = useLocation();
  // 解析当前网站的querystring 例:'email=123&count=11'
  let querystring = (str) => {
    let obj = {};
    // ? 前面有就执行后面代码 没有就不执行
    // let arr = str.split('?')[1]?.split('&').map(el => el.split('='));
    // 易理解方法
    let query = str.split("?")[1];
    // 没传参
    if (!query) {
      return obj;
    }
    // 传参了,切割字符串
    let arr = query.split("&").map((el) => el.split("="));
    arr.forEach((el) => {
      // el=[['email','123],['page','22']]
      obj[el[0]] = el[1];
    });
    return obj;
  };
  let queryobj = querystring(routes.search);
  console.log(queryobj);
  return (
    <div>
      <h3>User</h3>
    </div>
  );
}

参数可以在网址中看到。
3.3. 动态路由传参
// 注册路由时
  {
    // 动态传参
    // path: "/login/:date",
    // 传多个
    path: "/login/:date/:time",
    element: <Login />,
  },
// 主页跳转到login页面
// router({ pathname: "/login/1234" });
// 传多个
router({ pathname: "/login/1234/hi" });
// login页面接收
let data = useParams();
console.log(data);参数可以在网址中看到。传过来的参数就是对象的形式,但不推荐使用,因为写代码时注册路由和跳转传参都要写,麻烦。
4. 嵌套路由(子路由)
注册路由:父路由的children属性,是个数组。
注:二级路由不能写成'/a1',这样写真正的网址是'http://ip:port/a1';
而'a1'指的网址是当前网页的网址的最后添加/a1,也就是'http://ip:port/user/a1
占位组件:<Outlet></Outlet>
// 注册子路由
{
  path: "/user",
  element: <User />,
  children: [
    {
      path: "/user/info",
      element: <Info />,
    },
    {
      path: "collection",
      element: <Collection />,
    },
  ],
}
// 父组件return的模板
<div>
  <h3>User</h3>
  <Link to='/user/info'>info</Link><br />
  <Link to='collection'>collection</Link>
  {/* 占位组件 */}
  <Outlet></Outlet>
</div>
5. 路由健全
5.1 路由守卫——loader
相当于vue中的路由守卫,有些页面需要一定条件才能访问,比如说个人中心页面需要登录过后才能访问。
// 独享守卫 写在单个路由中,作为属性
loader: () => {
    // 假设做是否登录判断
  if (false) {
    return null;
  } else {
    return redirect('/login')
  }
}
// 全局守卫 写在路由前面 作为函数
let loader = () => {
  // 假设做是否登录判断
  if (false) {
    return null;
  } else {
    return redirect("/login");
  }
};5.2 重定向——redirect
相当于自动帮你切网址



















