React 低代碼項目:網絡請求與問卷基礎實現

🍞吐司問卷:網絡請求與問卷基礎實現

Date: February 10, 2025


Log

技術要點:

  • HTTP協議
  • XMLHttpRequest、fetch、axios
  • mock.js、postman
  • Webpack devServer 代理、craco.js 擴展 webpack
  • Restful API

開發要點:

  • 搭建 mock 服務

注:前端項目并不推薦直接使用 mock.js。因為它不支持 fetch,且上線時需要剔除模擬接口。

因此,建議構建一個簡易服務端,通過 Koa 搭建一個接口路由用于測試接口。

  • Ajax 封裝、useRequest 使用
  • 分頁、LoadMore



Mock 數據

前端 Mock 模擬 Ajax

要點:

  • 前端引入 mock.js 測試 api

安裝:

npm i mockjs
npm i --save-dev @types/mockjs  // 使用ts需要額外安裝

注意點:

  • mock.js 只能劫持 XMLHttpRequest,不能劫持 fetch
  • 要在生產環境(上線時)注釋掉,否則線上請求也被劫持

Case:

**效果:**會執行兩次 mock(原因見下)

image.png

定義的mock

import Mock from 'mockjs'Mock.mock('/api/test', 'get', () => {return {error: 0,data: {name: 'test',age: 18,},}
})

頁面中引用

import React, { FC, useEffect } from 'react'
import styles from './Home.module.scss'
import { useNavigate } from 'react-router-dom'
import { Typography, Button } from 'antd'
import { MANAGE_INDEX_PATHNAME } from '../router'
import axios from 'axios'
import '../_mock/index'const { Title, Paragraph } = Typographyconst Home: FC = () => {const nav = useNavigate()useEffect(() => {axios.get('/api/test').then(res => console.log(res))}, [])return (<div className={styles.container}><div className={styles.info}><Title>問卷調查 | 在線投票</Title><Paragraph>已累計創建問卷 100 份,發布問卷 90 份,收到答卷 980 份</Paragraph><div><Button type="primary" onClick={() => nav(MANAGE_INDEX_PATHNAME)}>創建問卷</Button></div></div></div>)
}export default Home

思考:

為什么 useEffect 會執行兩次?

React 18 中,useEffect 默認會在開發模式下執行兩次,這是為了幫助開發者發現副作用的潛在問題。

參考:

https://github.com/nuysoft/Mock/wiki/Getting-Started



服務端 nodejs 實現 mock.js

服務端 mock 實現

目標:

  • 服務端實現mock

要點:

  • mock.js 用于劫持網絡請求,并實現豐富的 Random 能力
  • mock.js 部署于 nodejs 服務端,并實現 Random 功能

安裝:

npm init -y
npm i mockjs
npm i koa koa-router
npm i nodemon  # 用于監聽node修改, 不用重啟項目

功能實現:

思路:服務端采用 Koa 構建路由處理需要 Mock 的 api

mock文件夾用于存放 Mock 的api,其中 index 做所有 Mock api 的整合。

目錄:

.
├── index.js
├── mock
│   ├── index.js
│   ├── question.js
│   └── test.js
├── package-lock.json
├── package.json
└── projectTree.md2 directories, 7 files

index.js

注意:這里設計 getRes() 可以刻意延遲 1s,模擬 loading 效果

const Koa = require('koa')
const Router = require('koa-router')
const mockList = require('./mock/index')const app = new Koa()
const router = new Router()// 模擬網絡延遲函數
async function getRes(fn) {return new Promise(resolve => {setTimeout(() => {const res = fn()resolve(res)}, 1000)})
}mockList.forEach(item => {const {url, method, response} = itemrouter[method](url, async (ctx, next) => {const res = await getRes(response)ctx.body = res})
})
app.use(router.routes())
app.listen(3002)

mock/index.js

const test = require('./test')
const question = require('./question')const mockList = [...test,...question
]module.exports = mockList

question.js

const Mock = require('mockjs')const Random = Mock.Randommodule.exports = [{url: '/api/question/:id',method: 'get',response() {return {error: 0,data: {id: Random.id(),title: Random.ctitle(),content: Random.cparagraph()}}}}, {url: '/api/question',method: 'post',response() {return {error: 0,data: {id: Random.id()}}}}
]

