创建可重用React组件的实用指南

news2024/11/24 5:52:45

尽管React是全球最受欢迎和使用最广泛的前端框架之一,但许多开发者在重构代码以提高可复用性时仍然感到困难。如果你发现自己在React应用中不断重复相同的代码片段,那你来对地方了。

在本教程中,将向你介绍三个最常见的特征,表明是时候构建一个可重用的 React 组件了。然后我们将继续通过构建一个可重用的布局和两个令人兴奋的 React hooks 来查看一些实际演示。

当你读完后,你就能自己弄清楚什么时候适合创建可重用的 React 组件,以及如何创建。

一、可重用 React 组件的前三个特征

1、重复创建具有相同 CSS 样式的wrappers

知道何时创建可重用组件,我最喜欢的标志是重复使用相同的 CSS 样式。现在,您可能会想,“等一下:为什么不简单地将相同的类名分配给共享相同 CSS 样式的元素呢?你说得完全正确。每次不同组件中的某些元素共享相同的样式时都创建可重用的组件不是一个好主意。事实上,它可能会带来不必要的复杂性。所以你得再问自己一件事:这些通常样式的元素是包装器吗?

请考虑以下登录和注册页面:

// Login.js
import './common.css';

function Login() {
  return (
    <div className='wrapper'>
      <main>
        {...}
      </main>
      <footer className='footer'>
        {...}
      </footer>
    </div>
  );
}

// SignUp.js
import './common.css';

function Signup() {
  return (
    <div className='wrapper'>
      <main>
        {...}
      </main>
      <footer className='footer'>
        {...}
      </footer>
    </div>
  );
}

 相同的样式将应用于每个组件的容器 (<div>元素) 和页脚。所以在这种情况下,你可以创建两个可重用的组件 — <Wrapper /> 和 <Footer /> — 并将它们作为 prop 传递给它们。例如,可以按如下方式重构 login 组件:

// Login.js
import Footer from "./Footer.js";

function Login() {
  return (
    <Wrapper main={{...}} footer={<Footer />} />
  );
} 

因此,您不再需要在多个页面中导入common.css或创建相同的<div>元素来包装所有内容。

2、重复使用事件侦听器

要将事件侦听器附加到元素上,你可以在 useEffect() 中像这样处理它:

// App.js
import { useEffect } from 'react';

function App() {
  const handleKeydown = () => {
    alert('key is pressed.');
  }

  useEffect(() => {
    document.addEventListener('keydown', handleKeydown);
    return () => {
      document.removeEventListener('keydown', handleKeydown);
    }
  }, []);

  return (...);
}

或者你可以直接在 JSX 中执行此操作,如下所示 button 组件:

// Button.js
function Button() {
  return (
    <button type="button" onClick={() => { alert('Hi!')}}>
      Click me!
    </button>
  );
};

当你想向 document 或 window 添加事件侦听器时,你必须使用第一种方法。但是,您可能已经意识到,第一种方法需要使用 useEffect(),addEventListener() 和 removeEventListener() 编写更多代码。因此,在这种情况下,创建自定义 hook 将使您的组件更加简洁。

使用事件侦听器有四种可能的方案:

  • 相同的事件侦听器,相同的事件处理程序
  • 相同的事件侦听器,不同的事件处理程序
  • 不同的事件侦听器,相同的事件处理程序
  • 不同的事件侦听器,不同的事件处理程序

在第一种情况下,您可以创建一个 hook,其中同时定义了事件侦听器和事件处理程序。

// useEventListener.js
import { useEffect } from 'react';

export default function useKeydown() {
  const handleKeydown = () => {
    alert('key is pressed.');
  }

  useEffect(() => {
    document.addEventListener('keydown', handleKeydown);
    return () => {
      document.removeEventListener('keydown', handleKeydown);
    }
  }, []);
};

然后,您可以在任何组件中使用此 hook,如下所示:

// App.js
import useKeydown from './useKeydown.js';

function App() {
  useKeydown();
  return (...);
};
// useEventListener.js
import { useEffect } from 'react';

export default function useEventListener({ event, handler} ) {
  useEffect(() => {
    document.addEventListener(event, handler);
    return () => {
      document.removeEventListener(event, handler);
    }
  }, []);
};

然后,您可以在任何组件中使用此 Hook,如下所示:

// App.js
import useEventListener from './useEventListener.js';

