React--》掌握react構建拖拽交互的技巧

在這篇文章中將深入探討如何使用react-dnd,從基礎的拖拽操作到更復雜的自定義功能帶你一步步走向實現流暢、可控且用戶友好的拖拽體驗,無論你是剛接觸拖拽功能的初學者還是想要精細化拖拽交互的經驗開發者,都能從中找到適合自己的靈感和解決方案。

目錄

react-dnd操作

拖拽排序操作

拖拽移動操作

react-beautiful-dnd操作

dnd-kit操作

react-dnd操作

????????react-dnd:一個用于在react應用中實現拖拽和放置功能的庫,它為開發者提供了一套靈活且可擴展的工具使得在react中處理拖拽交互變得簡單且高效,通過react-dnd開發者可以輕松地創建拖拽組件、設置拖拽目標以及處理拖拽過程中各個階段的事件(如開始拖拽、拖拽過程中、放置等),它不僅支持基礎的拖拽功能還允許開發者自定義拖拽行為、指定可放置區域、調整拖拽元素的樣式等,詳情請閱讀官方文檔:地址?,當然也可以去看看源碼:地址?進行學習,接下來我們終端執行如下命令進行安裝react-dnd,以下是使用拖拽的具體步驟:

npm install react-dnd react-dnd-html5-backend

包裹容器:接下來我們開始實現拖拽操作,react-dnd提供一個上下文提供者DndProvider,它用于在應用中啟用拖拽功能并且是實現拖拽交互的基礎,所有需要拖拽行為的組件都必須包裹在DndProvider中

HTML5Backend是react-dnd的一個后端實現,用于處理瀏覽器中的拖拽操作,通過引入react-dnd可以在瀏覽器中啟用標準的拖拽行為,代碼如下所示:

import Drag from './components/drag'
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';const App = () => {return (<DndProvider backend={ HTML5Backend }><Drag></Drag></DndProvider>)
}export default App

拖拽源:接下來我們開始設置拖拽源操作,react-dnd提供了useDrag用來提供對拖拽元素的一些操作,具體的代碼邏輯如下所示:

import { useDrag } from "react-dnd";
import "./index.less";const Draggable = () => {/*** 參數1:返回值是一個對象,主要放一些拖拽物的狀態* 參數2:ref實例,只要將它注入到DOM中該DOM就會變成一個可拖拽的DOM*/const [{ isDragging }, dragRef]: any = useDrag(() => ({type: "box", // 拖拽的類型,要和接收者那邊的類型對應上item: { id: "1" }, // 拖拽的數據,要和接收者那邊的數據對應上collect: (monitor) => ({ // 拖拽過程中的一些狀態,要和接收者那邊的數據對應上isDragging: monitor.isDragging(),}),}));return <div ref={dragRef} className="drag"></div>;
};export default Draggable;

通過如上代碼,調整一下css樣式之后,我們就可以對我們定義的div盒子進行拖拽操作了,如下:

如果想隱藏在拖拽過程中原本為啥的元素,可以通過參數1中的對象來確定是否在拖拽中,如果拖拽的話直接隱藏原本元素就好了,代碼如下:

import { useDrag } from "react-dnd";
import "./index.less";const Draggable = () => {/*** 參數1:返回值是一個對象,主要放一些拖拽物的狀態* 參數2:ref實例,只要將它注入到DOM中該DOM就會變成一個可拖拽的DOM*/const [{ isDragging }, dragRef]: any = useDrag(() => ({type: "box", // 拖拽的類型,要和接收者那邊的類型對應上item: { id: "1" }, // 拖拽的數據,要和接收者那邊的數據對應上collect: (monitor) => ({ // 拖拽過程中的一些狀態,要和接收者那邊的數據對應上isDragging: monitor.isDragging(),}),}));if (isDragging) {return <div ref={dragRef}></div>;}return <div ref={dragRef} className="drag"></div>;
};export default Draggable;

當然我們也可以通過props傳參的方式來實現不同拖拽的id的拖拽源,如下所示:

拖拽區域:接下來我們開始設置拖拽區域操作,react-dnd提供了useDrop用來提供對拖拽區域的一些操作,具體的代碼邏輯如下所示:

import { useDrop } from "react-dnd";
import "./index.less";const Droppable = () => {const [{ isOver }, drop]: any = useDrop(() => ({accept: 'box', // 只接受box類型的數據collect: (monitor) => ({ // 收集器,用來獲取拖拽過程中的一些信息isOver: monitor.isOver() }),drop: (item) => { // 放置事件處理函數console.log(item)}}))return <div ref={drop} className="drop"></div>;
};export default Droppable;

然后接下面我們定義幾個拖拽源,然后將拖拽元素拖拽到拖拽區域里面,可以執行放置時間的處理函數從而打印一下對應的數據,如下所示:

drop這個回調事件可以寫的很復雜這里我們可以將其抽離出去通過props來實現調用,useDrop支持第二個參數[state]作為依賴項,當你通過[state]將狀態傳入useDrop,你實際上是在告訴react當state發生變化時重新執行useDrop鉤子,useDrop就能根據最新的state來決定目標區域的行為或者重新計算是否可以接受拖拽等,如下所示:

import { useDrop } from "react-dnd";
import "./index.less";const Droppable = ({ handleDrop, state, text, children }: any) => {const [{ isOver }, drop]: any = useDrop(() => ({accept: 'box', // 只接受box類型的數據collect: (monitor) => ({ // 收集器,用來獲取拖拽過程中的一些信息isOver: monitor.isOver() }),drop: (item) => handleDrop(item) // 放置事件處理函數}), [state])return <div ref={drop} className="drop">{text}{children}</div>;
};export default Droppable;

拖拽排序操作

????????拖拽排序:說白了就是改變原數據的位置順序,這里我們使用了immutability-helper用于簡化js中不可變數據操作的工具包,它提供一些簡單API來更新嵌套的對象或數組而不會直接修改原數據,這樣可以避免直接變更數據確保數據的不可變性,終端執行如下命令安裝:

npm install immutability-helper

immutability-helper通常用于React中尤其是更新狀態時,幫助避免直接改變state的問題,比如更新嵌套對象或者數組的某個值時immutability-helper會返回一個新的對象而不是修改原對象例如使用它更新數組中的元素:

import update from 'immutability-helper';const state = [1, 2, 3];
const newState = update(state, { 1: { $set: 4 } });console.log(newState); // [1, 4, 3]

接下來我們在拖拽排序中使用,其中useCallback確保了moveCard和 renderCard函數不會在每次組件渲染時被重新創建,這樣避免了不必要的重新渲染和性能開銷。如下所示:

import update from 'immutability-helper'
import { useCallback, useState } from 'react'
import { Card } from './Card'const Index = () => {const [cards, setCards] = useState([{ id: 1, text: 'Write a cool JS library' },{ id: 2, text: 'Make it generic enough' },{ id: 3, text: 'Write README' },{ id: 4, text: 'Create some examples' },{ id: 5, text: 'Spam in Twitter and IRC to promote it (note that this element is taller than the others)' },{ id: 6, text: '???' },{ id: 7, text: 'PROFIT' },])const moveCard = useCallback((dragIndex: number, hoverIndex: number) => {setCards((prevCards: any) => update(prevCards, {$splice: [[dragIndex, 1],[hoverIndex, 0, prevCards[dragIndex]],],}))}, [])const renderCard = useCallback((card: any, index: number) => {return (<Card type='card' key={card.id} index={index} id={card.id} text={card.text} moveCard={moveCard} />)}, [])return (<><div style={{ width: '400px' }}>{cards.map((card, i) => renderCard(card, i))}</div></>)
}export default Index

然后接下來我們將拖拽源和放置源寫在同一個div區域內,這樣標簽內容就既可以拖拽又可以放置,具體代碼如下所示,這里我們通過在div元素設置data-handler-id來唯一地標識該div元素,方便對其進行操作:

import { useRef } from 'react'
import { useDrag, useDrop } from 'react-dnd'const style = {border: '1px dashed gray',padding: '0.5rem 1rem',marginBottom: '.5rem',backgroundColor: 'white',cursor: 'move',
}export const Card = ({ id, text, index, moveCard, type }: any) => {const ref = useRef<HTMLDivElement>(null)const [{ handlerId }, drop] = useDrop({accept: type,collect: (monitor) => ({ // 收集器,用來獲取拖拽過程中的一些信息handlerId: monitor.getHandlerId(), // 設置拖拽源的唯一標識,用來區分不同的拖拽源}),hover(item: any, monitor) {if (!ref.current) returnconst dragIndex = item.index // 拖拽元素的索引位置const hoverIndex = index // 鼠標懸停元素的索引位置if (dragIndex === hoverIndex) returnconst hoverBoundingRect = ref.current?.getBoundingClientRect() // 獲取鼠標懸停元素的邊界信息const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2 // 鼠標懸停元素的中點位置const clientOffset: any = monitor.getClientOffset() // 獲取鼠標在頁面中的位置信息const hoverClientY = clientOffset.y - hoverBoundingRect.topif (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) return // 如果拖拽元素在鼠標懸停元素的上方,并且鼠標位置在元素的中點下方,則不執行移動操作if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) return // 如果拖拽元素在鼠標懸停元素的下方,并且鼠標位置在元素的中點上方,則不執行移動操作moveCard(dragIndex, hoverIndex) // 調用moveCard函數,實現拖拽排序效果item.index = hoverIndex // 更新拖拽元素的索引位置},})const [{ isDragging }, drag] = useDrag({type,item: () => ({ id, index }),collect: (monitor: any) => ({isDragging: monitor.isDragging(),}),})const opacity = isDragging ? 0 : 1drag(drop(ref))return (<div ref={ref} style={{ ...style, opacity }} data-handler-id={handlerId}>{text}</div>)
}

最終呈現的效果如下所示:

拖拽移動操作

????????拖拽移動:說白了就是改變原數據的left和top值,借助依賴項的變化來控制拖拽源不斷改變其位置信息,如下我們定義一個拖拽源并且設置其依賴項的內容,如下所示:

import { useDrag } from 'react-dnd'const style: any = {position: 'absolute',border: '1px dashed gray',backgroundColor: 'white',width: '50px',height: '50px',cursor: 'move',
}
export const Box = ({ id, left, top, children, type }: any) => {const [{ isDragging }, drag]: any = useDrag(() => ({type,item: { id, left, top },collect: (monitor) => ({isDragging: monitor.isDragging(),}),}), [id, left, top])if (isDragging) return <div ref={drag} />return (<div ref={drag} style={{ ...style, left, top }}>{children}</div>)
}

然后我們通過如下代碼來設置其規定只能在范圍內進行移動,超出范圍自動回到原本位置:

import update from 'immutability-helper'
import { useCallback, useState } from 'react'
import { useDrop } from 'react-dnd'
import { Box } from './Box'const styles: any = {width: 300,height: 300,border: '1px solid black',position: 'relative',
}const Index = () => {const [boxes, setBoxes] = useState<any>({a: { top: 20, left: 80, title: 'box1' },b: { top: 180, left: 20, title: 'box2' },})const moveBox = useCallback((id: string, left: number, top: number) => {setBoxes(update(boxes, {[id]: { $merge: { left, top } },}),)}, [boxes, setBoxes])const [, drop]: any = useDrop(() => ({accept: 'box',drop(item: any, monitor) { // 拖拽結束時觸發的事件處理函數const delta: any = monitor.getDifferenceFromInitialOffset() // 獲取鼠標移動的距離let left = Math.round(item.left + delta.x) // 計算新的left值let top = Math.round(item.top + delta.y) // 計算新的top值// 最小和最大邊界限制left = Math.max(1, Math.min(left, 250));top = Math.max(1, Math.min(top, 250));moveBox(item.id, left, top) // 更新box的位置return undefined // 返回undefined,表示拖拽結束},}), [moveBox])return (<div style={{ display: 'flex', margin: '100px', gap: '30px' }}><div ref={drop} style={styles}>{Object.keys(boxes).map((key) => {const { left, top, title } = boxes[key]return (<Box key={key} id={key} left={left} top={top} type='box'>{title}</Box>)})}</div><div>box1: x坐標:{ boxes.a.left } - y坐標:{ boxes.a.top }<br/>box2: x坐標:{ boxes.b.left } - y坐標:{ boxes.b.top }</div></div>)
}export default Index

react-beautiful-dnd操作

????????react-beautiful-dnd:是一個用于react的拖放(drag-and-drop)庫,旨在幫助開發者在react應用中實現漂亮且易于使用的拖放交互,它提供了一個高效流暢且可訪問的拖放體驗,常用于實現類似列表排序卡片拖動等功能,終端執行如下命令安裝:

npm install react-beautiful-dnd --save

它和react-dnd的區別主要在于其專注于排序方面的內容,優勢如下,缺點就是React-beautiful-dnd 不支持React 高版本和嚴格模式,并且也是好幾年沒有維護了,大家需要根據自身情況選擇是否去使用

1)拖放排序:支持列表項(如任務卡、文件等)的排序,可以拖動列表項改變其順序。

2)跨列拖放:可以在多個列或容器之間拖動元素。

3)響應式:它的設計考慮了響應式和可訪問性,使得即使是在移動設備上或使用鍵盤的用戶也能夠順利使用拖放功能。

4)流暢動畫:提供平滑的動畫效果,使拖放過程更自然和易于理解。

5)高效:優化了性能,能夠在大量元素的情況下依然流暢運行。

我們可以通過訪問 鏈接?來查看其具體的實現案例操作,可以看到拖拽非常的絲滑,右側菜單還提供了各種場景下的案例操作:

接下來我們就寫一個簡單的示例進行演示一下,代碼如下所示:

import { useState, useCallback } from 'react';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';// 設置數組的初始元素
const getItems = (count: any) =>Array.from({ length: count }, (_: any, k) => k).map(k => ({ id: `item-${k}`, content: `item ${k}`}));// 重新排序數組元素
const reorder = (list: any, startIndex: any, endIndex: any) => {const result = Array.from(list);const [removed] = result.splice(startIndex, 1);result.splice(endIndex, 0, removed);return result;
};
const grid = 8;
// 獲取拖拽元素的樣式
const getItemStyle = (isDragging: any, draggableStyle: any) => ({userSelect: 'none',padding: grid * 2,margin: `0 ${grid}px 0 0`,background: isDragging ? 'lightgreen' : 'grey',...draggableStyle,
});
// 獲取列表的樣式
const getListStyle = (isDraggingOver: any) => ({background: isDraggingOver ? 'lightblue' : 'lightgrey',display: 'flex',padding: grid,overflow: 'auto',
});const App = () => {const [items, setItems] = useState(getItems(6));const onDragEnd = useCallback((result: any) => {// 是否拖拽到了其他位置if (!result.destination) return;const reorderedItems: any = reorder(items,result.source.index,result.destination.index);setItems(reorderedItems);}, [items]);return (<DragDropContext onDragEnd={onDragEnd}><Droppable droppableId="droppable" direction="horizontal">{(provided: any, snapshot: any) => (<div ref={provided.innerRef} style={getListStyle(snapshot.isDraggingOver)} {...provided.droppableProps}>{items.map((item, index) => (<Draggable key={item.id} draggableId={item.id} index={index}>{(provided: any, snapshot: any) => (<div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}style={getItemStyle( snapshot.isDragging, provided.draggableProps.style)}>{item.content}</div>)}</Draggable>))}{provided.placeholder}</div>)}</Droppable></DragDropContext>);
};export default App;

dnd-kit操作

??????? dnd-kit: 是一個用于實現拖放(drag-and-drop)交互的react庫,它提供了一組高效靈活的API使開發者能夠輕松構建具有拖放功能的應用,通過在瀏覽器中直接操作DOM元素并處理拖動放置以及元素重排的過程,使得用戶能夠在界面中拖動元素動態地改變其位置或順序,終端執行如下命令安裝:

npm install @dnd-kit/core

其主要優勢如下所示:

1)簡化拖放功能:封裝了拖放的核心邏輯開發者無需從頭開始編寫復雜的拖放機制

2)高度自定義:提供了豐富的API開發者可以自定義拖動行為、動畫效果、邊界限制、拖動過程中元素的樣式等

3)支持觸摸屏和桌面設備:同時支持鼠標和觸摸事件,適應不同設備。

4)性能優化:設計注重性能,通過高效的狀態管理和渲染機制保證即使在復雜場景下也能流暢運行。

我們可以通過訪問 鏈接?來查看其具體的實現案例操作,可以看到拖拽非常的絲滑,右側菜單還提供了各種場景下的案例操作:

接下來我們就寫一個簡單的示例進行演示一下,代碼如下所示:

import { useState } from 'react'
import { DndContext, useDroppable, useDraggable } from "@dnd-kit/core";// 設置放置和拖拽組件
const Droppable = (props: any) => {const {isOver, setNodeRef} = useDroppable({ id: props.id });return (<div ref={setNodeRef}>{props.children}</div>);
}
const Draggable = (props: any) => {const {attributes, listeners, setNodeRef, transform} = useDraggable({ id: props.id });const style = transform ? {transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,} : undefined;return (<div ref={setNodeRef} style={style} {...listeners} {...attributes}>{props.children}</div>);
}
export default function Index() {const containers = ['A', 'B', 'C','D','E'];const [parent, setParent] = useState(null);const draggableMarkup = (<Draggable id="draggable"><div style={{width:100,height:100,background:'pink',cursor:'move'}}>可拖拽組件</div></Draggable>);const handleDragEnd=(event: any)=> {const {over} = event;setParent(over ? over.id : null);}return (<DndContext onDragEnd={handleDragEnd}><div style={{display:'flex',justifyContent: 'space-between',paddingTop:50}}>{containers.map((id) => (<Droppable key={id} id={id}><div style={{width:200,height:200,border:'1px solid #000'}}>{parent === id ? draggableMarkup : '放置源'}</div></Droppable>))}</div>{parent === null ? draggableMarkup : null}</DndContext>);
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79433.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79433.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79433.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構與算法:回溯

回溯 先給出一些leetcode算法題&#xff0c;以后遇見了相關題目再往上增加 主要參考代碼隨想錄 2.1、組合問題 關于去重&#xff1a;兩種寫法的性能分析 需要注意的是&#xff1a;使用set去重的版本相對于used數組的版本效率都要低很多&#xff0c;大家在leetcode上提交&#x…

iview 分頁改變每頁條數時請求兩次問題

問題 在iview page分頁的時候&#xff0c;修改每頁條數時&#xff0c;會發出兩次請求。 iview 版本是4.0.0 原因 iview 的分頁在調用on-page-size-change之前會調用on-Change。默認會先調用on-Change回到第一頁&#xff0c;再調用on-page-size-change改變分頁顯示數量 此時就會…

一周學會Pandas2 Python數據處理與分析-Pandas2復雜數據查詢操作

鋒哥原創的Pandas2 Python數據處理與分析 視頻教程&#xff1a; 2025版 Pandas2 Python數據處理與分析 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 前面我們學了.loc[]等幾個簡單的數據篩選操作&#xff0c;但實際業務需求往 往需要按照一定的條件甚至復雜的組合條件…

【Vue bug】:deep()失效

vue 組件中使用了 element-plus 組件 <template><el-dialog:model-value"visible":title"title":width"width px":before-close"onClose"><div class"container" :style"{height:height px}"&g…

Trae 安裝第三方插件支持本地部署的大語言模型

Trae 安裝第三方插件支持本地部署的大語言模型 0. 引言1. 安裝插件 0. 引言 字節發布的 Trae IDE 一直不支持本地部署的的大語言模型。 Qwen3 剛剛發布&#xff0c;想在 Trae 中使用本地部署的 Qwen3&#xff0c;我們可以在 Trae 中安裝其他插件。 1. 安裝插件 我們可以安裝…

JavaScript 中的 Proxy 與 Reflect 教程

目錄 get 和 set 捕獲器詳解 為什么要用 Reflect? 使用語法間接調用內部方法 使用 Reflect 直接調用內部方法 對比總結: Reflect API 及其與 Proxy 的配合 Proxy 的典型應用場景 Proxy 是 ES6 引入的一種元編程特性。它允許創建一個代理對象來包裝目標對象,并攔截對目標…

基于STM32的心電圖監測系統設計

摘要 本論文旨在設計一種基于 STM32 微控制器的心電圖監測系統&#xff0c;通過對人體心電信號的采集、處理和分析&#xff0c;實現對心電圖的實時監測與顯示。系統采用高精度的心電信號采集模塊&#xff0c;結合 STM32 強大的數據處理能力&#xff0c;能夠有效去除噪聲干擾&a…

C語言----操作符詳解(萬字詳解)

目錄 1. 操作符的分類 2. 二進制和進制轉換 3. 原碼 反碼 補碼 4. 移位操作符 4.1 左移操作符 >> 4.2 右移操作符 >> 5. 位操作符 5.1 按位與 & 5.2 按位或 | 5.3 按位異或 ^ 5.4 按位取反 ~ 練習 整數存儲在內存中二進制中1的個數 練習 二進制位…

【進階】C# 委托(Delegate)知識點總結歸納

1. 委托的基本概念 定義&#xff1a;委托是一種類型安全的函數指針&#xff0c;用于封裝方法&#xff08;靜態方法或實例方法&#xff09;。 核心作用&#xff1a;允許將方法作為參數傳遞&#xff0c;實現回調機制和事件處理。 類型安全&#xff1a;委托在編譯時會檢查方法簽…

WebRTC 服務器之Janus視頻會議插件信令交互

1.基礎知識回顧 WebRTC 服務器之Janus概述和環境搭建-CSDN博客 WebRTC 服務器之Janus架構分析-CSDN博客 2.插件使用流程 我們要使?janus的功能時&#xff0c;通常要執?以下操作&#xff1a; 1. 在你的??引入 Janus.js 庫&#xff0c;即是包含janus.js&#xff1b; <…

Go語言中的無鎖數據結構與并發效率優化

1. 引言 在高并發系統開發中&#xff0c;性能瓶頸往往出現在并發控制上。作為一個有著10年Go開發經驗的后端工程師&#xff0c;我見證了無數因鎖競爭導致的性能問題&#xff0c;也親歷了無鎖編程為系統帶來的巨大提升。 傳統的鎖機制就像是十字路口的紅綠燈——雖然能確保安全…

STM32部分:2、環境搭建

飛書文檔https://x509p6c8to.feishu.cn/wiki/DQsBw76bCiWaO4kS8TXcWDs0nAh Keil MDK用于編寫代碼&#xff0c;編譯代碼芯片支持包&#xff0c;用于支持某類芯片編程支持STM32CubeMX用于自動生成工程&#xff0c;減少手動重復工作 STM32F1系列芯片支持包 軟件下載 直接下載&am…

U3D工程師簡歷模板

模板信息 簡歷范文名稱&#xff1a;U3D工程師簡歷模板&#xff0c;所屬行業&#xff1a;其他 | 職位&#xff0c;模板編號&#xff1a;B29EPQ 專業的個人簡歷模板&#xff0c;邏輯清晰&#xff0c;排版簡潔美觀&#xff0c;讓你的個人簡歷顯得更專業&#xff0c;找到好工作。…

Java設計模式: 實戰案例解析

Java設計模式: 實戰案例解析 在軟件開發中&#xff0c;設計模式是一種用來解決特定問題的可復用解決方案。它們是經過實踐驗證的最佳實踐&#xff0c;能夠幫助開發人員設計出高質量、易于維護的代碼。本文將介紹一些常見的Java設計模式&#xff0c;并通過實戰案例解析它們在實際…

Vue3源碼學習5-不使用 `const enum` 的原因

文章目錄 前言? 什么是 const enum? 為什么 Vue 3 不使用 const enum1. &#x1f4e6; **影響構建工具兼容性**2. &#x1f501; **難以做模塊間 tree-shaking**3. &#x1f9ea; **調試困難**4. &#x1f4e6; **Vue 是庫&#xff0c;不掌控用戶配置** ? 官方推薦做法&…

C++學習:六個月從基礎到就業——C++11/14:lambda表達式

C學習&#xff1a;六個月從基礎到就業——C11/14&#xff1a;lambda表達式 本文是我C學習之旅系列的第四十篇技術文章&#xff0c;也是第三階段"現代C特性"的第二篇&#xff0c;主要介紹C11/14中引入的lambda表達式。查看完整系列目錄了解更多內容。 引言 Lambda表達…

AIDC智算中心建設:計算力核心技術解析

目錄 一、智算中心發展概覽 二、計算力核心技術解析 一、智算中心發展概覽 智算中心是人工智能發展的關鍵基礎設施&#xff0c;基于人工智能計算架構&#xff0c;提供人工智能應用所需算力服務、數據服務和算法服務的算力基礎設施&#xff0c;融合高性能計算設備、高速網絡以…

IoTDB時序數據庫V2.0.2大版本更新的一些梳理

一些小知識&#xff1a; 關于事務&#xff1a;時序數據庫是沒有事務的&#xff0c;它和關系數據庫的應用場景不同&#xff0c;通常情況下不需要多點同時操作同一條數據&#xff0c;而且要保證極高的吐出量&#xff0c;事務太消耗資源&#xff0c;并且時序數據庫提供了覆寫的功能…

CSS定位詳解

在前端開發中&#xff0c;CSS 定位&#xff08;positioning&#xff09;是一個核心概念&#xff0c;它決定了元素在頁面上的位置和布局方式。無論是構建復雜的交互界面&#xff0c;還是實現簡單的頁面排版&#xff0c;CSS 定位都是不可或缺的工具。本文將全面介紹 CSS 中的五種…

React 語法擴展

useReducer鉤子函數 不同action類型返回不同處理行為 useState()函數返回解構為兩個值 state當前狀態 dispatch修改狀態函數 dispatch()函數參數為一個actuon對象 如 &#xff1a; 樣例&#xff1a; import { useReducer } from react; import ./App.css;// 定義一個Reduce…