React Router-v6.25.1

news2024/11/14 14:35:06

以下例子是根据vite+react+ts构建的,使用路由前先安装好这些环境!!!!

1、路由的简单使用

首先要创建一个浏览器路由器并配置我们的第一个路由。这将为我们的 Web 应用启用客户端路由。

main.jsx文件是入口点。打开它,我们将把 React Router 放到页面上。

import * as React from "react";
import * as ReactDOM from "react-dom/client";
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";
import "./index.css";

const router = createBrowserRouter([
  {
    path: "/",
    element: <div>Hello world!</div>,
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

我们通常将第一个路由称为“根路由”,因为其余路由将在其中呈现。它将作为 UI 的根布局,随着我们进一步深入,我们将拥有嵌套布局。

正常访问的页面因该是:

如果访问不存在的路由页面将是如下:

 2、创建根路径和错误页面

2.1、创建根布局组件(src/routes/root.tsx)

export default function Root() {
  return (
    <>
      <div id="sidebar">
        <h1>React Router Contacts</h1>
        <div>
          <form id="search-form" role="search">
            <input
              id="q"
              aria-label="Search contacts"
              placeholder="Search"
              type="search"
              name="q"
            />
            <div
              id="search-spinner"
              aria-hidden
              hidden={true}
            />
            <div
              className="sr-only"
              aria-live="polite"
            ></div>
          </form>
          <form method="post">
            <button type="submit">New</button>
          </form>
        </div>
        <nav>
          <ul>
            <li>
              <a href={`/contacts/1`}>Your Name</a>
            </li>
            <li>
              <a href={`/contacts/2`}>Your Friend</a>
            </li>
          </ul>
        </nav>
      </div>
      <div id="detail"></div>
    </>
  );
}

目前还没有任何特定于 React Router 的内容,因此请随意复制/粘贴所有内容。

注意:其实一般是挂在app上的,实际开发中应该是app作为根路由的!!!

2.2、设置<Root>为根路由element

import React from 'react'
import ReactDOM from 'react-dom/client'
import Root from './routes/root'
import {
  createBrowserRouter,
  RouterProvider,
} from 'react-router-dom'

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root></Root>,
  },
]);

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>,
)

2.3、创建错误页面组件挂载

路径:src/error/error-page.tsx

import { useRouteError } from "react-router-dom";

export default function ErrorPage() {
  const error = useRouteError();
  console.error(error);

  return (
    <div id="error-page">
      <h1>Oops!</h1>
      <p>Sorry, an unexpected error has occurred.</p>
      <p>
        <i>{error.statusText || error.message}</i>
      </p>
    </div>
  );
}

将设置<ErrorPage>为errorElement根路由

import React from 'react'
import ReactDOM from 'react-dom/client'
import Root from './routes/root'
import {
  createBrowserRouter,
  RouterProvider,
} from 'react-router-dom'
import ErrorPage from './error/error-page'

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root></Root>,
    errorElement: <ErrorPage></ErrorPage>,
  },
]);

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>,
)

当你访问不存的地址的时候就跳转到错误页:

3、添加其他组件路由

src/routes/contact.jsx

import { Form } from "react-router-dom";

export default function Contact() {
  const contact = {
    first: "Your",
    last: "Name",
    avatar: "https://robohash.org/you.png?size=200x200",
    twitter: "your_handle",
    notes: "Some notes",
    favorite: true,
  };

  return (
    <div id="contact">
      <div>
        <img
          key={contact.avatar}
          src={
            contact.avatar ||
            `https://robohash.org/${contact.id}.png?size=200x200`
          }
        />
      </div>

      <div>
        <h1>
          {contact.first || contact.last ? (
            <>
              {contact.first} {contact.last}
            </>
          ) : (
            <i>No Name</i>
          )}{" "}
          <Favorite contact={contact} />
        </h1>

        {contact.twitter && (
          <p>
            <a
              target="_blank"
              href={`https://twitter.com/${contact.twitter}`}
            >
              {contact.twitter}
            </a>
          </p>
        )}

        {contact.notes && <p>{contact.notes}</p>}

        <div>
          <Form action="edit">
            <button type="submit">Edit</button>
          </Form>
          <Form
            method="post"
            action="destroy"
            onSubmit={(event) => {
              if (
                !confirm(
                  "Please confirm you want to delete this record."
                )
              ) {
                event.preventDefault();
              }
            }}
          >
            <button type="submit">Delete</button>
          </Form>
        </div>
      </div>
    </div>
  );
}