function App() {
  const handleKeydown = () => {
    alert('key is pressed.');
  }
  useEventListener('keydown', handleKeydown);
  return (...);
};

3、重复使用相同的 GraphQL 脚本

在使 GraphQL 代码可重用时,您真的不需要寻找迹象。对于复杂的应用程序,用于查询或更改的 GraphQL 脚本很容易占用 30-50 行代码,因为要请求的属性很多。如果您多次使用同一个 GraphQL 脚本,我认为它应该有自己的自定义hook。

import { gql, useQuery } from "@apollo/react-hooks";

const GET_POSTS = gql`
  query getPosts {
    getPosts {
    user {
      id
      name
      ...
      }
      emojis {
         id
         ...
      }
      ...
  }
`;

const { data, loading, error } = useQuery(GET_POSTS, {
  fetchPolicy: "network-only"
});

与其在每个从后端请求的页面中重复此代码,不如为这个特定的 API 创建一个 React hook:

import { gql, useQuery } from "@apollo/react-hooks";

function useGetPosts() {
  const GET_POSTS = gql`{...}`;
  const { data, loading, error } = useQuery(GET_POSTS, {
    fetchPolicy: "network-only"
  });
  return [data];
}

const Test = () => {
  const [data] = useGetPosts();
  return (
    <div>{data?.map(post => <h1>{post.text}</h1>)}</div>
  );
};

二、构建三种可重用的 React 组件

1、布局组件

React 通常用于构建复杂的 Web 应用程序。这意味着需要在 React 中开发大量页面,我怀疑应用程序的每个页面都会有不同的布局。例如,由 30 个页面组成的 Web 应用程序通常使用少于 5 种不同的布局。因此,构建可在许多不同页面中使用的灵活、可重用的布局至关重要。这将为您节省大量代码,从而节省大量时间。

考虑以下 React 功能组件:

import React from "react";
import style from "./Feed.module.css";

export default function Feed() {
  return (
    <div className={style.FeedContainer}>
      <header className={style.FeedHeader}>Header</header>
      <main className={style.FeedMain}>
        {
          <div className={style.ItemList}>
            {itemData.map((item, idx) => (
              <div key={idx} className={style.Item}>
                {item}
              </div>
            ))}
          </div>
        }
      </main>
      <footer className={style.FeedFooter}>Footer</footer>
    </div>
  );
}

const itemData = [1, 2, 3, 4, 5];

这是一个典型的网页,其中包含 <header>、<main> 、<footer>。如果还有 30 个这样的网页,你很容易厌倦重复编写 HTML 标签和一遍又一遍地应用相同的样式。

相反,您可以创建一个接收 <header>、<main><footer>作为props的布局组件。

// Layout.js
import React from "react";
import style from "./Layout.module.css";
import PropTypes from "prop-types";

export default function Layout({ header, main, footer }) {
  return (
    <div className={style.Container}>
      <header className={style.Header}>{header}</header>
      <main className={style.Main}>{main}</main>
      <footer className={style.Footer}>{footer}</footer>
    </div>
  );
}

Layout.propTypes = {
  main: PropTypes.element.isRequired,
  header: PropTypes.element,
  footer: PropTypes.element
};
// Feed.js
import React from "react";
import Layout from "./Layout";
import style from "./Feed.module.css";

export default function Feed() {
  return (
    <Layout
      header={<div className={style.FeedHeader}>Header</div>}
      main={
        <div className={style.ItemList}>
          {itemData.map((item, idx) => (
            <div key={idx} className={style.Item}>
              {item}
            </div>
          ))}
        </div>
      }
      footer={<div className={style.FeedFooter}>Footer</div>}
    />
  );
}

const itemData = [1, 2, 3, 4, 5];
创建具有粘性元素布局的专业提示

许多开发人员在想要将页眉粘贴到视区顶部或将页脚粘贴到底部时,倾向于使用 position: fixed 或 position: absolute。但是,对于布局,您应该尽量避免这种情况。

由于布局的元素将是传递的 props 的父元素,因此您希望保持布局元素的样式尽可能简单——以便传递<header> 、 <main>或 <footer> 能按预期设置样式。因此,我建议将 position: fixed 和 display: flex 应用于布局的最外层元素,并设置 overflow-y: scroll 到该<main>元素。

