当前位置: 首页 > news >正文

鸿蒙OSUniApp 制作自定义弹窗与模态框组件#三方框架 #Uniapp

UniApp 制作自定义弹窗与模态框组件

前言

在移动应用开发中,弹窗和模态框是用户交互的重要组成部分,它们用于显示提示信息、收集用户输入或确认用户操作。尽管 UniApp 提供了基础的交互组件如 uni.showModal()uni.showToast(),但这些原生组件的样式和交互方式往往难以满足设计师的要求和复杂的业务需求。

本文将详细介绍如何在 UniApp 中实现自定义弹窗和模态框组件,从基础弹窗到复杂的可交互模态框,全面提升你的应用交互体验。通过本文,你将学会如何打造灵活、美观且功能强大的弹窗组件。

弹窗组件设计思路

在开始编码前,我们需要明确自定义弹窗组件的设计目标和核心功能:

  1. 灵活性:支持不同的弹窗类型(提示、确认、输入等)
  2. 可配置性:可自定义样式、动画效果和内容
  3. 易用性:简单的调用方式,丰富的事件回调
  4. 性能优化:合理的组件复用机制,避免重复创建

基于以上设计思路,我们将实现两个核心组件:

  1. 基础弹窗组件(BasePopup):处理弹窗的显示、隐藏、动画等基础功能
  2. 高级模态框组件(Modal):在基础弹窗基础上,实现更复杂的交互和布局

基础弹窗组件实现

首先,我们来实现一个基础的弹窗组件(BasePopup),它将作为所有弹窗类型的基础:

<!-- components/base-popup/base-popup.vue -->
<template><view class="popup-mask" :class="{ 'popup-show': showPopup }" :style="{ backgroundColor: maskColor }"@tap="handleMaskClick"@touchmove.stop.prevent="preventTouchMove"><view class="popup-container" :class="[`popup-${position}`, showContent ? 'popup-content-show' : '',customClass]":style="customStyle"@tap.stop="() => {}"><slot></slot></view></view>
</template><script>
export default {name: 'BasePopup',props: {// 是否显示弹窗show: {type: Boolean,default: false},// 弹窗位置:center, top, bottom, left, rightposition: {type: String,default: 'center'},// 是否允许点击遮罩关闭maskClosable: {type: Boolean,default: true},// 遮罩背景色maskColor: {type: String,default: 'rgba(0, 0, 0, 0.5)'},// 弹窗内容动画时长(ms)duration: {type: Number,default: 300},// 自定义弹窗样式customStyle: {type: Object,default: () => ({})},// 自定义弹窗类customClass: {type: String,default: ''},// 是否阻止页面滚动preventScroll: {type: Boolean,default: true}},data() {return {showPopup: false,showContent: false}},watch: {show: {handler(val) {if (val) {this.open();} else {this.close();}},immediate: true}},methods: {// 打开弹窗open() {this.showPopup = true;// 渐入动画setTimeout(() => {this.showContent = true;}, 50);},// 关闭弹窗close() {this.showContent = false;// 等待内容关闭动画结束后再关闭整个弹窗setTimeout(() => {this.showPopup = false;this.$emit('close');}, this.duration);},// 处理遮罩点击handleMaskClick() {if (this.maskClosable) {this.$emit('update:show', false);}},// 阻止页面滚动preventTouchMove() {if (this.preventScroll) {return;}}}
}
</script><style scoped>
.popup-mask {position: fixed;top: 0;left: 0;right: 0;bottom: 0;z-index: 999;opacity: 0;visibility: hidden;transition: all 0.3s ease-in-out;display: flex;justify-content: center;align-items: center;
}.popup-show {opacity: 1;visibility: visible;
}.popup-container {position: relative;opacity: 0;transform: scale(0.9);transition: all 0.3s ease-in-out;max-width: 90%;max-height: 90%;overflow: auto;background-color: #fff;border-radius: 12rpx;box-shadow: 0 0 20rpx rgba(0, 0, 0, 0.1);
}.popup-content-show {opacity: 1;transform: scale(1);
}/* 不同位置的弹窗样式 */
.popup-center {/* 默认已居中 */
}.popup-top {position: absolute;top: 0;left: 0;width: 100%;transform: translateY(-100%);border-radius: 0 0 12rpx 12rpx;
}.popup-bottom {position: absolute;bottom: 0;left: 0;width: 100%;transform: translateY(100%);border-radius: 12rpx 12rpx 0 0;
}.popup-top.popup-content-show,
.popup-bottom.popup-content-show {transform: translateY(0);
}.popup-left {position: absolute;top: 0;left: 0;height: 100%;transform: translateX(-100%);border-radius: 0 12rpx 12rpx 0;
}.popup-right {position: absolute;top: 0;right: 0;height: 100%;transform: translateX(100%);border-radius: 12rpx 0 0 12rpx;
}.popup-left.popup-content-show,
.popup-right.popup-content-show {transform: translateX(0);
}
</style>

这个基础弹窗组件具有以下特点:

  1. 支持多种弹出位置(中间、顶部、底部、左侧、右侧)
  2. 支持自定义背景色、样式和过渡动画
  3. 可配置点击遮罩是否关闭
  4. 阻止页面滚动,提升用户体验

高级模态框组件实现

在基础弹窗组件之上,我们可以实现一个功能更完善的模态框组件:

<!-- components/modal/modal.vue -->
<template><base-popup:show="show":position="position":mask-closable="maskClosable":mask-color="maskColor":duration="duration":custom-style="customStyle":custom-class="customClass"@update:show="$emit('update:show', $event)"@close="$emit('close')"><view class="modal-content"><!-- 标题区域 --><view v-if="showHeader" class="modal-header"><text class="modal-title">{{ title }}</text><view v-if="showClose" class="modal-close" @tap.stop="$emit('update:show', false)">✕</view></view><!-- 内容区域 --><view class="modal-body" :style="bodyStyle"><!-- 使用默认插槽或展示传入的内容 --><slot><text class="modal-message">{{ message }}</text></slot></view><!-- 按钮区域 --><view v-if="showFooter" class="modal-footer"><slot name="footer"><view v-if="showCancel" class="modal-btn modal-cancel-btn" :style="cancelBtnStyle"@tap.stop="handleCancel">{{ cancelText }}</view><view v-if="showConfirm" class="modal-btn modal-confirm-btn" :style="confirmBtnStyle"@tap.stop="handleConfirm">{{ confirmText }}</view></slot></view></view></base-popup>
</template><script>
import BasePopup from '../base-popup/base-popup.vue';export default {name: 'Modal',components: {BasePopup},props: {// 是否显示模态框show: {type: Boolean,default: false},// 标题title: {type: String,default: '提示'},// 内容文本message: {type: String,default: ''},// 是否显示头部showHeader: {type: Boolean,default: true},// 是否显示关闭按钮showClose: {type: Boolean,default: true},// 是否显示底部showFooter: {type: Boolean,default: true},// 是否显示取消按钮showCancel: {type: Boolean,default: true},// 是否显示确认按钮showConfirm: {type: Boolean,default: true},// 取消按钮文本cancelText: {type: String,default: '取消'},// 确认按钮文本confirmText: {type: String,default: '确认'},// 弹窗位置position: {type: String,default: 'center'},// 是否允许点击遮罩关闭maskClosable: {type: Boolean,default: true},// 遮罩背景色maskColor: {type: String,default: 'rgba(0, 0, 0, 0.5)'},// 动画时长duration: {type: Number,default: 300},// 自定义样式customStyle: {type: Object,default: () => ({})},// 自定义内容区域样式bodyStyle: {type: Object,default: () => ({})},// 自定义取消按钮样式cancelBtnStyle: {type: Object,default: () => ({})},// 自定义确认按钮样式confirmBtnStyle: {type: Object,default: () => ({})},// 自定义类名customClass: {type: String,default: ''}},methods: {// 处理取消事件handleCancel() {this.$emit('update:show', false);this.$emit('cancel');},// 处理确认事件handleConfirm() {this.$emit('update:show', false);this.$emit('confirm');}}
}
</script><style scoped>
.modal-content {min-width: 560rpx;box-sizing: border-box;
}.modal-header {position: relative;padding: 30rpx 30rpx 20rpx;border-bottom: 1rpx solid #f0f0f0;display: flex;justify-content: center;align-items: center;
}.modal-title {font-size: 32rpx;font-weight: bold;color: #333;text-align: center;flex: 1;
}.modal-close {position: absolute;right: 30rpx;top: 30rpx;width: 40rpx;height: 40rpx;font-size: 32rpx;color: #999;display: flex;justify-content: center;align-items: center;
}.modal-body {padding: 40rpx 30rpx;max-height: 60vh;overflow-y: auto;
}.modal-message {font-size: 28rpx;color: #333;line-height: 1.5;text-align: center;word-break: break-all;
}.modal-footer {display: flex;padding: 20rpx 30rpx 30rpx;border-top: 1rpx solid #f0f0f0;
}.modal-btn {flex: 1;height: 80rpx;line-height: 80rpx;text-align: center;font-size: 30rpx;border-radius: 80rpx;margin: 0 20rpx;
}.modal-cancel-btn {background-color: #f5f5f5;color: #666;
}.modal-confirm-btn {background-color: #07c160;color: #fff;
}
</style>

这个模态框组件在基础弹窗之上增加了以下功能:

  1. 标题栏和关闭按钮
  2. 自定义内容区域(支持插槽或文本)
  3. 底部按钮区域(支持自定义样式和文本)
  4. 完善的事件处理(确认、取消、关闭)

使用示例

1. 基础弹窗示例

<template><view class="container"><button @tap="showBasicPopup = true">显示基础弹窗</button><base-popup :show.sync="showBasicPopup" position="bottom"><view style="padding: 30rpx;"><text>这是一个基础弹窗</text></view></base-popup></view>
</template><script>
import BasePopup from '@/components/base-popup/base-popup.vue';export default {components: {BasePopup},data() {return {showBasicPopup: false}}
}
</script>

2. 模态框组件示例

<template><view class="container"><button @tap="showConfirmModal">显示确认模态框</button><button @tap="showCustomModal">显示自定义模态框</button><!-- 确认模态框 --><modal:show.sync="confirmModal"title="操作确认"message="确定要删除这个项目吗?此操作不可恢复。"@confirm="handleConfirm"@cancel="handleCancel"></modal><!-- 自定义模态框 --><modal:show.sync="customModal"title="自定义内容":show-footer="false"><view class="custom-content"><image src="/static/images/success.png" class="success-icon"></image><text class="success-text">操作成功</text><text class="success-tip">将在3秒后自动关闭</text></view></modal></view>
</template><script>
import Modal from '@/components/modal/modal.vue';export default {components: {Modal},data() {return {confirmModal: false,customModal: false}},methods: {showConfirmModal() {this.confirmModal = true;},showCustomModal() {this.customModal = true;// 3秒后自动关闭setTimeout(() => {this.customModal = false;}, 3000);},handleConfirm() {console.log('用户点击了确认');// 执行确认操作uni.showToast({title: '已确认操作',icon: 'success'});},handleCancel() {console.log('用户点击了取消');}}
}
</script><style>
.container {padding: 40rpx;
}button {margin-bottom: 30rpx;
}.custom-content {display: flex;flex-direction: column;align-items: center;padding: 30rpx;
}.success-icon {width: 120rpx;height: 120rpx;margin-bottom: 20rpx;
}.success-text {font-size: 32rpx;color: #07c160;font-weight: bold;margin-bottom: 10rpx;
}.success-tip {font-size: 24rpx;color: #999;
}
</style>

高级应用:表单输入模态框

在实际应用中,我们经常需要通过模态框收集用户输入。下面是一个表单输入模态框的示例:

<template><modal:show.sync="show"title="用户信息":mask-closable="false":confirm-text="'保存'"@confirm="handleSave"><view class="form-container"><view class="form-item"><text class="form-label">姓名</text><input class="form-input" v-model="form.name" placeholder="请输入姓名" /></view><view class="form-item"><text class="form-label">手机号</text><input class="form-input" v-model="form.phone" type="number" placeholder="请输入手机号" /></view><view class="form-item"><text class="form-label">地址</text><textarea class="form-textarea" v-model="form.address" placeholder="请输入地址"></textarea></view></view></modal>
</template><script>
import Modal from '@/components/modal/modal.vue';export default {name: 'FormModal',components: {Modal},props: {show: {type: Boolean,default: false},// 初始表单数据initData: {type: Object,default: () => ({})}},data() {return {form: {name: '',phone: '',address: ''}}},watch: {show(val) {if (val) {// 打开模态框时,初始化表单数据this.form = {name: this.initData.name || '',phone: this.initData.phone || '',address: this.initData.address || ''};}}},methods: {// 保存表单数据handleSave() {// 表单验证if (!this.form.name) {uni.showToast({title: '请输入姓名',icon: 'none'});return;}if (!this.form.phone) {uni.showToast({title: '请输入手机号',icon: 'none'});return;}// 验证通过,发出保存事件this.$emit('save', {...this.form});}}
}
</script><style scoped>
.form-container {padding: 10rpx 0;
}.form-item {margin-bottom: 30rpx;
}.form-label {display: block;font-size: 28rpx;color: #333;margin-bottom: 10rpx;
}.form-input {width: 100%;height: 80rpx;border: 1rpx solid #eee;border-radius: 8rpx;padding: 0 20rpx;box-sizing: border-box;font-size: 28rpx;
}.form-textarea {width: 100%;height: 160rpx;border: 1rpx solid #eee;border-radius: 8rpx;padding: 20rpx;box-sizing: border-box;font-size: 28rpx;
}
</style>

在页面中使用表单模态框:

<template><view class="container"><button @tap="showFormModal">编辑用户信息</button><form-modal :show.sync="formModalVisible" :init-data="userData"@save="handleSaveUserData"></form-modal></view>
</template><script>
import FormModal from '@/components/form-modal/form-modal.vue';export default {components: {FormModal},data() {return {formModalVisible: false,userData: {name: '张三',phone: '13800138000',address: '北京市朝阳区'}}},methods: {showFormModal() {this.formModalVisible = true;},handleSaveUserData(data) {console.log('保存的用户数据:', data);this.userData = {...data};uni.showToast({title: '保存成功',icon: 'success'});}}
}
</script>

实现一个全局弹窗管理器

为了更方便地调用弹窗,我们可以实现一个全局弹窗管理器,让弹窗的使用更像系统函数调用:

// utils/popup-manager.js
import Vue from 'vue';
import Modal from '@/components/modal/modal.vue';class PopupManager {constructor() {// 创建一个Vue实例来管理模态框this.modalInstance = null;this.initModalInstance();}// 初始化模态框实例initModalInstance() {const ModalConstructor = Vue.extend(Modal);this.modalInstance = new ModalConstructor({el: document.createElement('div')});document.body.appendChild(this.modalInstance.$el);}// 显示提示框alert(options = {}) {return new Promise(resolve => {const defaultOptions = {title: '提示',message: '',confirmText: '确定',showCancel: false,maskClosable: false};const mergedOptions = {...defaultOptions, ...options};this.modalInstance.title = mergedOptions.title;this.modalInstance.message = mergedOptions.message;this.modalInstance.confirmText = mergedOptions.confirmText;this.modalInstance.showCancel = mergedOptions.showCancel;this.modalInstance.maskClosable = mergedOptions.maskClosable;this.modalInstance.show = true;// 监听确认事件this.modalInstance.$once('confirm', () => {resolve(true);});// 处理取消事件this.modalInstance.$once('cancel', () => {resolve(false);});});}// 显示确认框confirm(options = {}) {const defaultOptions = {title: '确认',showCancel: true,cancelText: '取消',confirmText: '确认'};return this.alert({...defaultOptions, ...options});}// 关闭所有弹窗closeAll() {if (this.modalInstance) {this.modalInstance.show = false;}}
}export default new PopupManager();

在页面中使用弹窗管理器:

import popupManager from '@/utils/popup-manager.js';// 显示一个提示框
popupManager.alert({title: '操作成功',message: '您的操作已完成'
}).then(() => {console.log('用户点击了确定');
});// 显示一个确认框
popupManager.confirm({title: '删除确认',message: '确定要删除这条记录吗?',confirmText: '删除'
}).then(result => {if (result) {console.log('用户确认了删除');// 执行删除操作} else {console.log('用户取消了删除');}
});

注意:上面的全局弹窗管理器代码主要适用于H5环境,在App和小程序环境中可能需要不同的实现方式。

最佳实践与优化建议

  1. 避免过多嵌套:弹窗内部尽量避免再打开多层弹窗,这会导致用户体验下降。

  2. 合理使用动画:动画可以提升用户体验,但过多或过于复杂的动画可能导致性能问题。

  3. 适配不同设备:确保弹窗在不同设备上都有良好的表现,尤其是在小屏幕设备上。

  4. 考虑无障碍访问:为弹窗添加适当的ARIA属性,提高无障碍体验。

  5. 性能优化

    • 避免在弹窗中放置过多复杂内容
    • 使用条件渲染(v-if)而不是隐藏显示(v-show)来完全移除不显示的弹窗DOM
    • 在关闭弹窗时及时清理资源
  6. 错误处理:添加适当的错误处理机制,确保弹窗显示和关闭的稳定性。

总结

本文详细介绍了如何在UniApp中实现自定义弹窗和模态框组件,从基础的弹窗到功能丰富的模态框,再到实用的表单输入模态框,全面覆盖了移动应用中常见的弹窗交互需求。通过这些组件,你可以大大提升应用的交互体验和美观度。

在实际项目中,你可以根据具体业务需求对这些组件进行扩展和优化,例如添加更多的动画效果、支持更复杂的布局、实现特定的交互逻辑等。希望本文对你的UniApp开发有所帮助!

在面对移动应用开发中各种弹窗交互的挑战时,拥有一套灵活、可定制的弹窗组件库将是你的得力助手。愿你能基于本文提供的思路和代码,打造出更加出色的用户体验。

相关文章:

鸿蒙OSUniApp 制作自定义弹窗与模态框组件#三方框架 #Uniapp

UniApp 制作自定义弹窗与模态框组件 前言 在移动应用开发中&#xff0c;弹窗和模态框是用户交互的重要组成部分&#xff0c;它们用于显示提示信息、收集用户输入或确认用户操作。尽管 UniApp 提供了基础的交互组件如 uni.showModal() 和 uni.showToast()&#xff0c;但这些原…...

web第一次课后作业--运行一个java web项目

一、创建java web项目 1.新建java EE --> 模版&#xff1a;Web应用程序 2.选择版本&#xff1a;Java EE 8 3. 配置tomcat 二、页面效果 默认页面 跳转页面 三、代码 3.1 默认页面 <% page contentType"text/html; charsetUTF-8" pageEncoding"UTF-8…...

工业互联网

工业互联网全景解析 工业互联网是工业数字化、网络化、智能化转型升级的重要抓手&#xff0c;是实现中国制造 2025 战略目标的重要路径&#xff0c;对于推动我国实体经济高质量、可持续发展&#xff0c;建设制造强国、网络强国&#xff0c;意义重大。2017 年&#xff0c;我国提…...

论QT6多线程技术

前言 以前我多线程使用传统的继承qthread重写run()或者继承qrunable类把对象丢到线程池解决。经过昨天的面试让我了解到新的技术&#xff0c;我之前看到过只不过没有详细的去了解movetotread技术&#xff0c;这个技术是qt5推出的&#xff0c;qt6还在延续使用 代码结构 以下是…...

TensorFlow深度学习实战(16)——注意力机制详解

TensorFlow深度学习实战&#xff08;16&#xff09;——注意力机制详解 0. 前言1. 引入注意力机制2. 注意力机制2.1 注意力机制原理2.2 注意力机制分类 3. 添加注意机制的 Seq2Seq 模型3.1 数据处理3.2 模型构建与训练3.3 模型性能评估 小结系列链接 0. 前言 在传统的神经网络…...

架空防静电地板材质全解析:选对材质,守护精密空间的“安全卫士”

在现代科技驱动的社会中&#xff0c;无论是数据中心、实验室、手术室&#xff0c;还是高端电子厂房&#xff0c;静电都是精密设备的“隐形杀手”。而架空防静电地板作为这些场所的“安全卫士”&#xff0c;其材质选择直接决定了防静电性能、承重能力及使用寿命。今天&#xff0…...

Linux系统中部署java服务(docker)

1、不使用docker ✅ 1. 检查并安装 Java 环境 检查 Java 是否已安装&#xff1a; java -version✅ 2. 上传 Java 项目 JAR 文件 可以创建一个server文件夹&#xff0c;然后上传目录 查看当前目录 然后创建目录上传jar包 ✅ 3. 启动 Java 服务 java -jar hywl-server.jar…...

PyGame游戏开发(入门知识+组件拆分+历史存档/回放+人机策略)

前言&#xff1a; 本章实现游戏组件的复用解耦&#xff0c;以及使用配置文件替代原有硬编码形式&#xff0c;进而只需要改动配置文件即可实现整个游戏的难度和地图变化&#xff0c;同时增加历史记录功能&#xff0c;在配置文件开启后即可保存每一局的记录为json形式作为后续强化…...

【上位机——WPF】Window标签常用属性

常用属性 常用属性程序退出 常用属性都是写在Window标签中的 <Window x:Class"WpfDemo1.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"…...

K8S Gateway AB测试、蓝绿发布、金丝雀(灰度)发布

假设有如下三个节点的 K8S 集群&#xff1a; ​ k8s31master 是控制节点 k8s31node1、k8s31node2 是工作节点 容器运行时是 containerd 一、场景分析 阅读本文&#xff0c;默认您已经安装了 K8S Gateway。 关于 AB 测试、金丝雀发布&#xff0c;可以看这篇文章。 二、实验准…...

人大金仓数据库 与django结合

要在Django项目中连接人大金仓数据库&#xff08;Kingbase&#xff09;&#xff0c;你需要使用一个适合的数据库适配器。人大金仓数据库是基于PostgreSQL的&#xff0c;因此你可以使用psycopg2库来与Django连接。但是&#xff0c;由于人大金仓数据库有其特定的功能和配置&#…...

RK3588 桌面系统配置WiFi和蓝牙配置

桌面右上角点击&#xff0c;打开选项&#xff0c;找到WiFi的选择网络或者WiFi设置 在弹出的窗口中选择需要连接的WiFi&#xff0c;然后右下角选择连接&#xff0c;然后输入WiFi密码即可连接。 25.4. 命令行连接wifi路由器 命令行配置wifi的方法有很多&#xff0c;下面介绍几种…...

TLV格式

‌TLV格式&#xff08;Tag-Length-Value&#xff09;是一种常用的数据序列化格式&#xff0c;主要用于数据包或消息的有效载荷编码。‌TLV格式将数据划分为三个主要部分&#xff1a;Tag&#xff08;标签&#xff09;、Length&#xff08;长度&#xff09;和Value&#xff08;值…...

2024年9月电子学会等级考试五级第三题——整数分解

题目 3、整数分解 正整数 N 的 K-P 分解是指将 N 写成 K 个正整数的 P 次方的和。本题就请你对任意给定的正整数 N、K、P&#xff0c;写出 N 的 K-P 分解。 时间限制&#xff1a;8000 内存限制&#xff1a;262144 输入 输入在一行给出 3 个正整数 N (≤ 400)、K (≤ N)、P (1 …...

软考 系统架构设计师系列知识点之杂项集萃(60)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;59&#xff09; 第97题 在面向对象设计中&#xff0c;&#xff08;&#xff09;可以实现界面控制、外部接口和环境隔离。&#xff08;&#xff09;作为完成用例业务的责任承担者&#xff0c;协调…...

使用Python开发经典俄罗斯方块游戏

使用Python开发经典俄罗斯方块游戏 在这篇教程中&#xff0c;我们将学习如何使用Python和Pygame库开发一个经典的俄罗斯方块游戏。这个项目将帮助你理解游戏开发的基本概念&#xff0c;包括图形界面、用户输入处理、碰撞检测等重要内容。 项目概述 我们将实现以下功能&…...

C++:字符数组与字符串指针变量的大小

#include<iostream> #include<cstring> int main(int argc, char const *argv[]) {// 字符数组char str[128] "hello world";std::cout<<sizeof(str)<<std::endl;std::cout<<strlen(str)<<std::endl;// 字符串指针变量char *st…...

stm32使用freertos时延时时间间隔不对,可能是晶振频率没设置

freertos 获取频率的接口 在 FreeRTOSConfig.h 文件中声明一个函数作为freertos的接口 /// /// brief 获取 SysTick 的频率 /// /// note arm cortex-m 系列 CPU 有一个 systick &#xff0c;里面有一个 CTRL 寄存器&#xff0c;其中的 bit2 /// 可以用来控制 systick 的时钟…...

51c~C语言~合集5

我自己的原文哦~ https://blog.51cto.com/whaosoft/13913911 一、大厂C语言编程10大规范 1 代码总体原则 1、清晰第一 清晰性是易于维护、易于重构的程序必需具备的特征。代码首先是给人读的&#xff0c;好的代码应当可以像文章一样发声朗诵出来。 目前软件维护期成本…...

前端流行框架Vue3教程:17. _组件数据传递

_组件数据传递 我们之前讲解过了组件之间的数据传递&#xff0c;props 和自定义事件 两种方式 props&#xff1a;父传子 自定义事件&#xff1a;子传父 除了上述的方案&#xff0c;props也可以实现子传父 一、项目结构 src/ └── components/├── ComponentsA.vue # 父…...

Stack overflow

本文来源 &#xff1a;腾讯元宝 Stack Overflow - Where Developers Learn, Share, & Build Careers 开发者学习&#xff0c;分享 通过学习、工作和经验积累等方式&#xff0c;逐步建立和发展自己的职业生涯。 Find answers to your technical questions and help othe…...

SpringBoot 3.4.5版本导入Lomobok依赖后无法生效的问题

问题背景 最近&#xff0c;随着DeepSeek的爆火&#xff0c;小编也编写了一个前后端分离的“知库随考”系统&#xff0c;由于Spring AI官方提示想要使用Spring AI的话要求Spring Boot的版本在“3.4.x”以上&#xff0c;所以我在创建SpringBoot项目的时候选择了了Server URL:http…...

FPGA: UltraScale+ bitslip实现(ISERDESE3)

收获 一晃五年~ 五年前那个夏夜&#xff0c;我对着泛蓝的屏幕敲下《给十年后的自己》&#xff0c;在2020年的疫情迷雾中编织着对未来的想象。此刻回望&#xff0c;第四届集创赛的参赛编号仍清晰如昨&#xff0c;而那个在家熬夜焊电路板的"不眠者"&#xff0c;现在…...

Electron详解:原理与不足

Electron是一个集成项目&#xff0c;它通过定制Chromium和Node.js&#xff0c;并将它们集成在内部来实现其功能。具体来说&#xff0c;Electron做了以下几个重要的工作&#xff1a; 定制Chromium&#xff1a;并将定制版本的Chromium集成在Electron内部。定制Node.js&#xff1…...

Spring Boot多数据源配置的陷阱与终极解决方案

引言 在微服务架构和复杂业务场景中&#xff0c;一个Spring Boot应用连接多个数据库的需求日益普遍。许多开发者尝试通过简单复制单数据源配置来实现多数据源&#xff0c;结果却遭遇了Bean冲突、事务失效、连接泄漏等隐蔽问题。本文将深入剖析Spring Boot自动配置的底层逻辑&a…...

android display 笔记(十四)VAU 和GSP 分别代表什么

VAU 和 GSP 的解释 GSP (Graphics/GPU Subsystem Processor) 含义&#xff1a; 图形处理子系统&#xff0c;通常指 SoC&#xff08;系统级芯片&#xff09;中负责 2D/3D 图形渲染、显示合成、图像后处理&#xff08;如缩放、旋转、色彩管理&#xff09; 的硬件模块。 在部分芯…...

tomcat 400 The valid characters are defined in RFC 7230 and RFC 3986

在遇到 Tomcat 因 URL 非法字符返回 400 Bad Request 时,选择在 Nginx 还是 Tomcat 中配置错误处理,需根据实际场景和需求权衡。以下是两种方案的详细对比及配置方法: 一、选择建议 方案适用场景优点缺点Nginx 配置- 需要统一处理所有后端服务(如多个 Tomcat 实例)的 400 …...

nginx负载均衡及keepalive高可用

实验前期准备&#xff1a; 5台虚拟机&#xff1a;4台当做服务器&#xff0c;1台当做客户机&#xff08;当然&#xff0c;也可以使用主机的浏览器&#xff09;&#xff0c;4台服务器中&#xff0c;2台服务器当做后端真实访问服务器&#xff1b;另外2台服务器当做负载均衡服务器…...

漏洞修复:tomcat 升级版本 spring-boot-starter-tomcat 的依赖项

在Spring Boot项目中修复Tomcat漏洞(如CVE-2024-21733)时,通常需要升级内嵌Tomcat版本。以下是具体操作步骤和注意事项: 一、确认当前Tomcat版本 通过启动日志查看 启动项目时,控制台日志中会显示类似 Starting Servlet engine: [Apache Tomcat/9.0.43] 的信息,直接查看版…...

二、IGMP

目录 1. IGMPv1 1.1 IGMPv1 报⽂类型 1.2 IGMPv1 工作机制 1.3 成员加入 1.4 离组机制 2. IGMPv2 2.1 IGMPv2 报文 2.3 查询器选举 & 维护 2.4 成员加入 2.4 离组机制 3. IGMPv3 3.1 IGMPv3 vs. IGMPv2 3.2 IGMPv3 报文 3.3 IGMPv3 工作机制 4. IGMP Proxy …...

Redis--基础知识点--27--redis缓存分类树

在 Redis 中存储分类树&#xff0c;通常需要选择合适的数据结构来表现层级关系。以下是使用 字符串&#xff08;String&#xff09; 和 哈希&#xff08;Hash&#xff09; 两种常见方案的举例说明&#xff0c;结合电商分类场景&#xff08;如 电子产品 > 手机 > 智能手机…...

【2025最新】VSCode Cline插件配置教程:免费使用Claude 3.7提升编程效率

 2025年最新VSCode Cline插件安装配置教程&#xff0c;详解多种免费使用Claude 3.7的方法&#xff0c;集成DeepSeek-R1与5大实用功能&#xff0c;专业编程效率提升指南。 Cline是VSCode中功能最强大的AI编程助手插件之一&#xff0c;它能与Claude、OpenAI等多种大模型无缝集…...

SQL笔记一

SQL的分类 DDL&#xff08;数据定义语言&#xff09;&#xff1a;CREATE&#xff08;创建&#xff09; ALTER&#xff08;修改&#xff09; DROP&#xff08;删除结构&#xff09; RENAME&#xff08;重命名&#xff09; TRUNCATE&#xff08;清空&#xff09; DML&#xff0…...

高可靠低纹波国产4644电源芯片在工业设备的应用

摘要 随着工业自动化和智能化的飞速发展&#xff0c;工业设备对于电源芯片的性能和可靠性提出了前所未有的严格要求。电源芯片作为工业设备的核心供电组件&#xff0c;其性能直接影响到整个设备的运行效率和稳定性。本文以国科安芯的ASP4644四通道降压稳压器为例&#xff0c;通…...

MyBatis 的分页插件 c

前言 大型项目的数据体量很大&#xff0c;在前端界面展示时为保障展示效果&#xff0c;会要求接口快速返回&#xff0c;这时候后端会选择分页获取数据&#xff0c;只传递要查询的页码数据。这就避免了大多问题&#xff0c;达到快速返回的效果。 常用的分页有2种&#xff1a; …...

网络安全-等级保护(等保) 2-5 GB/T 25070—2019《信息安全技术 网络安全等级保护安全设计技术要求》-2019-05-10发布【现行】

################################################################################ GB/T 22239-2019 《信息安全技术 网络安全等级保护基础要求》包含安全物理环境、安全通信网络、安全区域边界、安全计算环境、安全管理中心、安全管理制度、安全管理机构、安全管理人员、安…...

嵌软面试每日一阅----FreeRTOS

一. FreeRTOS 创建任务的方法及区别 在 FreeRTOS 中&#xff0c;任务创建主要有两种方式&#xff1a;动态内存分配&#xff08;xTaskCreate()&#xff09;和静态内存分配&#xff08;xTaskCreateStatic()&#xff09;。以下是两者的核心区别及使用场景&#xff1a; 1. 动态创建…...

EasyExcel详解

文章目录 一、easyExcel1.什么是easyExcel2.easyExcel示例demo3.easyExcel read的底层逻辑~~4.easyExcel write的底层逻辑~~ 二、FastExcel1.为什么更换为fastExcel2.fastExcel新功能 一、easyExcel 1.什么是easyExcel 内容摘自官方&#xff1a;Java解析、生成Excel比较有名的…...

023-C语言预处理详解

C语言预处理详解 文章目录 C语言预处理详解1. 预定义符号2. #define定义常量3. #define定义宏4. 带有副作用的宏参数5. 宏替换的规则6. 宏函数的对比7. #和##7.1 #运算符7.2 ##运算符 8. 命名约定9. #undef10. 命令行定义11. 条件编译12. 头文件包含12.1 头文件被包含方式12.1.…...

C#自定义控件-实现了一个支持平移、缩放、双击重置的图像显示控件

1. 控件概述 这是一个继承自 Control 的自定义控件&#xff0c;主要用于图像的显示和交互操作&#xff0c;具有以下核心功能&#xff1a; 图像显示与缩放&#xff08;支持鼠标滚轮缩放&#xff09;图像平移&#xff08;支持鼠标拖拽&#xff09;视图重置&#xff08;双击重置…...

MarkitDown:AI时代的文档转换利器

在当今AI快速发展的时代,如何高效地将各种格式的文档转换为机器可读的格式,成为了一个迫切需要解决的问题。今天,我们来介绍一款由微软开发的强大工具——MarkitDown,它正是为解决这一问题而生的。 什么是MarkitDown? MarkitDown是一个用Python编写的轻量级工具,专门用…...

《数字分身进化论:React Native与Flutter如何打造沉浸式虚拟形象编辑》

React Native&#xff0c;依托JavaScript语言&#xff0c;借助其成熟的React生态系统&#xff0c;开发者能够快速上手&#xff0c;将前端开发的经验巧妙运用到移动应用开发中。它通过JavaScript桥接机制调用原生组件&#xff0c;实现与iOS和Android系统的深度交互&#xff0c;这…...

DeerFlow:字节新一代 DeepSearch 框架

项目地址&#xff1a;https://github.com/bytedance/deer-flow/ 【全新的 Multi-Agent 架构设计】独家设计的 Research Team 机制&#xff0c;支持多轮对话、多轮决策和多轮任务执行。与 LangChain 原版 Supervisor 相比&#xff0c;显著减少 Tokens 消耗和 API 调用次数&#…...

数字孪生工厂实战指南:基于Unreal Engine/Omniverse的虚实同步系统开发

引言&#xff1a;工业元宇宙的基石技术 在智能制造2025与工业元宇宙的交汇点&#xff0c;数字孪生技术正重塑传统制造业。本文将手把手指导您构建基于Unreal Engine 5.4与NVIDIA Omniverse的实时数字孪生工厂系统&#xff0c;集成Kafka实现毫秒级虚实同步&#xff0c;最终交付…...

牛客网NC22015:最大值和最小值

牛客网NC22015&#xff1a;最大值和最小值 题目描述 题目要求 输入&#xff1a;一行&#xff0c;包含三个整数 a, b, c &#xff08;1≤a,b,c≤1000000&#xff09; 输出&#xff1a;两行&#xff0c;第一行输出最大数&#xff0c;第二行输出最小数。 样例输入&#xff1a; …...

Uniapp中小程序调用腾讯地图(获取定位地址)

1、先配置权限&#xff1a; 这是上图的代码&#xff1a; "permission": { "scope.userLocation": { "desc": "你的位置信息将用于小程序位置接口的效果展示" } } 第二步&#xff1a;写代码&#xff1a; //下面是uniapp的模版代码 主…...

2025 后端自学UNIAPP【项目实战:旅游项目】5、个人中心页面:微信登录,同意授权,获取用户信息

一、框架以及准备工作 1、前端项目文件结构展示 2、后端项目文件结构展示 3、登录微信公众平台&#xff0c;注册一个个人的程序&#xff0c;获取大appid&#xff08;前端后端都需要&#xff09;和密钥&#xff08;后端需要&#xff09; 微信公众平台微信公众平台&…...

隆重推荐(Android 和 iOS)UI 自动化工具—Maestro

文章目录 前言一、为什么选择 Maestro&#xff1f;二、使用步骤1.安装&#xff08;Windows&#xff09;2.运行示例 三、Maestro Studio &#xff08;重点&#xff09;轻松编辑测试 四、价格总结 前言 当前移动 UI 自动化工具的实际效能与预期存在显著差距&#xff0c;团队推行…...

C#发送文件到蓝牙设备

测试环境&#xff1a; visual studio 2022 win11笔记本电脑&#xff0c;具有蓝牙功能 .net6控制台 测试步骤如下&#xff1a; 1 新增名为BluetoothDemo控制台项目 2 通过nuget安装InTheHand.Net.Bluetooth&#xff0c;版本选择4.2.1和安装InTheHand.Net.Obex&#xff0c;版…...

采用sherpa-onnx 实现 ios语音唤起的调研

背景 项目中需要实现一个语音唤起的功能&#xff0c;选择sherpa-onnx进行调研&#xff0c;要求各端都要验证没有问题。个人负责ios这部分的调研。查询官方发现没有直接针对ios语音唤起的稳定&#xff0c;主要技术平台也没有相关的可以借鉴。经过调研之后补充了一个。 一、下载…...