function Favorite({ contact }) {
  const favorite = contact.favorite;
  return (
    <Form method="post">
      <button
        name="favorite"
        value={favorite ? "false" : "true"}
        aria-label={
          favorite
            ? "Remove from favorites"
            : "Add to favorites"
        }
      >
        {favorite ? "★" : "☆"}
      </button>
    </Form>
  );
}

导入联系人组件并创建新路线

import React from 'react'
import ReactDOM from 'react-dom/client'
// import Root from './routes/root'
import App from './App'
import {
  createBrowserRouter,
  RouterProvider,
} from 'react-router-dom'
import ErrorPage from './error/error-page'
import Contact from './routes/contact'

const router = createBrowserRouter([
  {
    path: "/",
    element: <App></App>,
    errorElement: <ErrorPage></ErrorPage>,
  },
  {
    path: "/contact/:contactId",
    element: <Contact></Contact>,
  },
]);

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>,
)

现在访问:http://localhost:3000/contact/1,就是跳转的新页面啦!!!

虽然可以跳转,但是,它不在我们的根布局中😠,继续往下走!!!

4、嵌套路由

我们希望联系人组件像这样在布局内部呈现<Root>

我们通过将联系路由设为根路由的子路由来实现这一点。

👉将联系人路由移至根路由的子路由-children

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
    errorElement: <ErrorPage />,
    children: [
      {
        path: "contacts/:contactId",
        element: <Contact />,
      },
    ],
  },
]);

此时操作点击Name的时候如下:

点击前:

点击后:

很明显,虽然url地址变了,但是页面结构只是增多了,原来的ui结构仍然存在,我们将这样的操作称为子组件跳转,可以理解为局部跳转展示!!!!

5、客户端路由(a改成Link的使用)

您可能已经注意到了,也可能没有,但是当我们单击侧边栏中的链接时,浏览器正在对下一个 URL 执行完整文档请求,而不是使用 React Router。

客户端路由允许我们的应用更新 URL,而无需从服务器请求另一个文档。相反,应用可以立即呈现新的 UI。让我们用 来实现它<Link>。

👉将侧边栏更改<a href><Link to>

import { Outlet,Link } from "react-router-dom";
export default function Root() {
    return (
      <>
        <div id="sidebar">
          <h1>React Router Contacts</h1>
          <div>
            <form id="search-form" role="search">
              <input
                id="q"
                aria-label="Search contacts"
                placeholder="Search"
                type="search"
                name="q"
              />
              <div
                id="search-spinner"
                aria-hidden
                hidden={true}
              />
              <div
                className="sr-only"
                aria-live="polite"
              ></div>
            </form>
            <form method="post">
              <button type="submit">New</button>
            </form>
          </div>
          <nav>
            <ul>
              <li>
              <Link to={`contacts/1`}>Your Name</Link>
              </li>
              <li>
              <Link to={`contacts/2`}>Your Friend</Link>
              </li>
            </ul>
          </nav>
        </div>
        <div id="detail">
        <Outlet />
        </div>
      </>
    );
  }

您可以在浏览器开发者工具中打开网络选项卡,看到它不再请求文档。(其实是因为a链接的问他,详细的问题可以去了解a链接为什么会请求刷新)

6、加载数据中(loader)

URL 段、布局和数据通常结合在一起(三重?)。我们已经可以在这个应用中看到它了:

URL 段成分数据
/<Root>聯絡人清單
联系人/:id<Contact>个人联系方式

由于这种自然的耦合,React Router 具有数据约定,可以轻松地将数据放入路由组件中。

我们将使用两个 API 来加载数据,loader和useLoaderData。首先,我们将在根模块中创建并导出加载器函数,然后将其连接到路由。最后,我们将访问和呈现数据。

loader 函数是一个异步函数,用于在组件渲染前获取数据。它通常被用来预加载数据,比如从服务器上获取数据,然后将这些数据传递给组件,使得组件可以在首次渲染时就拥有所有必要的数据。