/* Layout.module.css */
.Container {
  /* Flexbox */
  display: flex;
  flex-direction: column;

  /* Width & Height */
  width: 100%;
  height: 100%;

  /* Misc */
  overflow: hidden;
  position: fixed;
}

.Main {
  /* Width & Height */
  width: 100%;
  height: 100%;

  /* Misc */
  overflow-y: scroll;
}

现在,让我们将一些样式应用于你的 Feed 页面:

/* Feed.module.css */
.FeedHeader {
  /* Width & Height */
  height: 70px;

  /* Color & Border */
  background-color: teal;
  color: beige;
}

.FeedFooter {
  /* Width & Height */
  height: 70px;

  /* Color & Border */
  background-color: beige;
  color: teal;
}

.ItemList {
  /* Flexbox */
  display: flex;
  flex-direction: column;
}

.Item {
  /* Width & Height */
  height: 300px;

  /* Misc */
  color: teal;
}

.FeedHeader,
.FeedFooter,
.Item {
  /* Flexbox */
  display: flex;
  justify-content: center;
  align-items: center;

  /* Color & Border */
  border: 1px solid teal;

  /* Misc */
  font-size: 35px;
}

2、事件侦听器

通常,同一个事件侦听器在整个 Web 应用程序中被多次使用。在这种情况下,创建自定义 React 钩子是个好主意。让我们通过开发一个 useScrollSaver 钩子来学习如何做到这一点,它保存用户设备在页面上的滚动位置——这样用户就不需要从顶部再次滚动。这个钩子对于列出大量元素(例如帖子和评论)的网页很有用。

让我们分解以下代码:

export default function useScrollSaver(scrollableDiv, pageUrl) {
  /* Save the scroll position */
  const handleScroll = () => {
    sessionStorage.setItem(
      `${pageUrl}-scrollPosition`,
      scrollableDiv.current.scrollTop.toString()
    );
  };
  useEffect(() => {
    if (scrollableDiv.current) {
      const scrollableBody = scrollableDiv.current;
      scrollableBody.addEventListener("scroll", handleScroll);
      return function cleanup() {
        scrollableBody.removeEventListener("scroll", handleScroll);
      };
    }
  }, [scrollableDiv, pageUrl]);

  /* Restore the saved scroll position */
  useEffect(() => {
    if (
      scrollableDiv.current &&
      sessionStorage.getItem(`${pageUrl}-scrollPosition`)
    ) {
      const prevScrollPos = Number(
        sessionStorage.getItem(`${pageUrl}-scrollPosition`)
      );
      scrollableDiv.current.scrollTop = prevScrollPos;
    }
  }, [scrollableDiv, pageUrl]);
}

你可以看到 useScrollSaver 钩子需要接收两个参数:scrollableDiv,它必须是一个可滚动的容器,就像上面布局中的<main>,以及 pageUrl,它将用作页面的标识符,以便你可以存储多个页面的滚动位置。

第 1 步:保存滚动位置

首先,您需要将 “scroll” 事件侦听器绑定到可滚动容器:

const scrollableBody = scrollableDiv.current;
scrollableBody.addEventListener("scroll", handleScroll);
return function cleanup() {
  scrollableBody.removeEventListener("scroll", handleScroll);
};

现在,每次用户滚动 scrollableDiv 时,都会运行一个名为 handleScroll 的函数。在这个函数中,你应该使用 localStorage 或 sessionStorage 来保存滚动位置。区别在于 localStorage 中的数据不会过期,而 sessionStorage 中的数据会在页面会话结束时被清除。您可以使用 setItem(id: string, value: string) 将数据保存在任一存储中:

const handleScroll = () => {
  sessionStorage.setItem(
    `${pageUrl}-scrollPosition`,
    scrolledDiv.current.scrollTop.toString()
  );
};
第 2 步:恢复滚动位置

当用户返回网页时,应将用户定向到它或它之前的滚动位置 — 如果有的话。这个位置数据目前保存在 sessionStorage 中,你需要把它拿出来使用。您可以使用 getItem(id: string) 从存储中获取数据。然后,您只需将可滚动容器的 scroll-top 设置为此获取的值:

const prevScrollPos = Number(
  sessionStorage.getItem(`${pageUrl}scrollPosition`)
);
scrollableDiv.current.scrollTop = prevScrollPos;
第 3 步:在任何网页中使用 useScrollSaver 钩子