**測試:**采用 postman 進行測試 post 請求

image.png


跨域問題處理

**目標:**處理跨域問題

剛剛我們搞定了服務端的 Mock,并處理了前端頁面。現在遇到跨域問題:

問題:

image.png

問題原因:

http://localhost:3001/home 訪問 http://localhost:3002/api/test 會產生 CORS 即跨域問題

Home.tsx

  const nav = useNavigate()useEffect(() => {try {const fetchData = async () => {try {const response = await axios.get('http://localhost:3001/api/test')console.log(response.data) // 輸出返回的響應數據} catch (error) {console.error('請求失敗', error)}}fetchData()} catch (error) {console.error('請求失敗', error)}}, [])

解決方案:

采用 Craco 來處理 React 中的跨域問題,本質上講是通過拓展 React 的 CRA 工具配置來處理跨域

具體步驟:

  • 前端配置Craco: 配置見參考文檔
  • 通過 Craco 構建 api 代理

image.png

**結果:**成功處理

image.png

參考文檔:

  • https://github.com/dilanx/craco



API 設計

Restful API

概念:

RESTful API 是一種基于 REST(Representational State Transfer)架構風格的 Web 服務設計方法。

特點:

資源導向

  • 將系統中的所有內容視為資源,每個資源有唯一的 URI(統一資源標識符)。例如,/users 表示用戶資源。

無狀態性(Statelessness)

  • 每個請求都是獨立的,不依賴于之前的請求。服務器不保留客戶端狀態信息。

表現層狀態轉移(Representation of Resources)

  • 通過 JSON、XML 等格式在客戶端和服務器之間傳遞資源的表現形式,而不是資源本身。

統一接口

  • 定義一致的方式進行操作,使得不同的客戶端可以以統一的接口與服務器交互。

自描述消息

  • 請求和響應中包含所有必要的信息,例如 HTTP 狀態碼、頭信息等,以幫助客戶端理解操作結果。

可緩存性

  • 設計 API 使得響應可以被緩存,從而提高性能。

使用標準 HTTP 方法

  • 使用 HTTP 動詞來操作資源:
    • GET:獲取資源。
    • POST:創建資源。
    • PUT:更新資源。
    • DELETE:刪除資源。

總結:

RESTful API 簡潔靈活,適用于構建現代Web服務,因其遵循標準化的設計原則,使得開發和集成變得簡單直觀。



用戶和問卷API設計

以下是設計的 API 表格,涵蓋了用戶功能和問卷功能:

功能方法路徑請求體響應
獲取用戶信息GET/api/user/info{ errno: 0, data: {...} }{ errno: 10001, msg: 'xxx' }
注冊POST/api/user/register{ username, password, nickname }{ errno: 0 }
登錄POST/api/user/login{ username, password }{ errno: 0, data: { token } } — JWT 使用 token
創建問卷POST/api/question{ errno: 0, data: { id } }
獲取單個問卷GET/api/question/:id{ errno: 0, data: { id, title ... } }
獲取問卷列表GET/api/question{ errno: 0, data: { list: [ ... ], total } }
更新問卷信息PATCH/api/question/:id{ title, isStar ... }{ errno: 0 }
批量徹底刪除問卷DELETE/api/question{ ids: [ ... ] }{ errno: 0 }
復制問卷POST/api/question/duplicate/:id{ errno: 0, data: { id } }

說明:

  • GET 請求 通常用于獲取資源,不需要請求體。
  • POST 請求 用于創建資源或進行某些操作,可能需要請求體包含必要的數據。
  • PATCH 請求 用于部分更新資源,需要請求體提供更新的字段和值。
  • DELETE 請求 用于刪除資源,這里是“假刪除”,通過更新 isDeleted 屬性實現。



問卷功能實現

目標:

  • 配置 axios 基礎功能
  • 開發問卷功能,期間使用 useRequest
  • 分頁和 LoadMore


接口案例測試

**目標:**構建接口文件并測試

要點:

  • 設計 axios instance 實例
  • 設計 getQuestionList 接口
  • 測試 getQuestionList 接口

文件樹:

├── src
│   ├── services
│   │   ├── ajax.ts
│   │   └── question.ts

ajax.ts

import axios from 'axios'
import { message } from 'antd'const instance = axios.create({timeout: 10000,
})instance.interceptors.response.use(res => {const resData = (res.data || {}) as ResTypeconsole.log('resData', resData)const { errno, data, msg } = resDataif (errno !== 0) {if (msg) {message.error(msg)}throw new Error(msg || '未知錯誤')}return data as any
})export default instanceexport type ResType = {errno: numberdata?: ResDataTypemsg?: string
}// key表示字段名,any表示字段值的類型
export type ResDataType = {[key: string]: any
}

question.tsx

import axios, { ResDataType } from './ajax'export const getQuestionList = async (id: string): Promise<ResDataType> => {const url = `/api/question/${id}`const data = (await axios.get(url)) as ResDataTypereturn data
}

接口測試:

import React, { FC, useEffect } from 'react'
import { useParams } from 'react-router-dom'
import { getQuestionList } from '../../../services/question'const Edit: FC = () => {const { id = '' } = useParams()useEffect(() => {async function fetchData() {const res = await getQuestionList(id)console.log('res', res)}fetchData()}, [])return (<div><h1>Edit {id}</h1></div>)
}export default Edit

image.png



設置 loading 狀態優化體驗

前言:之前我們在設計接口的時候,故意設計延遲函數用于模擬

// 模擬網絡延遲函數
async function getRes(fn) {return new Promise(resolve => {setTimeout(() => {const res = fn()resolve(res)}, 1000)})
}

**問題:**現在我們設計完成新增問卷函數 createQuestionService() 。實際測試時,點擊創建頁面到新頁面時,會發生1s的延遲。在這期間,我們仍然可以頻繁點擊創建問卷,如下所示:

2025-02-08 16.43.17.gif

**解決方案:**設置 disable 屬性,當點擊時禁用問卷創建即可

2025-02-08 16.42.31.gif

Case:

import { createQuestionService } from '../services/question'
const ManageLayout: FC = () => {const nav = useNavigate()const { pathname } = useLocation()const [loading, setLoading] = useState(false)async function handleCreateClick() {setLoading(true)const data = await createQuestionService()const { id } = dataif (id) {nav(`/question/edit/${id}`)message.success('創建成功')}setLoading(false)}return (<><div className={styles.container}><div className={styles.left}><Flex gap="small" wrap><Buttontype="primary"size="large"icon={<PlusOutlined />}disabled={loading}onClick={handleCreateClick}>新建問卷</Button></Flex></div></>)
}export default ManageLayout


自定義Hook抽離公共邏輯

**思路:**抽離原有的獲取編輯頁面的數據為 hook,方便編輯頁面進行復用。

不用 Hook 之前:/edit/index

import React, { FC, useState, useEffect } from 'react'
import { useParams } from 'react-router-dom'
import { getQuestionListService } from '../../../services/question'const Edit: FC = () => {const { id = '' } = useParams()const [loading, setLoading] = useState(true)const [questionData, setQuestionData] = useState({})useEffect(() => {async function fetchData() {const res = await getQuestionListService(id)setQuestionData(res)setLoading(false)}fetchData()}, [])return (<div><h1>Edit {id}</h1>{loading ? (<div>Loading...</div>) : (<div><p>{JSON.stringify(questionData)}</p></div>)}</div>)
}export default Edit

Hook設計:

hooks/useLoadQuestionData

import { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import { getQuestionListService } from '../services/question'function useLoadQuestionData() {const { id = '' } = useParams()const [loading, setLoading] = useState(true)const [questionData, setQuestionData] = useState({})useEffect(() => {async function fetchData() {const res = await getQuestionListService(id)setQuestionData(res)setLoading(false)}fetchData()}, [])return { loading, questionData }
}export default useLoadQuestionData

優化之后:/edit/index

import React, { FC } from 'react'
import { useParams } from 'react-router-dom'
import useLoadQuestionData from '../../../hooks/useLoadQuestionData'const Edit: FC = () => {const { id = '' } = useParams()const { loading, questionData } = useLoadQuestionData()return (<div><h1>Edit {id}</h1>{loading ? (<div>Loading...</div>) : (<div><p>{JSON.stringify(questionData)}</p></div>)}</div>)
}export default Edit


useRequest重構Ajax請求

**思路:**采用 ahooks 中的 useRequest 鉤子重構之前的 Ajax 請求

useRequest:

默認請求:默認情況下,useRequest 第一個參數是一個異步函數,在組件初始化時,會自動執行該異步函數。同時自動管理該異步函數的 loading , data , error 等狀態。

const { data, error, loading } = useRequest(service);

**Case:**重構 useLoadQuestionData

原本:

import { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import { getQuestionListService } from '../services/question'function useLoadQuestionData() {const { id = '' } = useParams()const [loading, setLoading] = useState(true)const [questionData, setQuestionData] = useState({})useEffect(() => {async function fetchData() {const res = await getQuestionListService(id)setQuestionData(res)setLoading(false)}fetchData()}, [])return { loading, questionData }
}export default useLoadQuestionData

重構之后:

import { useParams } from 'react-router-dom'
import { getQuestionListService } from '../services/question'
import { useRequest } from 'ahooks'function useLoadQuestionData() {const { id = '' } = useParams()async function load() {const data = await getQuestionListService(id)return data}const { data, loading } = useRequest(load)return { data, loading }
}export default useLoadQuestionData

參考:

https://ahooks.js.org/zh-CN/hooks/use-request/index#index-default



分頁功能實現

要點:

  • 從 URL 參數中獲取 page 和 pageSize, 并同步到 Pagination 組件中
  • 當 page 或 pageSize 變化時, 更新 URL 參數
  • AntD 中 Pagination 的 current、pageSize、total、onChange 等屬性和方法

ListPage.tsx

import React, { FC } from 'react'
import { Pagination, PaginationProps } from 'antd'
import { useSearchParams, useNavigate, useLocation } from 'react-router-dom'
import {LIST_PAGE_SIZE,LIST_PAGE_PARAM_KEY,LIST_PAGE_SIZE_PARAM_KEY,
} from '../constant'type ListPageProps = {total: number
}const ListPage: FC<ListPageProps> = (props: ListPageProps) => {const { total } = propsconst [current, setCurrent] = React.useState(1)const [pageSize, setPageSize] = React.useState(LIST_PAGE_SIZE)// 從 URL 參數中獲取 page 和 pageSize, 并同步到 Pagination 組件中const [searchParams] = useSearchParams()const nav = useNavigate()const { pathname } = useLocation()const handleChange: PaginationProps['onChange'] = pageNumber => {searchParams.set(LIST_PAGE_PARAM_KEY, pageNumber.toString())searchParams.set(LIST_PAGE_SIZE_PARAM_KEY, pageSize.toString())nav({pathname,search: searchParams.toString(),})}React.useEffect(() => {const page = parseInt(searchParams.get(LIST_PAGE_PARAM_KEY) || '') || 1const pageSize =parseInt(searchParams.get(LIST_PAGE_SIZE_PARAM_KEY) || '') ||LIST_PAGE_SIZEsetCurrent(page)setPageSize(pageSize)}, [searchParams])return (<Paginationcurrent={current}pageSize={pageSize}total={total}onChange={handleChange}/>)
}export default ListPage

問卷中進行使用:

Star.tsx

...
const { Title } = Typographyconst Star: FC = () => {useTitle('星標問卷')const { data = {}, loading } = useLoadQuestionListData({ isStar: true })const { list = [], total = 0 } = datareturn (<>...{!loading && list.length > 0 && (<div className={styles.footer}><ListPage total={total} /></div>)}</>)
}export default Star


LoadMore 功能實現

要點:

  • 防抖功能實現

思路:

當頁面的 ele 的 bottom 距離頂部一段距離時,自動加載頁面

image.png



問卷標星、復制、刪除功能

**目標:**實現問卷標星功能

**效果:**點擊星標更新

2025-02-10 15.27.50.gif

思路:

  • 標星接口更新實現:采用 useRequest 實現
  • 頁面標星狀態更新:采用 useRequest 的回調函數實現

Code:

const [isStarState, setIsStarState] = useState(isStar)// 標星接口更新實現
const { loading: changeStarLoading, run: changeStar } = useRequest(async () => {await updateQuestionService(_id, { isStar: !isStarState })},{// 頁面標星狀態更新manual: true,onSuccess: () => {setIsStarState(!isStarState)message.success('已更新')},}
)

**目標:**實現問卷復制功能

思路:

  • 實現復制功能的接口請求
  • 實現復制功能的回調實現,實現導航到編輯頁面

細節:

  • 防止重復點擊:loading: duplicateLoading 綁定到 Button 上,當我們點擊復制后,在接口數據返回前,按鈕無法再次點擊。

Code:

const { loading: duplicateLoading, run: duplicate } = useRequest(async () => {const data = await duplicateQuestionService(_id)return data},{manual: true,onSuccess: (res: any) => {message.success('復制成功')nav(`/question/edit/${res.id}`)},}
)----<Popconfirmtitle="確認復制嗎?"okText="確認"cancelText="取消"onConfirm={duplicate}
><Buttontype="text"size="small"icon={<CopyOutlined />}disabled={duplicateLoading}>復制</Button>
</Popconfirm>

**目標:**實現問卷刪除功能

**需求:**實現刪除功能,問卷點擊刪除是假刪除,刪除后,問卷會進入回收站

思路:

  • 實現刪除功能的接口請求與回調
  • 實現當刪除后,頁面會不再渲染此卡片
const [isDeleted, setIsDeleted] = useState(false)
const { loading: deleteLoading, run: deleteQuestion } = useRequest(async () => await updateQuestionService(_id, { isDeleted: true }),{manual: true,onSuccess: () => {message.success('刪除成功')},}
)
function del() {confirm({title: '刪除問卷',icon: <ExclamationCircleOutlined />,onOk() {deleteQuestion()setIsDeleted(true)},})
}
// 實現當刪除后,頁面會不再渲染此卡片
if (isDeleted) return null // 已經刪除的問卷,不要再渲染卡片了return (<div className={styles.container}><div className={styles.title}><div className={styles.left}>...---<Buttontype="text"size="small"icon={<DeleteOutlined />}onClick={del}disabled={deleteLoading}
>刪除
</Button>


問卷恢復與刪除

要點:

  • for await (const id of selectionIds) 可以遍歷請求
  • useRequeset 中的debounceWait 可以實現恢復防抖

2025-02-17 16.01.24.gif

  • useRequeset 中的refresh() 可以實現:使用上一次的參數,重新發起請求。

理解:refresh() 觸發數據的重新加載,它確保在執行恢復和刪除操作后,頁面上的數據能夠及時更新,避免了顯示過時的信息。

Code:

const {data = {},loading,refresh,
} = useLoadQuestionListData({ isDeleted: true })...// 恢復
const { run: recover } = useRequest(async () => {for await (const id of selectionIds) {await updateQuestionService(id, { isDeleted: false })}},{manual: true,debounceWait: 500,onSuccess: () => {message.success('恢復成功')refresh()setSelectionIds([])},}
)// 刪除
const { run: deleteQuestion } = useRequest(async () => await deleteQuestionService(selectionIds),{manual: true,onSuccess: () => {message.success('刪除成功')refresh()setSelectionIds([])},}
)

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

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

相關文章

安裝海康威視相機SDK后,catkin_make其他項目時,出現“libusb_set_option”錯誤的解決方法

硬件&#xff1a;雷神MIX G139H047LD 工控機 系統&#xff1a;ubuntu20.04 之前運行某項目時&#xff0c;處于正常狀態。后來由于要使用海康威視工業相機&#xff08;型號&#xff1a;MV-CA013-21UC&#xff09;&#xff0c;便下載了并安裝了該相機的SDK&#xff0c;之后運行…

人工智能之自動駕駛技術體系

自動駕駛技術體系 自動駕駛技術是人工智能在交通領域的重要應用&#xff0c;旨在通過計算機視覺、傳感器融合、路徑規劃等技術實現車輛的自主駕駛。自動駕駛不僅能夠提高交通效率&#xff0c;還能減少交通事故和環境污染。本文將深入探討自動駕駛的技術體系&#xff0c;包括感…

淺談模組-相機鬼像

一&#xff0e;前言 在成像中&#xff0c;我們常常會遇到肉眼觀測的真實世界中&#xff0c;不存在的異常光影出現在畫面中&#xff0c;并伴有各種顏色&#xff0c;我們將這個物體稱為鬼像。某些鬼像可能會對圖像產生美感的體驗&#xff0c;但是大多數的鬼像都會對圖像的質量以…

vmware虛擬機Ubuntu Desktop系統怎么和我的電腦相互復制文件、內容

1、先安裝vmware workstation 17 player&#xff0c;然后再安裝Ubuntu Desktop虛擬機&#xff0c;然后再安裝vmware tools&#xff0c;具體可以參考如下視頻&#xff1a; VMware虛擬機與主機實現文件共享&#xff0c;其實一點也不難_嗶哩嗶哩_bilibili 2、本人親自試過了&…

Spring Boot項目中解決跨域問題(四種方式)

目錄 一&#xff0c;跨域產生的原因二&#xff0c;什么情況下算跨域三&#xff0c;實際演示四&#xff0c;解決跨域的方法 1&#xff0c;CrossOrigin注解2&#xff0c;添加全局過濾器3&#xff0c;實現WebMvcConfigurer4&#xff0c;Nginx解決跨域5&#xff0c;注意 開發項目…

Oracle JDK、Open JDK zulu下載地址

一、Oracle JDK https://www.oracle.com/java/technologies/downloads/ 剛進去是最新的版本&#xff0c;往下滑可以看到老版本 二、Open JDK的 Azul Zulu https://www.azul.com/downloads/ 直接可以選版本等選項卡

軟件測試:1、單元測試

1. 單元測試的基本概念 單元&#xff08;Unit&#xff09;&#xff1a;軟件系統的基本組成單位&#xff0c;可以是函數、模塊、方法或類。 單元測試&#xff08;Unit Testing&#xff09;&#xff1a;對軟件單元進行的測試&#xff0c;驗證代碼的正確性、規范性、安全性和性能…

Leetcode.264 丑數 II

題目鏈接 Leetcode.264 丑數 II mid 題目描述 給你一個整數 n n n &#xff0c;請你找出并返回第 n n n 個 丑數 。 丑數 就是質因子只包含 2 2 2、 3 3 3 和 5 5 5 的正整數。 示例1&#xff1a; 輸入&#xff1a;n 10 輸出&#xff1a;12 解釋&#xff1a;[1, 2, 3,…

瑞芯微RV1126部署YOLOv8全流程:環境搭建、pt-onnx-rknn模型轉換、C++推理代碼、錯誤解決、優化、交叉編譯第三方庫

目錄 1 環境搭建 2 交叉編譯opencv 3 模型訓練 4 模型轉換 4.1 pt模型轉onnx模型 4.2 onnx模型轉rknn模型 4.2.1 安裝rknn-toolkit 4.2.2 onn轉成rknn模型 5 升級npu驅動 6 C++推理源碼demo 6.1 原版demo 6.2 增加opencv讀取圖片的代碼 7 交叉編譯x264 ffmepg和op…

【Python爬蟲(32)】從單飛 to 團戰:Python多線程爬蟲進化史

【Python爬蟲】專欄簡介&#xff1a;本專欄是 Python 爬蟲領域的集大成之作&#xff0c;共 100 章節。從 Python 基礎語法、爬蟲入門知識講起&#xff0c;深入探討反爬蟲、多線程、分布式等進階技術。以大量實例為支撐&#xff0c;覆蓋網頁、圖片、音頻等各類數據爬取&#xff…

C#初級教程(1)——C# 與.NET 框架:探索微軟平臺編程的強大組合

圖片來源&#xff1a; https://www.lvhang.site/docs/dotnettimeline 即夢AI - 一站式AI創作平臺 一、歷史發展脈絡 在早期的微軟平臺編程中&#xff0c;常用的編程語言有 Visual Basic、C、C。到了 20 世紀 90 年代末&#xff0c;Win32 API、MFC&#xff08;Microsoft Found…

【接口封裝】——13、登錄窗口的標題欄內容設置

解釋&#xff1a; 1、封裝內容&#xff1a;圖標、文本內容、寬度 2、ui.iconLabel&#xff1a;在UI文件中的自定義命名 3、引入頭文件&#xff1a;#include<qpixmap.h> 函數定義&#xff1a; #pragma once#include <QWidget> #include "ui_TitleBar.h"cl…

DeepSeek全生態接入指南:官方通道+三大云平臺

DeepSeek全生態接入指南&#xff1a;官方通道三大云平臺 一、官方資源入口 1.1 核心交互平臺 &#x1f5a5;? DeepSeek官網&#xff1a; https://chat.deepseek.com/ &#xff08;體驗最新對話模型能力&#xff09; 二、客戶端工具 OllamaChatboxCherry StudioAnythingLLM …

web安全:跨站請求偽造 (CSRF)

跨站請求偽造 (CSRF) ? 跨站請求偽造&#xff08;CSRF&#xff0c;Cross-Site Request Forgery&#xff09; 是一種網絡攻擊方式&#xff0c;攻擊者誘使受害者在未經其授權的情況下執行特定操作。CSRF 利用受害者已登錄的身份和瀏覽器自動發送的認證信息&#xff08;如 Cooki…

前端ES面試題及參考答案

目錄 let/const 與 var 的區別?TDZ 是什么? 箭頭函數與普通函數的區別?箭頭函數能否作為構造函數? 模板字符串的嵌套表達式和標簽模板用法? 解構賦值的應用場景及對象 / 數組解構差異? 函數參數默認值的生效條件及暫時性死區問題? 展開運算符(...)在數組 / 對象中…

Windows 圖形顯示驅動開發-查詢 WDDM(3.2) 功能支持和啟用

查詢 Windows 顯示驅動程序模型 (WDDM) 功能的支持和啟用。 其中介紹了&#xff1a; 用戶模式和內核模式顯示驅動程序&#xff08;UMD 和 KMD&#xff09;如何查詢 OS&#xff0c;以確定 WDDM 功能在系統上是否受支持和已啟用。 OS 如何確定驅動程序是否支持特定的 WDDM 功能…

MySQL InnoDB 存儲引擎的索引詳解

在 MySQL 中&#xff0c;InnoDB 是最常用的存儲引擎&#xff0c;它支持事務、行級鎖和外鍵約束等功能&#xff0c;而索引則是提升數據庫查詢性能的關鍵。在 InnoDB 存儲引擎中&#xff0c;索引不僅僅是提高查詢速度的工具&#xff0c;還是數據庫的核心組成部分之一。本文將詳細…

基于Spring Boot的RabbitMQ延時隊列技術實現

文章目錄 基于Spring Boot的RabbitMQ延時隊列技術實現延時隊列應用場景基本概念實現延時隊列添加依賴基礎配置配置類設計消息生產者消息消費者 兩種TTL設置方式 訂單超時關閉實例訂單服務消息處理 延遲消息插件安裝插件配置延遲交換機 基于Spring Boot的RabbitMQ延時隊列技術實…

畢業項目推薦:基于yolov8/yolov5/yolo11的番茄成熟度檢測識別系統(python+卷積神經網絡)

文章目錄 概要一、整體資源介紹技術要點功能展示&#xff1a;功能1 支持單張圖片識別功能2 支持遍歷文件夾識別功能3 支持識別視頻文件功能4 支持攝像頭識別功能5 支持結果文件導出&#xff08;xls格式&#xff09;功能6 支持切換檢測到的目標查看 二、數據集三、算法介紹1. YO…

【智能客服】ChatGPT大模型話術優化落地方案

本文原創作者:姚瑞南 AI-agent 大模型運營專家,先后任職于美團、獵聘等中大廠AI訓練專家和智能運營專家崗;多年人工智能行業智能產品運營及大模型落地經驗,擁有AI外呼方向國家專利與PMP項目管理證書。(轉載需經授權) 目錄 一、項目背景 1.1 行業背景 1.2 業務現…