👉从以下位置导出加载器root.jsx

import { Outlet, Link } from "react-router-dom";
import { getContacts } from "./contact";

export async function loader() {
  const contacts = await getContacts();
  return { contacts };
}

 👉在路由上配置 loader

/* other imports */
import Root, { loader as rootLoader } from "./routes/root";

const router = createBrowserRouter([
  {
    path: "/",
    element: <APP />,
    errorElement: <ErrorPage />,
    loader: rootLoader,
    children: [
      {
        path: "contacts/:contactId",
        element: <Contact />,
      },
    ],
  },
]);

👉访问并呈现数据 root.tsx

import {
  Outlet,
  Link,
  useLoaderData,
} from "react-router-dom";
import { getContacts } from "../contacts";

/* other code */

export default function Root() {
  const { contacts } = useLoaderData();
  return (
    <>
      <div id="sidebar">
        <h1>React Router Contacts</h1>
        {/* other code */}

        <nav>
          {contacts.length ? (
            <ul>
              {contacts.map((contact) => (
                <li key={contact.id}>
                  <Link to={`contacts/${contact.id}`}>
                    {contact.first || contact.last ? (
                      <>
                        {contact.first} {contact.last}
                      </>
                    ) : (
                      <i>No Name</i>
                    )}{" "}
                    {contact.favorite && <span>★</span>}
                  </Link>
                </li>
              ))}
            </ul>
          ) : (
            <p>
              <i>No contacts</i>
            </p>
          )}
        </nav>

        {/* other code */}
      </div>
    </>
  );
}

就是这样!React Router 现在会自动将数据与您的 UI 保持同步。我们目前还没有任何数据,因此您可能会得到一个空白列表,如下所示:


 7、更新数据(action)

我们刚刚创建的编辑路由已经呈现了一个表单。要更新记录,我们需要做的就是将操作连接到路由。表单将发布到操作,数据将自动重新验证。

src/routes/edit.tsx

👉向编辑模块添加操作

import {
  Form,
  useLoaderData,
  redirect,
} from "react-router-dom";
import { updateContact } from "../contacts";

export async function action({ request, params }) {
  const formData = await request.formData();
  const updates = Object.fromEntries(formData);
  await updateContact(params.contactId, updates);
  return redirect(`/contacts/${params.contactId}`);
}

👉将操作连接到路线 main.ts

/* existing code */
import EditContact, {
  action as editAction,
} from "./routes/edit";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    loader: rootLoader,
    action: rootAction,
    children: [
      {
        path: "contacts/:contactId",
        element: <Contact />,
        loader: contactLoader,
      },
      {
        path: "contacts/:contactId/edit",
        element: <EditContact />,
        loader: contactLoader,
        action: editAction,
      },
    ],
  },
]);

/* existing code */

填写表格,点击保存,然后你就会看到类似这样的内容!(除了看起来更舒服,而且可能没有那么毛茸茸的。)

注意:其实就是action里面的回调方法,它会在表单提交时被调用,而不是在页面加载时。 action 函数接收一个 ActionFunctionArgs 类型的参数,这个参数包含了请求方法、请求体、URL 参数等信息。action 函数应该返回一个 Promise,这个 Promise 会解析成一个对象,这个对象可以包含状态码和数据,它们将被用来构建响应。

特别注意:action 和 loader 是独立的概念,它们可以同时存在或只存在其中一个。action 主要用于处理表单提交,而 loader 用于在页面加载时预取数据。

8、动态路由

其实之前的案例已经使用过了,这里再详细讲一下,所谓的动态路由就是一个模块展示不同的内容,比如根据id展示不同的信息等操作:

路由配置:

chotacts就是动态路由:通过<Link to={`contacts/1`}>Your Name</Link>方式就可以访问了

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
    errorElement: <ErrorPage />,
    children: [
      {
        path: "contacts/:contactId",
        element: <Contact />,
      },
    ],
  },
]);

注意:contactIdURL 段。冒号 ( :) 具有特殊含义,将其转换为“动态段”。动态段将匹配 URL 中该位置的动态(变化)值,例如联系人 ID。我们将 URL 中的这些值称为“URL 参数”,或简称为“params”。

