输入人民币金额的参数要求:

输入要求:

  • 通过键盘,只允许输入负号、小数点、数字、退格键、删除键、方向左键、方向右键、Home键、End键、Tab键;
  • 负号只能在开头;
  • 只保留第一个小数点;
  • 替换全角输入的小数点,即“。”替换为“.”;
  • 小数点开头的前面补0;
  • 限制小数点后最多两位;
  • 去除前导零(非小数的情况下,去除开头的0);
  • 通过复制粘贴的,确保粘贴出来的内容符合上述的要求。

显示要求:

  • 聚焦时 @focus 显示原始金额数值,如:1234.56;
  • 失焦时 @blur 格式化金额数值,如:¥ 1,234.56;
  • 键盘输入 @keydown 按输入要求过滤内容;
  • 输入内容 @input 防漏兜底,防止通过粘贴输入的,按输入要求过滤内容;
  • 回车时 @keyup.enter.native="$event.target.blur()" 失焦;

方法一:使用 el-input 的 @input 和 @blur

优点:输入方便,可以自由输入

缺点:改变原值

如:

输入的原值为:1234.56

显示的内容为:¥1,234.56

最终值为:¥1,234.56

示例代码:

<script setup lang="ts" name="MaterialOut">
import { ref } from "vue";
import { formatInputRMB, formatToRMB, formatRMB } from "@/utils/formatter";// 金额
const total = ref<string>("");
</script><template><!-- 控制输入:@input="total = formatInputRMB($event)" 控制只能输入数字、小数点(两位小数) --><!-- 控制显示:@blur="total = formatRMB(formatToRMB(total))" 输入框失去焦点时,将输入框内容格式化为人民币格式 --><!-- 控制失焦:@keyup.enter.native="$event.target.blur()" 按回车输入框失去焦点 --><el-inputv-model="total"@input="total = formatInputRMB($event)"@blur="total = formatRMB(formatToRMB(total))"@keyup.enter.native="$event.target.blur()"placeholder="请输入金额,按回车确认" />
</template>

 formatter.ts

/*** 格式化输入人民币金额* @param val 输入值* @returns 数字字符串,如:0、123、1234.0、1234.56*/
export const formatInputRMB = (val: string) => {let result = val ?? "";// 格式化输入的内容result = result// 替换全角输入的小数点.replace(/。/g, ".")// 只保留数字和小数点.replace(/[^\d.]/g, "")// 小数点开头的前面补0.replace(/^\./, "0.")// 只保留第一个小数点.replace(/(\..*)\./g, "$1")// 去除前导零,非小数的情况下,去除开头的0.replace(/^0+(\d)/, "$1")// 限制小数点后最多两位.replace(/^(\d+\.\d{2})\d+/, "$1");return result;
};/*** 格式化为人民币金额* @param val 字符串或数字* @param rounding 是否四舍五入(默认 true,若设为 false 则直接截断)* @returns 数字字符串,如:0.00、1.20、123.04、1234.56*/
export const formatToRMB = (val: string | number | null, rounding: boolean = true) => {let result = String(val || "0.00");// 格式化输入的内容result = result// 替换全角输入的小数点.replace(/。/g, ".")// 只保留数字和小数点.replace(/[^\d.]/g, "")// 小数点开头的前面补0.replace(/^\./, "0.")// 只保留第一个小数点.replace(/(\..*)\./g, "$1")// 去除前导零,非小数的情况下,去除开头的0.replace(/^0+(\d)/, "$1");// 分割整数部分和小数部分let [integer = "0", decimal = ""] = result.split(".");// 四舍五入处理小数部分if (rounding) {// 四舍五入处理(通过 Number 转换自动处理)const rounded = Math.round(Number(`${integer}.${decimal}`) * 100) / 100;return rounded.toFixed(2);}// 截断处理小数部分else {// 截断并补零decimal = decimal.slice(0, 2).padEnd(2, "0");// 确保整数部分存在integer = integer ?? "0";return `${integer}.${decimal}`;}
};/**** 格式化为带符号和千分位的人民币金额* @param val 字符串或数字* @param rounding 是否四舍五入(默认 true,若设为 false 则直接截断)* @returns 人民币金额字符串,如:¥0.00、¥1.20、¥123.04、¥1,234.56*/
export const formatRMB = (val: string | number) => {let result = formatToRMB(val);// 添加人民币符号 ¥,添加千分位 ,result = "¥" + result.replace(/\B(?=(\d{3})+(?!\d))/g, ",");return result;
};