现在你已经完成了自定义钩子的创建,你可以在任何你想要的网页中使用这个钩子,只要你把两个必需的项目传递给钩子:scrollableDiv 和 pageUrl。让我们回到 Layout.js 并在其中使用您的钩子。这将允许使用此布局的任何网页享受您的滚动保护程序:

// Layout.js
import React, { useRef } from "react";
import style from "./Layout.module.css";
import PropTypes from "prop-types";
import useScrollSaver from "./useScrollSaver";

export default function Layout({ header, main, footer }) {
  const scrollableDiv = useRef(null);
  useScrollSaver(scrollableDiv, window.location.pathname);
  return (
    <div className={style.Container}>
      <header className={style.Header}>{header}</header>
      <main ref={scrollableDiv} className={style.Main}>
        {main}
      </main>
      <footer className={style.Footer}>{footer}</footer>
    </div>
  );
}

3、查询/更改(特定于 GraphQL)

如果您像我一样喜欢将 GraphQL 与 React 一起使用,您可以通过为 GraphQL 查询或更改创建 React 钩子来进一步减少您的代码库。

请考虑以下运行 GraphQL 查询 getPosts() 的示例:

import { gql, useQuery } from "@apollo/react-hooks";

const GET_POSTS = gql`
  query getPosts {
    getPosts {
    user {
      id
      name
      ...
      }
      emojis {
         id
         ...
      }
      ...
  }
`;

const { data, loading, error } = useQuery(GET_POSTS, {
  fetchPolicy: "network-only"
});

如果要从后端请求的属性越来越多,您的 GraphQL 脚本将占用越来越多的空间。因此,无需在每次需要运行查询 getPosts() 时都重复 GraphQL 脚本和 useQuery,而是可以创建以下 React 钩子:

// useGetPosts.js
import { gql, useQuery } from "@apollo/react-hooks";

export default function useGetPosts() {
  const GET_POSTS = gql`
  query getPosts {
    getPosts {
    user {
      id
      name
      ...
      }
      emojis {
         id
         ...
      }
      ...
  }
  `;

  const { data, loading, error } = useQuery(GET_POSTS, {
    fetchPolicy: "network-only"
  });

  return [data, loading, error];
}

然后,您可以按如下方式使用 useGetPosts() 钩子:

// Feed.js
import React from "react";
import Layout from "./Layout";
import style from "./Feed.module.css";
import useGetPosts from "./useGetPosts.js";

export default function Feed() {
  const [data, loading, error] = useGetPosts();
  return (
    <Layout
      header={<div className={style.FeedHeader}>Header</div>}
      main={
        <div className={style.ItemList}>
          {data?.getPosts.map((item, idx) => (
            <div key={idx} className={style.Item}>
              {item}
            </div>
          ))}
        </div>
      }
      footer={<div className={style.FeedFooter}>Footer</div>}
    />
  );
}

三、关于创建可重用 React 组件的常见问题解答

1、React.js 中的可重用组件是什么?

React.js 中的可重用组件是封装用户界面 (UI) 功能的特定部分的基本代码块,从而能够以模块化和高效的方式构建应用程序。这些组件旨在在整个应用程序甚至不同项目中使用,提供一定程度的代码可重用性,从而显著简化开发。它们通过封装其逻辑和渲染来促进明确的关注点分离,确保其内部实现细节对应用程序的其余部分保持隐藏。这不仅增强了代码的组织和可维护性,还使开发人员能够通过跨团队和项目共享和重用组件来更加协作。

可重用组件的主要优点之一是它们能够保持用户界面的一致性。通过在应用程序的不同部分使用相同的组件,您可以确保统一的外观和感觉,遵守设计准则并创建更精致的用户体验。这些组件通过 props 进行参数化,允许自定义和适应各种用例。此参数化功能在一致性和灵活性之间提供了平衡,使开发人员能够根据每个应用程序功能或页面的特定要求微调组件行为和外观。

可重用性不仅可以节省时间和精力,还可以简化测试过程。隔离和封装的组件更易于测试,您可以创建单元测试来验证其正确性和功能。通过将可重用组件整合到 React 应用程序中,您可以建立可维护、模块化且一致的代码库,最终提高开发效率并提高用户界面的整体质量。

2、React 中可重用组件的示例是什么?