9、路由重定向

现在我们知道了如何重定向,让我们更新创建新联系人的操作以重定向到编辑页面:

👉重定向到新记录的编辑页面 root.tsx

import {
  Outlet,
  Link,
  useLoaderData,
  Form,
  redirect,
} from "react-router-dom";
import { getContacts, createContact } from "../contacts";

export async function action() {
  const contact = await createContact();
  return redirect(`/contacts/${contact.id}/edit`);
}

现在,当我们点击“新建”时,我们应该进入编辑页面:

👉添加一些记录

我将使用第一届 Remix 大会的杰出演讲者阵容 😁

10、活动链接样式

现在我们有了一堆记录,但我们不清楚侧边栏中显示的是哪一条。我们可以用它NavLink来修复这个问题。

👉使用NavLink侧边栏中的 root.tsx

import {
  Outlet,
  NavLink,
  useLoaderData,
  Form,
  redirect,
} from "react-router-dom";

export default function Root() {
  return (
    <>
      <div id="sidebar">
        {/* other code */}

        <nav>
          {contacts.length ? (
            <ul>
              {contacts.map((contact) => (
                <li key={contact.id}>
                  <NavLink
                    to={`contacts/${contact.id}`}
                    className={({ isActive, isPending }) =>
                      isActive
                        ? "active"
                        : isPending
                        ? "pending"
                        : ""
                    }
                  >
                    {/* other code */}
                  </NavLink>
                </li>
              ))}
            </ul>
          ) : (
            <p>{/* other code */}</p>
          )}
        </nav>
      </div>
    </>
  );
}

请注意,我们正在将一个函数传递给className。当用户位于 中的 URL 时NavLinkisActive则为真。当它即将激活时(数据仍在加载),则为isPending真。这使我们能够轻松指示用户所在的位置,以及对已点击但仍在等待数据加载的链接提供即时反馈。

NavLink 是 react-router-dom 库中的一个组件,用于创建具有激活高亮效果的导航链接。当用户浏览到与 NavLink 配置的 to 属性相匹配的路由时,NavLink 可以自动应用特定的样式或类名,以指示当前的导航位置。

NavLink 提供了以下主要属性:

  • to: 指定链接的目标地址。
  • className: 默认的 CSS 类名,始终应用在链接上。
  • activeClassName: 当链接与当前路由匹配时应用的 CSS 类名。
  • activeStyle: 直接应用在链接上的内联样式,当链接与当前路由匹配时生效。
  • exact: 如果设置为 true,则只有当完整路径与 to 属性完全匹配时,链接才会被视为“激活”状态。否则,任何包含 to 属性路径的部分匹配也会激活链接。
  • end: 如果设置为 true,并且 to 属性是一个索引路由(即没有子路由的父路由),那么即使 to 不完全匹配,链接也会被视为“激活”。这与 exact 属性相反。

下面是一个简单的 NavLink 使用示例:

import { NavLink } from 'react-router-dom';

function Navigation() {
  return (
    <nav>
      <ul>
        <li>
          <NavLink to="/" exact activeClassName="selected">
            Home
          </NavLink>
        </li>
        <li>
          <NavLink to="/about" activeClassName="selected">
            About
          </NavLink>
        </li>
        <li>
          <NavLink to="/contact" activeClassName="selected">
            Contact
          </NavLink>
        </li>
      </ul>
    </nav>
  );
}

在这个例子中,当用户位于首页 (/) 时,“Home”链接将获得 selected 类名,从而应用相应的样式。同样地,当用户在 “About” 或 “Contact” 页面时,相应的链接也将获得高亮显示。

NavLink 是创建响应式和用户友好的导航菜单的理想选择,因为它可以自动处理链接的激活状态,无需手动编写逻辑来检查当前的路由。


11、全局待处理 UI

当用户浏览应用程序时,React Router 会保留旧页面,因为正在加载下一页的数据。您可能已经注意到,当您在列表之间单击时,应用程序感觉有点无响应。让我们为用户提供一些反馈,以便应用程序不会感觉无响应。

React Router 在后台管理所有状态,并揭示构建动态 Web 应用所需的部分内容。在本例中,我们将使用钩子useNavigation。