效果:

输入前

输入中 

回车确认后

方法二:使用 el-input 的 :formatter 和 :parser

优点:保持原值

缺点:输入受限,不能自由输入

如:

输入的原值为:1234.56

显示的内容为:¥1,234.56

最终值为:1234.56

示例代码:

<script setup lang="ts" name="MaterialOut">
import { ref } from "vue";// 存储原始数值(用于业务逻辑)
const total = ref<number | null>(null);// 格式化显示金额(用于 input 显示)
const formatRMB = (value: number | null): string => {if (value === null || isNaN(value)) return "";const valStr = value.toFixed(2);const [integer, decimal] = valStr.split(".");const formattedInteger = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ",");return `¥ ${formattedInteger}.${decimal}`;
};// 解析输入内容(用于 input 输入)
const parseRMB = (value: string): string => {// 去除非数字和小数点字符let filtered = value.replace(/[^\d.]/g, "").replace(/(\..*)\./g, "$1");if (filtered === "." || filtered === "") return "";const [integer = "0", decimal] = filtered.split(".");const cleanInteger = integer.replace(/^0+/, "") || "0";const cleanDecimal = decimal ? decimal.slice(0, 2) : "";return cleanDecimal ? `${cleanInteger}.${cleanDecimal}` : cleanInteger;
};// 输入事件处理
const handleInput = (value: string) => {const parsed = parseRMB(value);total.value = parsed ? parseFloat(parsed) : null;
};
</script><template><el-inputv-model="total":formatter="(val: string) => formatRMB(val ? parseFloat(val) : null)":parser="(val: string) => parseRMB(val)"@input="handleInput"@keyup.enter.native="$event.target.blur()"type="text"placeholder="请输入金额,按回车确认" />
</template>

效果:

输入前

 输入中

回车确认后 

方法三(推荐):使用 el-input 的 @focus、@blur、@keydown、@input

优点:输入方便,可以自由输入,保持原值

缺点:无