React 中可重用组件的一个常见示例是 “Button” 组件。按钮是用户界面的基本部分,在整个应用程序中用于各种交互。在 React 中创建可重用的 Button 组件可以让你保持一致的外观和行为,同时减少代码重复。下面是一个可重用的 Button 组件的简单示例:

import React from 'react';

const Button = ({ label, onClick, style }) => {
return (
<button
style={style}
onClick={onClick}
>
{label}
</button>
);
};

export default Button;

在此示例中,Button 组件被封装成一个功能组件,它接收三个关键属性:“label”用于按钮上显示的文本,“onClick”用于单击事件处理程序,以及一个可选的“style”属性用于自定义按钮的外观。此组件封装了按钮的 HTML 结构和行为,使其在整个应用程序中易于重用,而无需复制代码。

此 Button 组件的使用展示了其可重用性和灵活性。在父组件(在本例中为 “App”)中,您可以传入特定的标签文本、单击事件处理函数和样式首选项,以创建具有不同用途和外观的不同按钮。通过使用此类可重用组件,您可以保持统一的用户界面样式并提高代码的可维护性。这些组件可以扩展到按钮之外,以包含更复杂的 UI 元素,例如输入字段、卡片或导航栏,从而形成模块化且可维护的 React 应用程序。可重用组件不仅可以加快开发速度,还可以带来更一致、用户友好的界面,该界面符合设计准则和最佳实践。

3、如何在 React 中创建可重用的组件?

在 React.js 中创建可重用组件是构建模块化和可维护应用程序的基本做法。该过程从一个明确的计划开始,您可以在其中确定要封装在组件中的特定功能或用户界面 (UI) 元素。定义组件的用途后,您可以在 React 项目中创建一个新的 JavaScript/JSX 文件。最好按照 React 的命名约定,以大写字母开头命名文件。

在这个新的组件文件中,您可以定义组件的行为和渲染逻辑。组件可以是功能性的,也可以是基于类的,具体取决于您的需要。在参数化组件时,您接受 props 作为输入,这允许您自定义其外观和行为。使用 PropTypes 或 TypeScript 定义 prop 类型可确保类型的安全性和清晰度,从而更容易理解应该如何使用组件。构建组件后,即可在应用程序的其他部分使用。您可以导入和合并它,传入特定的 props 来为每个用例配置其行为。

4、React 中可重用组件有什么好处?

React 中的可重用组件提供了许多好处,可以显着增强开发过程和应用程序的质量。它们通过将复杂的用户界面分解为更小的、独立的构建块来促进模块化,使代码库更有条理和可维护。这些组件专注于特定功能或 UI 元素,允许开发人员独立管理和更新它们,从而降低意外副作用的风险并简化开发过程。

可重用组件的主要优点是它们的可重用性,从而节省时间和精力。您可以在应用程序的不同部分或不同项目中使用相同的组件,而无需重写类似的代码。这不仅加快了开发速度,还确保了一致的用户界面。一致性是另一个关键优势。通过对特定 UI 元素使用相同的组件,您可以保持统一的外观和行为,遵守设计准则并改善用户体验。

此外,可重用组件是高度可定制的。它们接受 props,这使开发人员能够微调其行为和外观以适应不同的用例。这种参数化增强了组件的灵活性和多功能性。当出现问题时,这些隔离的组件更容易测试和调试,从而可以有效地解决问题。此外,通过跨项目共享和重用组件,团队可以更有效地协作,保持统一的 UI 样式,并确保代码一致性,这对于大规模和长期开发工作至关重要。总之,React 中的可重用组件简化了开发,鼓励代码可重用性,保持 UI 一致性,并提供可定制性,最终导致更高效、更高质量的应用程序。

5、在 React 中,什么是好的可重用组件?

React 中设计良好的可重用组件表现出几个关键特征。首先,可重用性是核心属性。创建这些组件时,应确保在应用程序的不同部分甚至单独的项目中使用。为了实现这一点,它们必须高度参数化,允许开发人员通过 prop 自定义它们的外观和行为。这种多功能性是使组件真正可重用的一个基本方面。

封装同样重要。可重用组件应封装其内部逻辑和渲染,从而将实现细节与应用程序的其余部分隔离开来。这种关注点分离可以产生更简洁、更模块化的代码,并简化集成。