👉useNavigation添加全局待处理 UI-routes/roots.tsx

import {
  // existing code
  useNavigation,
} from "react-router-dom";

// existing code

export default function Root() {
  const { contacts } = useLoaderData();
  const navigation = useNavigation();

  return (
    <>
      <div id="sidebar">{/* existing code */}</div>
      <div
        id="detail"
        className={
          navigation.state === "loading" ? "loading" : ""
        }
      >
        <Outlet />
      </div>
    </>
  );
}

useNavigation返回当前导航状态: 可以是以下之一"idle" | "submitting" | "loading"

在我们的例子中,"loading"如果我们不处于空闲状态,我们会向应用程序的主要部分添加一个类。然后,CSS 会在短暂延迟后添加一个漂亮的淡入淡出效果(以避免快速加载时 UI 闪烁)。不过,您可以做任何您想做的事情,比如在顶部显示一个旋转器或加载栏。

请注意,我们的数据模型 ( src/contacts.js) 具有客户端缓存,因此第二次导航到同一联系人的速度很快。此行为不是React Router,它会重新加载更改路线的数据,无论您之前是否去过那里。但是,它确实避免在导航期间调用不变路线(如列表)的加载器。

12、取消按钮

在编辑页面上,我们有一个取消按钮,但它目前还没有任何作用。我们希望它能发挥与浏览器后退按钮相同的作用。

我们需要按钮上的点击处理程序以及useNavigateReact Router。

👉使用以下代码添加取消按钮点击处理程序useNavigate

import {
  Form,
  useLoaderData,
  redirect,
  useNavigate,
} from "react-router-dom";

export default function EditContact() {
  const { contact } = useLoaderData();
  const navigate = useNavigate();

  return (
    <Form method="post" id="contact-form">
      {/* existing code */}

      <p>
        <button type="submit">Save</button>
        <button
          type="button"
          onClick={() => {
            navigate(-1);
          }}
        >
          Cancel
        </button>
      </p>
    </Form>
  );
}

现在,当用户点击“取消”时,他们将被送回浏览器历史记录中的一个条目。

event.preventDefault🧐 为什么按钮上没有?

尽管看似多余,但这<button type="button">是阻止按钮提交其表单的 HTML 方式。

还有两个功能要实现。我们已经进入最后冲刺阶段!

13、URL 搜索参数和 GET 提交

到目前为止,我们所有的交互式 UI 要么是更改 URL 的链接,要么是将数据发布到操作的表单。搜索字段很有趣,因为它是两者的混合:它是一个表单,但它只更改 URL,而不会更改数据。

现在它只是一个普通的 HTML <form>,而不是 React Router <Form>。让我们看看浏览器默认对它做了什么:

👉在搜索栏中输入姓名,然后按回车键

请注意,浏览器的 URL 现在以URLSearchParams的形式包含您的查询:

http://127.0.0.1:5173/?q=ryan

如果我们查看搜索表单,它看起来像这样:

<form id="search-form" role="search">
  <input
    id="q"
    aria-label="Search contacts"
    placeholder="Search"
    type="search"
    name="q"
  />
  <div id="search-spinner" aria-hidden hidden={true} />
  <div className="sr-only" aria-live="polite"></div>
</form>

正如我们之前所见,浏览器可以通过name其输入元素的属性序列化表单。此输入的名称是q,这就是 URL 为的原因?q=。如果我们将其命名为,则searchURL 将是?search=

请注意,此表单与我们使用过的其他表单不同,它没有<form method="post">。默认值为method"get"这意味着当浏览器创建下一个文档的请求时,它不会将表单数据放入请求 POST 主体中,而是放入URLSearchParamsGET 请求的。


14、使用客户端路由进行 GET 提交

让我们使用客户端路由来提交此表单并过滤我们现有加载器中的列表。

👉更改<form><Form>

<Form id="search-form" role="search">
  <input
    id="q"
    aria-label="Search contacts"
    placeholder="Search"
    type="search"
    name="q"
  />
  <div id="search-spinner" aria-hidden hidden={true} />
  <div className="sr-only" aria-live="polite"></div>
</Form>

👉如果有 URLSearchParams,则过滤列表