<script setup lang="ts" name="MaterialOut">
import { ref } from "vue";// 存储原始数值(用于业务逻辑)
const total = ref<number | null>(null);// 输入框内部状态(带格式)
const inputValue = ref<string>("");// 处理键盘输入
function handleKeyDown(e: KeyboardEvent) {// 只允许输入负号、小数点、数字、退格键、删除键、方向左键、方向右键、Home键、End键、Tab键const allowedKeys = ["-","0","1","2","3","4","5","6","7","8","9",".","Backspace","Delete","ArrowLeft","ArrowRight","Home","End","Tab"];// 阻止非法字符输入if (!allowedKeys.includes(e.key)) {e.preventDefault();return;}const inputEl = e.target as HTMLInputElement;const cursorPos = inputEl.selectionStart || 0;const value = inputValue.value;// 阻止输入多个小数点if (e.key === "." && value.includes(".")) {e.preventDefault();return;}// 阻止输入多个负号 或 负号不在开头if (e.key === "-" && (value.includes("-") || cursorPos !== 0)) {e.preventDefault();return;}// 辅助按键,则不阻止,任何时候都允许输入const assistantKeys = ["Backspace", "Delete", "ArrowLeft", "ArrowRight", "Home", "End", "Tab"];if (assistantKeys.includes(e.key)) {return;}// 如果已有小数点,并且光标在小数点后,限制最多两位if (value.includes(".")) {const decimalIndex = value.indexOf(".");const parts = value.split(".");// 仅当光标在小数点之后时才限制输入if (parts[1] && parts[1].length >= 2 && cursorPos > decimalIndex) {e.preventDefault();}}
}// 处理输入内容(防漏兜底,防止不是通过键盘输入,而是通过粘贴输入的)
function handleInput(value: string) {// 过滤输入的内容let filtered = value// 替换全角输入的小数点.replace(/。/g, ".")// 只保留负号、数字和小数点.replace(/[^-\d.]/g, "")// 小数点开头的前面补0.replace(/^\./, "0.")// 只保留第一个小数点.replace(/(\..*)\./g, "$1")// 负号只能在开头.replace(/(\--*)\-/g, "$1")// 去除前导零(非小数的情况下,去除开头的0).replace(/^0+(\d)/, "$1")// 限制小数点后最多两位.replace(/^(\d+\.\d{2})\d+/, "$1");// 负号只能在开头,等效于 replace(/(\--*)\-/g, "$1")// if (filtered.startsWith("-")) {//   const rest = filtered.slice(1).replace(/[^\d.]/g, "");//   filtered = "-" + rest;// } else {//   filtered = filtered.replace(/[^\d.]/g, "");// }/*// 处理小数点const parts = filtered.split(".");// 只保留第一个小数点,等效于 replace(/(\..*)\./g, "$1")if (parts.length > 2) {filtered = parts[0] + "." + parts.slice(1).join("");}// 限制小数点后最多两位if (parts[1]) {// 限制小数部分最多两位,等效于 replace(/^(\d+\.\d{2})\d+/, "$1")parts[1] = parts[1].slice(0, 2);filtered = parts[0] + "." + parts[1];}*/// 如果过滤后为空 或 无效内容,则清空 totalif (!filtered || filtered === "-" || filtered === "." || filtered === "-.") {total.value = null;} else {total.value = parseFloat(filtered);}inputValue.value = filtered;
}// 获得焦点时显示原始值
function handleFocus() {inputValue.value = total.value?.toString() || "";
}// 失去焦点后格式化显示为人民币格式
function handleBlur() {const rawValue = inputValue.value;if (!rawValue) {inputValue.value = "";total.value = null;return;}const num = parseFloat(rawValue);if (isNaN(num)) {inputValue.value = "";total.value = null;return;}total.value = num;const [integerPart, decimalPart = "00"] = Math.abs(num).toFixed(2).split(".");// 千分位格式化const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");const sign = num < 0 ? "-" : "";// 格式化为人民币格式inputValue.value = `¥ ${sign}${formattedInteger}.${decimalPart}`;
}
</script><template><!-- 控制输入:@keydown="handleKeyDown" 和 @input="handleInput" --><!-- 控制显示:@focus="handleFocus"和 @blur="handleBlur" --><!-- 控制失焦:@keyup.enter.native="$event.target.blur()" 按回车输入框失去焦点 --><el-inputv-model="inputValue"@focus="handleFocus"@blur="handleBlur"@keydown="handleKeyDown"@input="handleInput"@keyup.enter.native="$event.target.blur()"placeholder="请输入金额,按回车确认" />
</template>

效果:

 输入前

输入中

回车确认后

将这部分逻辑封装成一个可复用的 Vue Composition API Hook

✅ 封装目标

我们将以下功能抽离为一个 useInputRMB() Hook:

功能描述
输入限制键盘拦截非法字符(数字、负号、小数点)
全角支持支持  和  自动转换
粘贴支持Ctrl+V / 鼠标右键粘贴内容自动过滤
回车失焦按下 Enter 键后输入框失去焦点
数据模型返回 inputValue 用于绑定到 <el-input>
数值存储返回 total 表示原始 `number
失焦格式化显示为 ¥ -1,234.56 格式

✅ 完整 Hook 实现:useInputRMB.ts

你可以将下面这段代码保存为 src/hooks/useInputRMB.ts 文件:

import { ref } from "vue";export function useInputRMB() {// 存储原始数值(用于业务逻辑)const total = ref<number | null>(null);// 输入框内部状态(带格式)const inputValue = ref<string>("");// 处理键盘输入function handleKeyDown(e: KeyboardEvent) {// 只允许输入负号、小数点、数字、退格键、删除键、方向左键、方向右键、Home键、End键、Tab键const allowedKeys = ["-","0","1","2","3","4","5","6","7","8","9",".","Backspace","Delete","ArrowLeft","ArrowRight","Home","End","Tab"];// 阻止非法字符输入if (!allowedKeys.includes(e.key)) {e.preventDefault();return;}const inputEl = e.target as HTMLInputElement;const cursorPos = inputEl.selectionStart || 0;const value = inputValue.value;// 阻止输入多个小数点if (e.key === "." && value.includes(".")) {e.preventDefault();return;}// 阻止输入多个负号 或 负号不在开头if (e.key === "-" && (value.includes("-") || cursorPos !== 0)) {e.preventDefault();return;}// 辅助按键,则不阻止,任何时候都允许输入const assistantKeys = ["Backspace", "Delete", "ArrowLeft", "ArrowRight", "Home", "End", "Tab"];if (assistantKeys.includes(e.key)) {return;}// 如果已有小数点,并且光标在小数点后,限制最多两位if (value.includes(".")) {const decimalIndex = value.indexOf(".");const parts = value.split(".");// 仅当光标在小数点之后时才限制输入if (parts[1] && parts[1].length >= 2 && cursorPos > decimalIndex) {e.preventDefault();}}}// 处理输入内容(防漏兜底,防止不是通过键盘输入,而是通过粘贴输入的)function handleInput(value: string) {// 过滤输入的内容let filtered = value// 替换全角输入的小数点.replace(/。/g, ".")// 只保留负号、数字和小数点.replace(/[^-\d.]/g, "")// 小数点开头的前面补0.replace(/^\./, "0.")// 只保留第一个小数点.replace(/(\..*)\./g, "$1")// 负号只能在开头.replace(/(\--*)\-/g, "$1")// 去除前导零(非小数的情况下,去除开头的0).replace(/^0+(\d)/, "$1")// 限制小数点后最多两位.replace(/^(\d+\.\d{2})\d+/, "$1");// 负号只能在开头,等效于 replace(/(\--*)\-/g, "$1")// if (filtered.startsWith("-")) {//   const rest = filtered.slice(1).replace(/[^\d.]/g, "");//   filtered = "-" + rest;// } else {//   filtered = filtered.replace(/[^\d.]/g, "");// }/*// 处理小数点const parts = filtered.split(".");// 只保留第一个小数点,等效于 replace(/(\..*)\./g, "$1")if (parts.length > 2) {filtered = parts[0] + "." + parts.slice(1).join("");}// 限制小数点后最多两位if (parts[1]) {// 限制小数部分最多两位,等效于 replace(/^(\d+\.\d{2})\d+/, "$1")parts[1] = parts[1].slice(0, 2);filtered = parts[0] + "." + parts[1];}*/// 如果过滤后为空 或 无效内容,则清空 totalif (!filtered || filtered === "-" || filtered === "." || filtered === "-.") {total.value = null;} else {total.value = parseFloat(filtered);}inputValue.value = filtered;}// 获得焦点时显示原始值function handleFocus() {inputValue.value = total.value?.toString() || "";}// 失去焦点后格式化显示为人民币格式function handleBlur() {const rawValue = inputValue.value;if (!rawValue) {inputValue.value = "";total.value = null;return;}const num = parseFloat(rawValue);if (isNaN(num)) {inputValue.value = "";total.value = null;return;}total.value = num;const [integerPart, decimalPart = "00"] = Math.abs(num).toFixed(2).split(".");// 千分位格式化const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");const sign = num < 0 ? "-" : "";// 格式化为人民币格式inputValue.value = `¥ ${sign}${formattedInteger}.${decimalPart}`;}return {inputValue,total,handleKeyDown,handleInput,handleBlur,handleFocus};
}

✅ 在组件中使用这个 Hook,使用方式一,解构使用

组件 MaterialOut.vue 文件如下:

<script setup lang="ts" name="MaterialOut">
import { useInputRMB } from "@/hooks/useInputRMB";const { inputValue, total, handleKeyDown, handleInput, handleBlur, handleFocus } = useInputRMB();
</script><template><!-- 控制输入:@keydown="handleKeyDown" 和 @input="handleInput" --><!-- 控制显示:@focus="handleFocus"和 @blur="handleBlur" --><!-- 控制失焦:@keyup.enter.native="$event.target.blur()" 按回车输入框失去焦点 --><el-inputv-model="inputValue"@focus="handleFocus"@blur="handleBlur"@keydown="handleKeyDown"@input="handleInput"@keyup.enter.native="$event.target.blur()"placeholder="请输入金额,按回车确认" />
</template>

 ✅ 效果:

输入前

输入中

回车确认后

✅ 在组件中使用这个 Hook,使用方式二,直接定义使用

组件 MaterialOut.vue 文件如下:

<script setup lang="ts" name="MaterialOut">
import { useInputRMB } from "@/hooks/useInputRMB";const inputRMBHooks = useInputRMB();
</script><template><!-- 控制输入:@keydown="handleKeyDown" 和 @input="handleInput" --><!-- 控制显示:@focus="handleFocus"和 @blur="handleBlur" --><!-- 控制失焦:@keyup.enter.native="$event.target.blur()" 按回车输入框失去焦点 --><!-- 这里注意,inputValue 需要 .value --><el-inputv-model="inputRMBHooks.inputValue.value"@focus="inputRMBHooks.handleFocus"@blur="inputRMBHooks.handleBlur"@keydown="inputRMBHooks.handleKeyDown"@input="inputRMBHooks.handleInput"@keyup.enter.native="$event.target.blur()"placeholder="请输入金额,按回车确认" />
</template>

直接原因

useInputRMB() 返回的 inputValue 本身是一个 ref 对象,而 inputRMBHooks 是一个普通对象(非响应式对象)。这种情况下,Vue 的模板无法自动解包嵌套在普通对象中的 ref,所以需要手动通过 .value 访问。

typescript

复制

下载

// 假设 useInputRMB 的实现类似这样:
const useInputRMB = () => {const inputValue = ref(""); // inputValue 是一个 refreturn {inputValue, // 将 ref 直接暴露出去};
};

为什么需要 .value

  1. 当 ref 被包裹在普通对象中时

    • 如果 inputRMBHooks 是一个普通对象(如 const inputRMBHooks = { inputValue: ref('') }),模板不会自动解包内部的 ref

    • 此时必须通过 inputRMBHooks.inputValue.value 访问值。

  2. 如果 inputRMBHooks 是响应式对象(如 reactive

    • Vue 会自动解包第一层的 ref,此时无需 .value

    • 但你的代码中 inputRMBHooks 可能是普通对象,或 inputValue 被嵌套在更深层。


验证方法

检查 useInputRMB 的实现:

  • 如果它返回的是 reactive 包裹的对象,且 inputValue 是 ref,模板中应该不需要 .value

  • 如果返回的是普通对象,则需要 .value


解决方案(可选)

如果希望省略 .value,可以将 inputRMBHooks 转为响应式对象:

typescript

复制

下载

const inputRMBHooks = reactive(useInputRMB());

然后在模板中直接使用 v-model="inputRMBHooks.inputValue"(无需 .value)。


总结

你的代码中需要 .value,是因为 inputRMBHooks 是一个普通对象,且 inputValue 是 ref,而 Vue 不会自动解包普通对象内部的 ref。通过 .value 显式访问是必要的。

✅ 在组件中使用这个 Hook,使用方式三,reactive定义使用

组件 MaterialOut.vue 文件如下:

​
<script setup lang="ts" name="MaterialOut">
import { reactive } from "vue";
import { useInputRMB } from "@/hooks/useInputRMB";const inputRMBHooks = reactive(useInputRMB());
</script><template><!-- 控制输入:@keydown="handleKeyDown" 和 @input="handleInput" --><!-- 控制显示:@focus="handleFocus"和 @blur="handleBlur" --><!-- 控制失焦:@keyup.enter.native="$event.target.blur()" 按回车输入框失去焦点 --><el-inputv-model="inputRMBHooks.inputValue"@focus="inputRMBHooks.handleFocus"@blur="inputRMBHooks.handleBlur"@keydown="inputRMBHooks.handleKeyDown"@input="inputRMBHooks.handleInput"@keyup.enter.native="$event.target.blur()"placeholder="请输入金额,按回车确认" />
</template>​

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

方正字库助力华为,赋能鸿蒙电脑打造全场景字体解决方案

2025年5月19日&#xff0c;搭载华为鸿蒙操作系统的鸿蒙电脑&#xff0c;面向用户推出集AI智能、互联流畅、安全保障和精致体验于一体的全新办公系统。作为鸿蒙生态核心字体服务商&#xff0c;方正字库为此次提供了全面的系统字体支持&#xff0c;涵盖中文、西文及符号三大类字库…

PHPStudy 一键式网站搭建工具的下载使用

目录 一、下载 PHPStudy二、安装步骤三、基本使用方法3.1 创建网站3.2 管理数据库3.3 软件管理3.4 自动启动3.5 配置管理 四、注意事项和进阶使用4.1 注意事项4.2 进阶使用 背景&#xff1a; 我们在学习和工作中&#xff0c;经常会遇到各种需要自己搭建环境的场景&#xff0c;这…

java中的线程安全的集合

1.ConcurrentHashMap。 key,value结构。 jdk1.7通过分段锁保证不同段同时操作是线程安全的&#xff0c;但并发不足&#xff0c;jdk1.8通过node节点锁和CAS保证并发安全。不同node节点可以并发读写。通过它的computer,computerIfAbsent,等可以保证原子更新value。ifAbsent表示有…

MySQL问题:MySQL中使用索引一定有效吗?如何排查索引效果

不一定有效&#xff0c;当查询条件中不包含索引列或查询条件复杂且不匹配索引顺序 对于一些小表&#xff0c;MySQL可能选择全表扫描而非使用索引&#xff0c;因为全表扫描的开销可能更小 最终是否用上索引是根据MySQL成本计算决定的&#xff0c;评估CPU和I/O成本 排查索引效…

使用vscode MSVC CMake进行C++开发和Debug

使用vscode MSVC CMake进行C开发和Debug 前言软件安装安装插件构建debuug方案一debug方案二其他 前言 一般情况下我都是使用visual studio来进行c开发的&#xff0c;但是由于python用的是vscode&#xff0c;所以二者如果统一的话能稍微提高一点效率。 软件安装 需要安装的软…

【后端高阶面经:消息队列篇】29、Kafka高性能探秘:零拷贝、顺序写与分区并发实战

一、 顺序写入:磁盘性能的极致挖掘 Kafka的高性能本质上源于对磁盘顺序访问的深度优化。 传统随机写入的磁盘操作需要磁头频繁寻道,机械硬盘的随机写性能通常仅为100IOPS左右,而Kafka通过追加日志(Append-Only Log)模式,将所有消息按顺序写入分区文件,使磁盘操作转化为…

AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月27日第90弹

从今天开始&#xff0c;咱们还是暂时基于旧的模型进行预测&#xff0c;好了&#xff0c;废话不多说&#xff0c;按照老办法&#xff0c;重点8-9码定位&#xff0c;配合三胆下1或下2&#xff0c;杀1-2个和尾&#xff0c;再杀6-8个和值&#xff0c;可以做到100-300注左右。 (1)定…

Git 初次推送远程仓库

Git 初次推送远程仓库&#xff08;完整实战版&#xff09; —— 涵盖重命名分支、强制合并、冲突解决等高频场景 &#x1f525; 核心流程图 初始化 → 关联远程 → 提交代码 → 处理分支冲突 → 成功推送 1. 基础操作&#xff08;全新仓库&#xff09; # 初始化 cd /your/pr…

Pluto实验报告——基于FM的音频信号传输并解调恢复

目录 一、实验目的 ................................ ................................ ................................ .................. 3 二、实验内容 ................................ ................................ ................................ ......…

输出数据OutputFormat案例

输出数据OutputFormat 案例&#xff1a; www.atguigu.com www.atguigu.com www.atguigu.com www.hao123.com www.shouhu.com www.baidu.com www.atguigu.com www.qq.com www.gaga.com www.qinghua.com www.sogou.com www.baidu.com www.alibaba.com …

STM32与ESP32的区别

STM32与ESP32都是当前电子行业中广泛使用的微控制器芯片&#xff0c;但二者在架构、功能、应用领域以及开发生态上均存在显著差异。需要高度实时响应和低功耗的系统通常适合STM32&#xff0c;而需要网络连接和便捷无线通讯的物联网应用通常更适合ESP32。 一、架构与性能 STM32…

YOLOv11改进 | Neck篇 | 双向特征金字塔网络BiFPN助力YOLOv11有效涨点

YOLOv11改进 | Neck篇 | 双向特征金字塔网络BiFPN助力YOLOv11有效涨点 引言 目标检测领域的最新进展表明,特征金字塔网络(FPN)的设计对模型性能具有决定性影响。本文详细介绍如何将**双向特征金字塔网络(BiFPN)**集成到YOLOv11的Neck部分,通过改进的多尺度特征融合机制…

Python后端框架新星Robyn:性能与开发体验的双重革命

引言:Python后端框架的进化之路 在Web开发领域,Python生态长期被Flask、Django等经典框架主导。随着异步编程需求的增长和高并发场景的普及,开发者对框架性能提出了更高要求。2023年,一款名为Robyn的新型Web框架横空出世,以其独特的Rust底层架构和优雅的Python API设计,…

ADS学习笔记(三) 瞬态仿真

参考书籍:见资源绑定,书籍3.4 瞬态仿真,书籍链接: https://pan.baidu.com/s/1pjw8p7r3-1x8qcC1-hljFQ?pwd4v79 提取码: 4v79 本文为对实验内容的补充 瞬态仿真放大倍数与交流仿真不一致 为什么对同一个BJT电路进行交流信号仿真和进行瞬态仿真,得出交流信号仿真的放大倍数是3.…

Flask 会话管理:从原理到实战,深度解析 session 机制

1、Flask中session 的实现原理&#xff1a;服务器与客户端的协作 HTTP 协议是无状态的——服务器无法区分两次请求是否来自同一用户。这意味着&#xff0c;用户登录后跳转到其他页面时&#xff0c;服务器会“忘记”用户身份。 为解决这一问题&#xff0c;Web 开发中引入了会话…

学习STC51单片机16(芯片为STC89C52RCRC)

每日一言 那些让你喘不过气的日子&#xff0c;正是蜕变的开始。 串口编程寄存器分析&#xff08;红色框里面的这个是串口助手里面生成的波特率初始化函数哈&#xff09; 我们就根据以上的寄存器分析&#xff0c;因为这个是配置波特率的需要的寄存器 PCON smod 0 就是PCON的bit…

crud方法命名示例

以下是基于表名dste_project_indicator&#xff08;项目指标表&#xff09;的完整命名示例&#xff0c;覆盖各类增删改查场景&#xff1a; 1. 表名与实体类映射 // 表名&#xff1a;dste_project_indicator // 实体类&#xff1a;DsteProjectIndicatorEntity public class Ds…

AI时代新词-人工智能生成内容(AIGC)

一、什么是人工智能生成内容&#xff08;AIGC&#xff09;&#xff1f; 人工智能生成内容&#xff08;Artificial Intelligence Generated Content&#xff0c;简称AIGC&#xff09;是指利用人工智能技术生成的各种形式的内容&#xff0c;包括文字、图像、音频和视频等。AIGC的…

英语六级-阅读篇

目录 2023年12月大学英语真题&#xff08;二&#xff09; 十五选十&#xff08;Section A&#xff09; 单词表 短语表 译文 Passage Two&#xff08;Section C&#xff09; 单词表 短语表 译文 简介&#xff1a;其实我总结这篇文章就是平时记忆该阅读文章单词中出现的…

Python 爬虫开发

文章目录 1. 常用库安装2. 基础爬虫开发2.1. 使用 requests 获取网页内容2.2. 使用 BeautifulSoup 解析 HTML2.3. 处理登录与会话 3. 进阶爬虫开发3.1. 处理动态加载内容&#xff08;Selenium&#xff09;3.2. 使用Scrapy框架3.3. 分布式爬虫&#xff08;Scrapy-Redis&#xff…