模块化是另一个关键属性。好的可重用组件应该具有单一的目的,专注于特定的功能或特定的 UI 元素。这种模块化设计增强了代码的可维护性和调试效率。此外,易于测试至关重要。隔离的组件更易于测试,从而促进创建健壮且可靠的代码。

最后,这些组件应该维护一个清晰的 API,指定它们接受的 props 及其预期用途。这种清晰度有助于其他开发人员了解如何有效地使用组件。当同一组件用于特定 UI 元素时,它们通过促进一致的用户界面,确保应用程序具有凝聚力和用户友好性。从本质上讲,一个好的可重用组件是可重新配置的、封装的、模块化的、易于测试的,并有助于代码的可维护性和 UI 的一致性。

文章翻译自:A Practical Guide to Creating Reusable React Components — SitePoint

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

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

相关文章

自动语音识别(ASR)与文本转语音(TTS)技术的应用与发展

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

ARM 架构(Advanced RISC Machine)精简指令集计算机(Reduced Instruction Set Computer)

文章目录 1、ARM 架构ARM 架构的特点ARM 架构的应用ARM 架构的未来发展 2、RISCRISC 的基本概念RISC 的优势RISC 的应用RISC 与 CISC 的对比总结 1、ARM 架构 ARM 架构是一种低功耗、高性能的处理器架构&#xff0c;广泛应用于移动设备、嵌入式系统以及越来越多的服务器和桌面…

戴尔 AI Factory 上的 Agentic RAG 搭载 NVIDIA 和 Elasticsearch 向量数据库

作者&#xff1a;来自 Elastic Hemant Malik, Dell Team 我们很高兴与戴尔合作撰写白皮书《戴尔 AI Factory with NVIDIA 上的 Agentic RAG》。白皮书是一份供开发人员参考的设计文档&#xff0c;概述了实施 Agentic 检索增强生成 (retrieval augmented generation - RAG) 应用…

Vue实训---0-完成Vue开发环境的搭建

1.在官网下载和安装VS Code编辑器 完成中文语言扩展&#xff08;chinese&#xff09;&#xff0c;安装成功后&#xff0c;需要重新启动VS Code编辑器&#xff0c;中文语言扩展才可以生效。 安装Vue-Official扩展&#xff0c;步骤与安装中文语言扩展相同&#xff08;专门用于为“…

POA-CNN-SVM鹈鹕算法优化卷积神经网络结合支持向量机多特征分类预测

分类预测 | Matlab实现POA-CNN-SVM鹈鹕算法优化卷积神经网络结合支持向量机多特征分类预测 目录 分类预测 | Matlab实现POA-CNN-SVM鹈鹕算法优化卷积神经网络结合支持向量机多特征分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现POA-CNN-SVM鹈鹕算法…

(STM32)ADC驱动配置

1.ADC驱动&#xff08;STM32&#xff09; ADC模块中&#xff0c;**常规模式&#xff08;Regular Mode&#xff09;和注入模式&#xff08;Injected Mode&#xff09;**是两种不同的ADC工作模式 常规模式&#xff1a;用于普通的ADC转换&#xff0c;是默认的ADC工作模式。 注入…

flume-将日志采集到hdfs

看到hdfs大家应该做什么&#xff1f; 是的你应该去把集群打开&#xff0c; cd /export/servers/hadoop/sbin 启动集群 ./start-all.sh 在虚拟机hadoop02和hadoop03上的conf目录下配置相同的日志采集方案&#xff0c;‘ cd /export/servers/flume/conf 切换完成之后&#…

机器人SLAM建图与自主导航:从基础到实践

前言 这篇文章我开始和大家一起探讨机器人SLAM建图与自主导航 &#xff0c;在前面的内容中&#xff0c;我们介绍了差速轮式机器人的概念及应用&#xff0c;谈到了使用Gazebo平台搭建仿真环境的教程&#xff0c;主要是利用gmapping slam算法&#xff0c;生成一张二维的仿真环境…

在线解析工具链接

在线字数统计工具-统计字符字节汉字数字标点符号-计算word文章字数字数统计,字符统计,字节统计,字数计算,统计字数,统计字节数,统计字符数,统计word字数,在线字数统计,在线查字数,计算字数,字数统计工具,支持手机移动端查询多少字数,英文:Calculate the number of words,Count …

学习Servlet(含义,作用)

