创建可重用React组件的实用指南
尽管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 {idname...}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 (<Layoutheader={<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 {idname...}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 {idname...}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 (<Layoutheader={<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
相关文章:
创建可重用React组件的实用指南
尽管React是全球最受欢迎和使用最广泛的前端框架之一,但许多开发者在重构代码以提高可复用性时仍然感到困难。如果你发现自己在React应用中不断重复相同的代码片段,那你来对地方了。 在本教程中,将向你介绍三个最常见的特征,表明是…...
蓝桥杯每日真题 - 第18天
题目:(出差) 题目描述(13届 C&C B组E题) 解题思路: 问题分析 问题实质是一个带权图的最短路径问题,但路径的权重包含两个部分: 从当前城市到下一个城市的路程时间。 当前城市的…...
MySQL中索引全详解
第一部分:什么是索引 索引在数据库中就像书的目录,能够快速定位数据位置,从而提升查询效率。没有索引时,数据库查询需要从头到尾扫描整个表(称为全表扫描),这在数据量大时非常耗时。有了索引后&…...
探索复合物TPP-PEG-Heparin的特性;磷酸三苯酯-聚乙二醇-肝素的线粒体靶向性
TPP-PEG-Heparin,即磷酸三苯酯(TPP)、聚乙二醇(PEG)和肝素(Heparin)的复合物,其特性融合了这三种成分的性质。 一、线粒体靶向性 TPP部分:具有线粒体靶向功能…...
ubuntu 配置 多个 git 客户端 账户
Git配置两个或多个账户 https://blog.csdn.net/mainking2003/article/details/134711865 git 提交 不用输入用户名、密码的方法(GIT免密提交) https://blog.csdn.net/wowocpp/article/details/125797263 git config 用法 https://blog.csdn.net/blueb…...
Web3与智能合约:区块链技术下的数字信任体系
随着互联网的不断发展,Web3代表着我们迈入了一个去中心化、更加安全和智能的网络时代。作为Web3的核心组成部分,区块链技术为智能合约的出现和发展提供了强有力的基础。智能合约不仅仅是自动化的代码,它们正逐步成为重塑数字世界信任体系的关…...
RocketMQ文件刷盘机制深度解析与Java模拟实现
引言 在现代分布式系统中,消息队列(Message Queue, MQ)作为一种重要的中间件,扮演着连接不同服务、实现异步通信和消息解耦的关键角色。Apache RocketMQ作为一款高性能的分布式消息中间件,广泛应用于实时数据流处理、…...
高级编程之结构化代码
背景:以下没结构化代码之前,定时器同步店铺信息的代码。 结构化的思想:SRP(单一职责),一个方法是做一件事,层次是相关的,逻辑和数据操作进行拆分,数据操作从业务流程上定…...
学习编程,学习中间件,学习源码的思路
01 看的多,内化不足 最近想复习一下编程相关的知识,在复习前我翻开了之前的一些笔记,这些笔记基本都是从书本、视频、博客等摘取记录的,看着这些笔记心里总结:看的多,内化不足。 02 整理大纲 为了解决这个…...
网络安全与加密
1.Base64简单说明描述:Base64可以成为密码学的基石,非常重要。特点:可以将任意的二进制数据进行Base64编码结果:所有的数据都能被编码为并只用65个字符就能表示的文本文件。65字符:A~Z a~z 0~9 / 对文件进行base64编码…...
开源协议介绍
文章目录 1. MIT License2. Apache License 2.03. GNU General Public License (GPL)4. GNU Lesser General Public License (LGPL)5. BSD License6. Mozilla Public License (MPL)7. Creative Commons Licenses (CC)8. Unlicense选择建议 在 开源平台上,开源项目通…...
Java技术复习提升 10异常
10 异常 10.1异常介绍及分类 异常捕获 选中后alttabt->选中try-catch 异常就是程序执行中不正常的情况 注意语法和逻辑错误并不是异常 异常分类有两种 error和exception error是错误 虚拟机无法解决的严重问题 exception是其他因为编程错误或者外在因素导致的一般性的问…...
java版工程项目管理系统源码:Spring Cloud与前后端分离的完美结合
在现代化的工程项目管理中,一套功能全面、操作便捷的系统至关重要。本文将介绍一个基于Spring Cloud和Spring Boot技术的Java版工程项目管理系统,结合Vue和ElementUI实现前后端分离。该系统涵盖了项目管理、合同管理、预警管理、竣工管理、质量管理等多个…...
Oracle与MySQL中CONCAT()函数的使用差异
一、CONCAT函数介绍 CONCAT函数是MySQL等数据库中用于连接两个或多个字符串的内置函数。其基本语法如下: CONCAT(string1, string2, ...)参数说明: string1, string2, …:需要连接的字符串参数,可以有多个。 返回值࿱…...
AI社媒引流工具:解锁智能化营销的新未来
在数字化浪潮的推动下,社交媒体成为品牌营销的主战场。然而,面对海量的用户数据和日益复杂的运营需求,传统营销方法显得力不从心。AI社媒引流王应运而生,帮助企业在多平台中精准触达目标用户,提升营销效率和效果。 1.…...
浏览器的事件循环机制
一、请简述浏览器的事件循环机制(Event Loop)基本原理 浏览器的事件循环机制是用于协调处理 JavaScript 中的异步任务与同步任务执行顺序的一种机制,它确保了代码能够按照合理的顺序执行,避免阻塞页面渲染等情况。其基本原理如下…...
如何在 React 项目中应用 TypeScript?应该注意那些点?结合实际项目示例及代码进行讲解!
在 React 项目中应用 TypeScript 是提升开发效率、增强代码可维护性和可读性的好方法。TypeScript 提供了静态类型检查、自动补全和代码提示等功能,这对于 React 开发者来说,能够帮助早期发现潜在的 bug,提高开发体验。 1. 项目初始化 在现…...
排序算法(五)--归并排序
文章目录 引言归并排序概述C语言实现代码解析结论 归并排序 C语言实例 引言 归并排序(Merge Sort)作为一种经典的排序算法,以其稳定性、分治法的巧妙应用以及相对高效的时间复杂度而著称。 归并排序概述 归并排序采用分治法(Di…...
Linux KASLR 地址偏移
kaslr开启时地址 cat /proc/cmdline BOOT_IMAGE/boot/vmlinuz-5.4.0-193-generic rootUUID0e46dee3-4557-434a-a2d2-a35c6ad3d327 ro find_preseed/preseed.cfg auto noprompt prioritycritical localeen_US quiet cat /boot/config-$(uname -r) | grep CONFIG_RANDOMIZE_B…...
利用开源图床的技巧与实践
随着互联网的普及,图片的使用变得越来越广泛。无论是个人博客、社交媒体还是企业网站,都离不开图片的呈现。而图床作为图片存储和管理的工具,可以帮助开发者和内容创作者高效地管理图片资源。本文将探讨如何利用开源图床,并提供相…...
Unity Lua方向的面试真题详解
最近有位同学面试Unity,面试的公司采用Lua的方案来做公司项目,我们把面试时问道的真题列举出来,并配上参考回复。 1、Lua热更文件时,文件是重写的,还是只写一部分? 热更分为资源更新和代码更新,资源更新…...
经验笔记:Git 基础操作指南
推荐一下Gitee最好的Git操作教程:Learn Git Branching 经验笔记:Git 基础操作指南 1. 安装 Git 首先确保您的计算机上已安装 Git。如果还没有安装,可以从 Git官网 下载并安装。 2. 配置 Git 安装完成后,打开命令行工具&#…...
大模型在智能客服中心领域的应用思考
大模型在智能客服中心领域的应用思考 作者:开源呼叫中心系统 FreeIPCC,Github地址:https://github.com/lihaiya/freeipcc 随着人工智能技术的飞速发展,特别是深度学习技术的突破,大型语言模型(LLMs&#x…...
ssm旅游推荐系统的设计与开发
摘 要 旅游推荐系统是一个综合性的在线旅游推荐平台,旨在为用户提供便捷的旅游规划和预定服务。通过该系统,用户能够浏览各类景点信息并进行分类查找,同时获取详尽的景点介绍和相关照片,以辅助做出旅行决策。系统提供在线门票订购…...
C++从零到满绩——入门基础and类和对象(上)
目录 1>>前言 2>>函数重载 3>>引用 3.1>>引用的概念 3.2>>引用三大特性 3.3>>引用的使用 3.4>>const引用 3.5>>指针与引用的关系 4>>inline内联函数 5>>nullptr 6>>类和对象(上&#…...
如何为PDF文件创建口令密码
介绍Adobe Acrobat https://helpx.adobe.com/cn/acrobat/using/access-acrobat-across-web-mobile-desktop.html 使用Adobe Acrobat软件添加口令...
【ubuntu】开机进入initramfs,无法开机
Step 1 blkid查看 ext4 的磁盘 Step 2 找到TYPE"EXT4"的盘,我们此处是 /dev/mapper/ubuntu–vg-ubuntu–lv,fsck命令是用于检查和修复Linux文件系统中的错误。通过使用-t参数指定文件系统类型(例如ext4)。我们使用如下命令进行…...
java基础---反射
仅供个人学习使用 1. 什么是反射 Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为…...
CircuitBreaker机制详解:Elasticsearch中的资源管理
CircuitBreaker机制详解:Elasticsearch中的资源管理 在现代软件架构中,熔断器(CircuitBreaker)是一种重要的模式,用于防止系统过载并保护系统稳定性。在Elasticsearch中,熔断器机制尤其关键,因为它们帮助管理资源使用,防止节点因资源耗尽而崩溃。本文将深入探讨Elasti…...
毕氏完美数
毕达哥拉斯 概要 2 \sqrt{2} 2 a b , a < b , a > b ab,a<b,a>b ab,a<b,a>b 判断完美数验证 自守数验证 水仙花数代码验证 概要 回顾完美数,自守数,水仙花数,根号2感受最美公式。 2 \sqrt{2} 2 毕达哥拉斯创立了一…...
数据结构-8.Java. 七大排序算法(中篇)
本篇博客给大家带来的是排序的知识点, 由于时间有限, 分两天来写, 中篇主要实现后三种排序算法: 冒泡排序,快速排序,下一篇讲 归并排序. 文章专栏: Java-数据结构 若有问题 评论区见 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作…...
如何能让安全责任更清晰——构建清晰安全责任体系策略与实践
安全已成为各行各业不可忽视的重要议题。然而,要确保组织的安全运行,仅仅有安全意识是不够的,还需要有一套清晰明确的安全责任体系来支撑。这套体系能够明确每个人的安全职责,促进安全管理工作的有序进行,降低事故发生…...
VBA技术资料MF228:移动形状并覆盖某单元格区域
我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…...
《Python基础》之基本数据类型
目录 基本数据类型 1、Number(数字) (1)、整数(int) (2)、浮点数(float) (3)、复数(complex) (4)、 布尔…...
2024 APMCM亚太数学建模C题 - 宠物行业及相关产业的发展分析和策略(详细解题思路)
在当下, 日益发展的时代,宠物的数量应该均为稳步上升,在美国出现了下降的趋势, 中国 2019-2020 年也下降,这部分变化可能与疫情相关。需要对该部分进行必要的解释说明。 问题 1: 基于附件 1 中的数据及您的团队收集的…...
66 mysql 的 表自增长锁
前言 mysql 的表锁之 AUTO_INC, 是我们自增长的时候做并发控制的锁 主要是用于 自增长生成新的 id 的时候的控制 在前面的文档中, 我们又看到 mysql 这边自增长的处理的相关的大概脉络 但是 对于一些 并发控制的细节, 我们当时 应该是直接忽略掉了 我们这里就来看一下…...
java中的this关键字
🎉🎉🎉欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的技术是JavaScript与Vue.目前正在往全栈方向前进, 如果我的博客给您带来了帮助欢迎您关注我,我将会持续不断的更新文章!!!🙏🙏🙏 文章目录…...
资源控制器--laravel进阶篇
laravel的控制器当中有个资源控制器,这个比较好用。 创建资源控制器 php artisan make:controller PhotoController --resource 创建个路由来使用该资源控制器 use App\Http\Controllers\PhotoController; Route::resource(photos, PhotoController::class); 隐式模型绑定不…...
智能工厂的设计软件 为了监管控一体化的全能Supervisor 的监督学习 之 序7 进化论及科学的信息技术创新:分布式账本/区块链/智能合约
Q&A Q46、 聊聊“分布式账本”“区块链”和“智能合约” “分布式账本”、“区块链”和“智能合约”是现代信息技术领域的几个重要概念,它们在金融、供应链管理、物联网等多个领域都发挥着重要作用。以下是对这三个概念的详细解析: 分布式账本 …...
从零开始认识显卡
显卡(GPU,全称为Graphics Processing Unit),是电脑中专门负责图形处理的硬件组件。以下是从零开始认识显卡的简单介绍: 1. 显卡的基本组成 显卡通常由以下几个主要部分组成: GPU核心:显卡的“…...
什么是计算机网络
什么是计算机网络? 计算机网络的定义计算机网络的分类按覆盖范围分类按拓扑结构分类按通信传输介质分类按信号频带占用方式分类 计算机网络的功能信息交换资源共享分布式处理 计算机网络的组成计算机网络的定义计算机网络的分类按覆盖范围分类按拓扑结构分类按通信传…...
网络安全在线网站/靶场:全面探索与实践
目录 1. CyberPatriot 简介 功能与特点 适用人群 2. Hack The Box 简介 功能与特点 适用人群 3. OverTheWire 简介 功能与特点 适用人群 4. VulnHub 简介 功能与特点 适用人群 5. PortSwigger Web Security Academy 简介 功能与特点 适用人群 6. TryHackM…...
多旋翼无人机长航时远距离集群技术详解
多旋翼无人机长航时远距离集群技术是当前无人机技术发展的重要方向之一,它结合了多旋翼无人机的灵活性和集群技术的优势,实现了无人机在长时间、远距离条件下的高效协同作业。以下是对该技术的详细解析: 一、多旋翼无人机特点 多旋翼无人机以…...
C#编写的日志记录组件 - 开源研究系列文章
以前编写过一个日志记录组件的博文,这次发布一个修改过的完善版本。 1、 项目目录; 2、 源码介绍; 1) 实现; 2) 使用; 后面的参数为级别设置,只有大于这个级别的才进行日志记录,限制了日志记录的…...
使用 Java 操作 SQLite 数据库
文章目录 1.导入依赖2.实际应用 1.导入依赖 <dependencies><dependency><groupId>org.xerial</groupId><artifactId>sqlite-jdbc</artifactId><version>3.36.0.3</version></dependency> </dependencies>2.实际应…...
再次讨论下孤注一掷
在孤注一掷中的黑客技术里面,简单介绍了电影孤注一掷中用的一些"黑科技",这里继续讨论下,抛弃这些黑科技,即使在绝对公平的情况下,你也一样赢不了赌场 相对论有一个假设就是光速不变,这里也有个…...
系统思考—跳出症状看全局
感谢合作伙伴的邀请,圆满结束国药试剂关于《系统思考》的课程。课堂上,我们围绕“缺货”这个看似具体的问题,展开了一场跨部门的深度探讨。销售、采购、物流等部门各抒己见,发现每个部门的出发点都是为了公司好,但误判…...
前端面试vue篇:Vue2 和 Vue3 在设计和性能上有显著区别
Vue3 相对于 Vue2 的主要改进和性能提升体现在以下几个关键领域 1.响应式系统: (1)Vue2 使用 Object.defineProperty 遍历对象的所有属性来实现响应式,这在大型应用中可能导致性能瓶颈,尤其是在组件初次渲染和大量数据变化时。 (2)Vue3 引入了…...
每天五分钟深度学习:神经网络模型的直观理解
本文重点 神经网络是深度学习的基础模型之一,本文将讲解一下基础模型神经网络是什么? 神经网络 如上所示,这个神经网络有两层(我们认为输入层不算神经网络的层数),其中一个隐藏层,还有一个是输出层。我们称隐藏层为第一层,输出层为第二层,输入层为第零层。 我们有输…...
高集成的MCU方案已成电机应用趋势?
【哔哥哔特导读】高集成化的芯片成为当下MCU领域研发和市场布局的重点,但是在实际应用中仍然面临散热等痛点问题,MCU厂商是如何解决和优化这些痛点? 随着全球工业自动化、智能制造和绿色发展的不断推进,中国电机行业正站在新一轮…...