export async function loader({ request }) {
  const url = new URL(request.url);
  const q = url.searchParams.get("q");
  const contacts = await getContacts(q);
  return { contacts };
}

因为这是 GET 而不是 POST,所以 React Router不会调用action。提交 GET 表单与单击链接相同:只有 URL 会发生变化。这就是为什么我们为过滤添加的代码位于 中loader,而不是action此路由的 中。

这也意味着这是正常的页面导航。您可以点击后退按钮返回到原来的位置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1953195.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【杰理蓝牙开发】AC695x 音频部分

本文主要记录 杰理蓝牙audio接口的使用&#xff0c;包括ADC和DAC原理的介绍和API接口的使用。 【杰理蓝牙开发】AC695x 音频部分 0. 个人简介 && 授权须知1. ADC【音频数据采集】硬件部分1.1 单片机引脚1.2 硬件电路设计1.3 MIC 输入通路解释 2. 【DAC】音频信号编解码…

GLSL教程 第9章:计算着色器

目录 9.1 计算着色器的基本概念 计算着色器的主要特点&#xff1a; 9.2 计算着色器的基础知识 1. 创建计算着色器 计算着色器代码&#xff1a; 2. 编译和链接计算着色器 示例代码&#xff1a; 3. 执行计算着色器 示例代码&#xff1a; 9.3 实现并行计算和数据并行处理…

51单片机-第五节-串口通信

1.什么是串口&#xff1f; 串口是通讯接口&#xff0c;实现两个设备的互相通信。 单片机自带UART&#xff0c;其中引脚有TXD发送端&#xff0c;RXD接收端。且电平标准为TTL&#xff08;5V为1,0V为0&#xff09;。 2.常见电平标准&#xff1a; &#xff08;1&#xff09;TTL电…

Mysql中如何实现两列的值互换?给你提供些思路。

文章目录 Mysql中如何实现两列的值互换1、第一感觉此sql应该能处理问题了2、需要一个地方存要替换的值&#xff0c;不然两列搞不定。2.1 加第三列&#xff1f;&#xff08;能解决&#xff0c;但是看起来呆呆&#xff09;2.2 上临时表&#xff08;搞点弯路走走&#xff09; 示例…

C语言画蜡烛图

GPT-4o (OpenAI) 在C语言中&#xff0c;绘制蜡烛图&#xff08;Candlestick Chart&#xff09;不是直接的任务&#xff0c;因为C语言本身不包含高级图形绘制库。然而&#xff0c;可以通过某些图形库来完成这项任务&#xff0c;例如使用GTK、SDL、OpenGL等。 以下是通过GTK库绘…

【iOS】—— retain\release实现原理和属性关键字

【iOS】—— retain\release实现原理和属性关键字 1. retain\reelase实现原理1.1 retain实现原理1.2 release实现原理 2. 属性关键字2.1 属性关键字的分类2.2 内存管理关键字2.2.1 weak2.2.2 assgin2.3.3 strong和copy 2.4 线程安全的关键字2.5 修饰变量的关键字2.5.1常量const…

北京率先建设AI原生城市,力争明年推出百个优秀行业大模型产品

7月26日&#xff0c;《北京市推动“人工智能”行动计划&#xff08;2024-2025年&#xff09;》&#xff08;简称《行动计划》&#xff09;正式向社会发布&#xff0c;新京报记者在北京市发展和改革委员会举行的新闻发布会上获悉&#xff0c;北京将率先建设AI原生城市&#xff0…

基于JSP的班级同学录网站

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSPB/S架构 工具&#xff1a;Eclipse、Mysql 系统展示 首页 管理员功能界面 用户功能界面 论坛管…

ubuntu上部署vue项目到ngixn中+SpringBoot项目+postgresql数据库

文章目录 前提1.Ubuntu上安装ngix2.部署Vue项目2.1上传vue项目2.2.配置 3.Ubuntu上安装Postgres4.部署springboot项目 前提 记一次在ubuntu部署前端vue和后端springboot项目&#xff0c;以及数据库postgresql的安装以及启动、停止等常用的命令。 1.Ubuntu上安装ngix 1、检查…

探索 Python 的色彩世界:Colorama 库深度解析