目录 前言 Servlet 的含义 Servlet 的作用 前言 一个完整的前后端项目&#xff0c;是需要前端和后端&#xff08;Java实现&#xff09;共同完成的。那应该如何实现前后端进行交互呢&#xff1f;答案&#xff1a;使用Servlet实现前后端交互 我会从了解Servlet的含义&…

从源码到应用:在线教育系统与教培网校APP开发实战指南

时下&#xff0c;各类教培网校APP逐渐成为教育机构的核心工具。那么&#xff0c;如何从源码出发&#xff0c;开发一套符合需求的在线教育系统与教培网校APP&#xff1f;本文将从架构设计、功能实现到部署上线&#xff0c;提供一份全面的开发实战指南。 一、在线教育系统的核心架…

Pyqt5的簡單教程

簡介 pyqt5是qt的Python版本&#xff0c;因為最近需要做一個有界面的程式&#xff0c;所以想到這個庫&#xff0c;這裡就稍微介紹它的安裝和使用教程 1.安裝qt5 可能需要安裝vs的c編譯組件 pip install pyQt52.使用拖拽組件編寫頁面 使用此工具打開組件 ctrls 生成.ui文件 …

---Arrays类

一 java 1.Arrays类 1.1 toString&#xff08;&#xff09; 1.2 arrays.sort( )-----sort排序 1&#xff09;直接调用sort&#xff08;&#xff09; Arrays.sort() 方法的默认排序顺序是 从小到大&#xff08;升序&#xff09;。 2&#xff09;定制排序【具体使用时 调整正负…

STM32F4----ADC模拟量转换成数字量

STM32F4----ADC模拟量转换成数字量 基本原理 当需要测量和记录外部电压的变化&#xff0c;或者根据外部电压的变化量来决定是否触发某个动作时&#xff0c;我们可以使用ADC&#xff08;模拟—数字转换器&#xff09;功能。这个功能可以将模拟的电压信号转换为数字信号&#x…

《Python 股票交易分析:开启智能投资新时代》(二)

Python 进行股票交易分析的优势 简洁易读&#xff1a;Python 的语法简洁明了&#xff0c;即使是编程新手也能较快上手&#xff0c;降低了股票交易分析的门槛。 Python 的简洁易读是其在股票交易分析中受欢迎的重要原因之一。Python 的语法简洁明了&#xff0c;与其他编程语言相…

python程序的编写以及发布(形象类比)

最近重新接触python&#xff0c;本人之前对于python的虚拟环境&#xff0c;安装包比较比较迷惑&#xff0c;这里给出一个具象的理解。可以将 Python 程序运行的过程类比成一次 做菜的过程&#xff0c;从准备食材到最后出锅。以下是具体的类比步骤&#xff1a; 1. 安装 Python 环…

ThinkPad t61p 作SMB服务器,打印服务器,pc ,android ,ipad利用此服务器互传文件

1.在t61p上安装win7 2,配置好smb 服务 3.再安装好打印驱动程序 4.pc与win7利用系统的网络互相发现,映射为硬盘使用。 5.android&#xff0c;ipad安装ES文件浏览器访问win7 共享文件夹&#xff0c;互传文件。 6.android手机安装FE文件浏览器&#xff0c;可以利用花生壳外网…

C# 属性 学习理解记录

字段和属性 左边字段&#xff0c;右边属性 拓展&#xff0c;属性安全&#xff1a; 1、设置public private 和protected 等&#xff0c;只读&#xff0c;只写&#xff0c; 2、在get set 方法时&#xff0c;验证&#xff0c;异常时抛出错误

决策树分类算法【sklearn/决策树分裂指标/鸢尾花分类实战】

决策树分类算法 1. 什么是决策树&#xff1f;2. DecisionTreeClassifier的使用&#xff08;sklearn&#xff09;2.1 算例介绍2.2 构建决策树并实现可视化 3. 决策树分裂指标3.1 信息熵&#xff08;ID3&#xff09;3.2 信息增益3.3 基尼指数&#xff08;CART&#xff09; 4. 代码…

CentOS使用中遇到的问题及解决方法

一、CentOS 7网络配置&#xff08;安装后无法联网问题&#xff09; 现象说明 在安装CentOS系统后&#xff0c;有可能出现无法联网的问题&#xff0c;虚拟机中的网络配置并没有问题&#xff0c;而系统却无法联网,也ping不通。 原因描述 CentOS默认开机不启动网络&#xff0c;因…