文章目录 &#x1f308; 探索 Python 的色彩世界&#xff1a;Colorama 库深度解析背景&#xff1a;为何选择 Colorama&#xff1f;Colorama 是什么&#xff1f;如何安装 Colorama&#xff1f;简单库函数使用方法场景应用示例常见问题及解决方案总结 &#x1f308; 探索 Python …

Gartner发布2024年零信任网络技术成熟度曲线:20项零信任相关的前沿和趋势性技术

大多数组织都制定了零信任信息安全策略&#xff0c;而网络是零信任实施领域的顶级技术。此技术成熟度曲线可以帮助安全和风险管理领导者确定合适的技术&#xff0c;以将零信任原则嵌入其网络中。 战略规划假设 到 2026 年&#xff0c;15% 的企业将在企业拥有的局域网上用 ZTNA …

HarmonyOS 质量、测试、上架速浏

1.应用质量要求&#xff1a; 1. 应用体验质量建议: 功能数据完备 功能完备 数据完备 基础体验要求 基础约束 兼容性 稳定性 性能 功耗 安全…

Yolov5-v7.0使用CBAM注意力机制记录

Yolov5-v7.0使用CBAM注意力机制记录 一、CBAM实现代码 在model/common.py文件中加入如下代码&#xff1a; #############CBAM注意力机制############## class ChannelAttention(nn.Module):def __init__(self, in_planes, ratio16):super(ChannelAttention, self).__init__(…

【Windows】激活补丁被误删,怎么办?如何关闭Windows11安全中心中的“病毒和威胁保护”!

按下“win&#xff08;徽标键&#xff09;i”快捷键&#xff0c;选择隐私与安全性-Windows安全中心。 选择防火墙和网络保护-域保护。 将开关闭&#xff0c;专业网络和公用网络防火墙也同样关闭&#xff0c;如下图所示&#xff1a; 关闭防火墙后&#xff0c;左边菜单…

改进向量搜索-使用PostgresML和LlamaIndex重新排名

改进向量搜索-使用PostgresML和LlamaIndex重新排名 搜索和重新排名&#xff1a;提高结果相关性 搜索系统通常采用两种主要方法&#xff1a;关键字和语义。关键字搜索将精确的查询词与索引数据库内容匹配&#xff0c;而语义搜索使用 NLP 和机器学习来理解查询上下文和意图。许多…

【踩坑系列-Docker】基于Alibaba Cloud Linux3基础镜像安装Nginx

Author&#xff1a;赵志乾 Date&#xff1a;2024-07-26 Declaration&#xff1a;All Right Reserved&#xff01;&#xff01;&#xff01; 1. 问题描述 使用Alibaba Cloud Linux3作为基础镜像&#xff0c;在其上安装Nginx&#xff0c;对应的Dockerfile内容如下&#xff1a; …

使用 From File 模块加载数据

目录 检查模型 创建时间和信号数据 加载 timeseries 数据 加载数组数据 加载总线数据 此示例说明如何使用 From File 模块从 MAT 文件加载仿真输入数据,包括如何创建和格式化输入数据。可以通过编程方式创建您加载的数据,加载从另一个仿真中记录的数据,或加载从…

栈和队列<数据结构 C版>

目录 栈&#xff08;Stack&#xff09; 栈的结构体 初始化 销毁 入栈 判空 出栈 取栈顶元素 获取栈个数 测试&#xff1a; 队列&#xff08;Queue&#xff09; 队列的结构体 单个结点 队列 初始化 销毁 入队列&#xff0c;队尾 判空 出队列&#xff0c;队头 …

【YashanDB知识库】开源调度框架Quartz写入Boolean值到YashanDB报错

问题现象 Quartz 是一个广泛应用于企业级应用中的开源作业调度框架&#xff0c;它主要用于在Java环境中管理和执行任务。 为了任务调度&#xff0c;Quartz的数据模型中使用了大量的布尔值记录任务、流程的各种状态&#xff0c;如&#xff1a; Quartz使用JDBC写入任务状态代码…

【资料分享】2024第三届钉钉杯大学生大数据挑战赛B题思路解析+双语言代码

2024钉钉杯大学生大数据挑战赛&#xff0c;B题解题思路和双语言代码分享&#xff0c;资料预览&#xff1a;