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

HarmonyOS NEXT - Dialog 和完全自定义弹框

demo 地址: https://github.com/iotjin/JhHarmonyDemo
组件对应代码实现地址
代码不定时更新,请前往github查看最新代码

在demo中这些组件和工具类都通过module实现了,具体可以参考HarmonyOS NEXT - 通过 module 模块化引用公共组件和utils

HarmonyOS NEXT - Dialog 和完全自定义弹框

  • 效果图
  • 调用方式
  • JhDialog.ets 完整代码

官方dialog 比较反人类,调用比较麻烦,下面两种还略微好点

  • 通过promptAction.openCustomDialog 实现自定义弹窗。对应官方文档
  • 不依赖UI组件的全局自定义弹出框 (openCustomDialog)(推荐)对应官方文档

在三方库上找了一个弹框库,简单调整样式封装了一层

三方库地址:
@pura/harmony-dialog(V1.0.7)

需要先在项目中导入三方库

 ohpm i @pura/harmony-dialog@1.0.7

OpenHarmony ohpm 环境配置等更多内容,请参考如何安装 OpenHarmony ohpm 包

效果图

在这里插入图片描述

调用方式

需要先全局初始化一次,否则弹框不显示
全局初始化可以放在入口的page处
1.0.8开始需要在在windowStage.loadContent 后执行初始化

以下是在第一个page的aboutToAppear方法初始化的

  aboutToAppear() {// 初始化Loadinglet uiContext: UIContext = this.getUIContext();JhDialog.initConfig(uiContext)}
  • 标题内容
     JhDialog.show({title: '提示',message: '您确定要退出登录吗',onCancel: () => {console.log(`点击了取消按钮`)},onConfirm: () => {console.log(`点击了确认按钮`)},});
  • 修改按钮文字
  JhDialog.show({title: '提示',message: '您需要同意相关协议才能使用!',leftText: '不同意',rightText: '同意',onCancel: () => {console.log(`点击了取消按钮`)},onConfirm: () => {console.log(`点击了确认按钮`)},});
  • 点击按钮弹框不消失
   JhDialog.show({title: '提示',message: '点击取消按钮弹框消失,点击确认按钮延时3秒后弹框消失',clickBtnClose: false,onCancel: (action, dialogId, content) => {console.log(`点击了取消按钮`)JhDialog.hide(dialogId)},onConfirm: (action, dialogId, content) => {console.log(`点击了确认按钮`)setTimeout(() => {JhDialog.hide(dialogId)}, 3000)},});
  • 录入框(数字类型,正整数,最大三位)
    JhDialog.showInputDialog({title: '提示',placeholder: "请输入年龄",inputType: InputType.Number,maxLength: 3,inputFilter: {value: "[0-9]",error: (value) => {console.error("inputFilter: " + value);}},onCancel: (action, dialogId, content) => {console.log(`点击了取消按钮`)JhProgressHUD.showText(`点击了取消按钮`)},onConfirm: (action, dialogId, content) => {console.log(`点击了确认按钮, 此时录入的文字为: ${content}}`)JhDialog.hide(dialogId)JhProgressHUD.showText(`点击了确认按钮`)},});
  • 多行录入框
  JhDialog.showTextAreaDialog({title: '提示',onCancel: (action, dialogId, content) => {console.log(`点击了取消按钮`)JhProgressHUD.showText(`点击了取消按钮`)},onConfirm: (action, dialogId, content) => {console.log(`点击了确认按钮, 此时录入的文字为: ${content}}`)JhDialog.hide(dialogId)JhProgressHUD.showText(`点击了确认按钮`)},});
  • 自定义内容
  JhDialog.showCustomDialog({title: '',contentAreaPadding: {top: 0,bottom: 0,left: 0,right: 0},contentBuilder: () => {this.customBuilder()},onCancel: () => {console.log(`点击了取消按钮`)},onConfirm: () => {console.log(`点击了确认按钮`)},});@BuildercustomBuilder() {Column() {}.width('100%').height(200).backgroundColor(Color.Red)}
  • 底部完全自定义
  let custom: JhCustomOptions = {height: 360,alignment: DialogAlignment.Bottom,offset: { dx: 0, dy: 0 },transition: AnimationHelper.transitionInDown(0),autoCancel: true, // 点击遮障层时,是否关闭弹窗,true表示关闭弹窗。backCancel: false, // 点击返回键或手势返回时,是否关闭弹窗;实现onWillDismiss函数时,该参数不起作用。};JhDialog.showBottomAllCustomDialog(wrapBuilder(AllCustomBuilder))// JhDialog.showBottomAllCustomDialog(wrapBuilder(AllCustomBuilder), custom)
  • 完全自定义-顶部弹出
   let custom: JhCustomOptions = {height: 360,alignment: DialogAlignment.Top,offset: { dx: 0, dy: 0 },transition: AnimationHelper.transitionInDown(0),autoCancel: true, // 点击遮障层时,是否关闭弹窗,true表示关闭弹窗。backCancel: false, // 点击返回键或手势返回时,是否关闭弹窗;实现onWillDismiss函数时,该参数不起作用。};JhDialog.showAllCustomDialog(wrapBuilder(AllCustomBuilder), custom)
  • 完全自定义-左侧弹出
  let custom: JhCustomOptions = {width: 260,height: '100%',alignment: DialogAlignment.CenterStart,offset: { dx: 0, dy: 0 },transition: AnimationHelper.transitionInLeft(200),autoCancel: true, // 点击遮障层时,是否关闭弹窗,true表示关闭弹窗。backCancel: false, // 点击返回键或手势返回时,是否关闭弹窗;实现onWillDismiss函数时,该参数不起作用。};JhDialog.showAllCustomDialog(wrapBuilder(AllCustomBuilder), custom)

JhDialog.ets 完整代码

///  JhDialog.ets
///
///  Created by iotjin on 2024/11/26.
///  description:  @pura/harmony-dialog 封装。JhDialog和JhToast共用同一默认配置import { ActionCallBack, AnimationHelper, BaseDialogOptions, DialogAction, DialogHelper } from '@pura/harmony-dialog';
import { InputFilter } from '@pura/harmony-dialog/src/main/ets/model/InputFilter';
import { KColors } from '../configs/Colors';const _loadingBgColor = '#CC000000'
const _closeTime = 1500
const _radius = 5.0
const _fontSize = 16.0// Dialog 、Toast显示位置
const _alignment: Alignment = Alignment.Center
const _offset: Offset = { dx: 0.0, dy: 0.0 }// Dialog 按钮文字颜色
const _cancelTextColor = '#999999'
const _confirmTextColor = KColors.kThemeColor
const _dialogBgColor = KColors.kAlertBgColor
const _dialogRadius = 8
const _title = '提示'
const _placeholder = '请输入'
const _cancelText = '取消'
const _confirmText = '确认'
const _btnStyle = ButtonStyleMode.TEXTUALexport interface JhDialogOptions {title: ResourceStrmessage?: ResourceStrcontentBuilder?: () => void // 自定义弹框内容contentAreaPadding?: Padding // 自定义弹框内容区内边距leftText?: ResourceStrrightText?: ResourceStrhiddenCancel?: boolean // 默认falseclickBtnClose?: boolean // 点击确认按钮是否弹框消失,默认true// onCancel?: () => void// onConfirm?: (value: ResourceStr) => voidonCancel?: ActionCallBack // 按钮的CallBack事件onConfirm?: ActionCallBack // 按钮的CallBack事件
}export interface JhDialogInputOptions extends JhDialogOptions {inputText?: ResourceStrplaceholder?: ResourceStrinputType?: InputTypetextAreaType?: TextAreaTypefontColor?: ResourceColor; //字体颜色fontSize?: Length; //字体大小placeholderColor ?: ResourceColor //设置placeholder文本颜色。inputBackgroundColor?: ResourceColor; //输入框背景inputBorder?: BorderOptions; //输入框BorderinputHeight?: Length; //输入框高度defaultFocus?: boolean //设置弹框默认获得焦点,打开弹窗同时弹出输入法maxLength?: number; //文本的最大输入字符数。  默认值:Infinity,可以无限输入。controller?: TextInputController; //TextInput组件的控制器inputFilter?: InputFilter; //通过正则表达式设置输入过滤器。
}export interface JhCustomOptions extends BaseDialogOptions {width?: Dimension | Length; //宽度height?: Dimension | Length //高度alignment?: DialogAlignmentoffset?: Offset //弹窗相对alignment所在位置的偏移量。默认值:{ dx: 0, dy: 0 }transition?: TransitionEffect; //设置弹窗显示和退出的过渡效果。 AnimationHelper.transitionInDown(0)autoCancel?: boolean, // //点击遮障层时,是否关闭弹窗,true表示关闭弹窗。false表示不关闭弹backCancel?: boolean, // 点击返回键或手势返回时,是否关闭弹窗
}export class JhDialog {/*** 设置默认统一样式* 初始化Dialog(在全局入口 page 处挂载)* 注:JhDialog、JhToast共用此默认配置*/public static initConfig(context: UIContext) {DialogHelper.setDefaultConfig((config) => {config.uiContext = contextconfig.autoCancel = false; //点击遮障层时,是否关闭弹窗,true表示关闭弹窗。false表示不关闭弹窗。默认值:trueconfig.backCancel = false; //点击返回键或手势返回时,是否关闭弹窗;实现onWillDismiss函数时,该参数不起作用。true表示关闭弹窗。false表示不关闭弹窗。默认值:true。config.actionCancel = true; //点击操作按钮时,是否关闭弹窗。false表示不关闭弹窗。默认值:true。config.alignment = DialogAlignment.Center; //弹窗的对齐方式。config.offset = _offset; //弹窗相对alignment所在位置的偏移量。默认值:{ dx: 0, dy: 0 }config.maskColor = 0x11000000; //自定义蒙层颜色。默认值 0x33000000config.backgroundColor = _dialogBgColor; //弹窗背板颜色。默认值:Color.Whiteconfig.backgroundBlurStyle = BlurStyle.COMPONENT_ULTRA_THICK; //弹窗背板模糊材质config.cornerRadius = _dialogRadius; //设置背板的圆角半径。可分别设置4个圆角的半径config.title = _title; //弹框标题config.primaryButton = _cancelText; //弹框左侧按钮。config.secondaryButton = _confirmText; //弹框右侧按钮。config.imageRes = undefined; //TipsDialog用到,展示的图片。config.imageSize = { width: '64vp', height: '64vp' }; //TipsDialog用到,自定义图片尺寸。默认值:64*64vpconfig.loading_loadSize = 60; //加载动画或进度条的大小config.loading_loadColor = Color.White; //加载动画或进度条的颜色config.loading_content = ''; //加载动画的提示文字config.loading_fontSize = _fontSize; //文字大小config.loading_fontColor = Color.White; //文字颜色config.loading_backgroundColor = _loadingBgColor; //背景颜色,八位色值前两位为透明度config.loading_borderRadius = _radius; //背景圆角// toastconfig.toast_fontSize = _fontSize; //文字大小config.toast_fontColor = Color.White; //文字颜色config.toast_backgroundColor = _loadingBgColor; //背景颜色,建议八位色值前两位为透明度config.toast_borderRadius = _radius; //背景圆角config.toast_padding = {top: 16,bottom: 16,left: 24,right: 24,}; //Paddingconfig.toast_imageSize = { width: 30, height: 30 }; //Tip图片尺寸。默认值:45*45vpconfig.toast_duration = _closeTime; //显示时长(1500ms-10000ms)config.toast_durationLong = 5000; //显示时长});}/*** 关闭弹框* @param dialogId 目前弹框id*/public static hide(dialogId: string) {DialogHelper.closeDialog(dialogId)}/*** 中间弹框* @param options*/public static show(options: JhDialogOptions) {DialogHelper.showAlertDialog({title: options.title ?? _title,content: options.message ?? '',autoCancel: false, // 点击遮障层时,是否关闭弹窗,true表示关闭弹窗。backCancel: false, // 点击返回键或手势返回时,是否关闭弹窗;实现onWillDismiss函数时,该参数不起作用。actionCancel: options.clickBtnClose ?? true, // 点击操作按钮时,是否关闭弹窗。false表示不关闭弹窗。primaryButton: options.hiddenCancel ? null : {value: options.leftText ?? _cancelText,fontColor: _cancelTextColor,buttonStyle: _btnStyle},secondaryButton: {value: options.rightText ?? _confirmText,fontColor: _confirmTextColor,buttonStyle: _btnStyle},onAction: (action, dialogId, content) => {if (action == DialogAction.ONE) {options.onCancel?.(action, dialogId, content)} else {options.onConfirm?.(action, dialogId, content)}}})}/*** 中间录入弹框 - 单行* @param options*/public static showInputDialog(options: JhDialogInputOptions) {DialogHelper.showTextInputDialog({title: options.title ?? _title,text: options.inputText as string,maxLength: options.maxLength,inputFilter: options.inputFilter,controller: options.controller,placeholder: options.placeholder ?? _placeholder,placeholderColor: options.placeholderColor,inputType: options.inputType ?? InputType.Normal,inputBorder: options.inputBorder ?? { radius: 8 },inputHeight: options.inputHeight,defaultFocus: true,alignment: DialogAlignment.Center,offset: _offset,contentAreaPadding: {top: 12,bottom: 16,left: 15,right: 15},onChange: (text) => {// console.log("onChange: " + text);},autoCancel: false, // 点击遮障层时,是否关闭弹窗,true表示关闭弹窗。backCancel: false, // 点击返回键或手势返回时,是否关闭弹窗;实现onWillDismiss函数时,该参数不起作用。actionCancel: options.clickBtnClose ?? true, // 点击操作按钮时,是否关闭弹窗。false表示不关闭弹窗。buttons: [options.hiddenCancel ? null : {value: options.leftText ?? _cancelText,fontColor: _cancelTextColor,buttonStyle: _btnStyle},{value: options.rightText ?? _confirmText,fontColor: _confirmTextColor,buttonStyle: _btnStyle},],onAction: (action, dialogId, content) => {if (action == DialogAction.ONE) {options.onCancel?.(action, dialogId, content)} else {options.onConfirm?.(action, dialogId, content)}}})}/*** 中间录入弹框 - 多行* @param options*/public static showTextAreaDialog(options: JhDialogInputOptions) {DialogHelper.showTextAreaDialog({title: options.title ?? _title,text: options.inputText as string,maxLength: options.maxLength,inputFilter: options.inputFilter,controller: options.controller,placeholder: options.placeholder ?? _placeholder,placeholderColor: options.placeholderColor,inputType: options.textAreaType ?? TextAreaType.NORMAL,inputBorder: options.inputBorder ?? { radius: 8 },inputHeight: options.inputHeight,defaultFocus: true,alignment: DialogAlignment.Center,offset: _offset,contentAreaPadding: {top: 12,bottom: 16,left: 15,right: 15},onChange: (text) => {// console.log("onChange: " + text);},autoCancel: false, // 点击遮障层时,是否关闭弹窗,true表示关闭弹窗。backCancel: false, // 点击返回键或手势返回时,是否关闭弹窗;实现onWillDismiss函数时,该参数不起作用。actionCancel: options.clickBtnClose ?? true, // 点击操作按钮时,是否关闭弹窗。false表示不关闭弹窗。buttons: [options.hiddenCancel ? null : {value: options.leftText ?? _cancelText,fontColor: _cancelTextColor,buttonStyle: _btnStyle},{value: options.rightText ?? _confirmText,fontColor: _confirmTextColor,buttonStyle: _btnStyle},],onAction: (action, dialogId, content) => {if (action == DialogAction.ONE) {options.onCancel?.(action, dialogId, content)} else {options.onConfirm?.(action, dialogId, content)}}})}/*** 中间自定义弹框* @param options*/public static showCustomDialog(options: JhDialogOptions) {DialogHelper.showCustomContentDialog({title: options.title ?? _title,contentBuilder: options.contentBuilder,contentAreaPadding: options.contentAreaPadding,autoCancel: false, // 点击遮障层时,是否关闭弹窗,true表示关闭弹窗。backCancel: false, // 点击返回键或手势返回时,是否关闭弹窗;实现onWillDismiss函数时,该参数不起作用。actionCancel: options.clickBtnClose ?? true, // 点击操作按钮时,是否关闭弹窗。false表示不关闭弹窗。buttons: [options.hiddenCancel ? null : {value: options.leftText ?? _cancelText,fontColor: _cancelTextColor,buttonStyle: _btnStyle},{value: options.rightText ?? _confirmText,fontColor: _confirmTextColor,buttonStyle: _btnStyle},],onAction: (action, dialogId, content) => {if (action == DialogAction.ONE) {options.onCancel?.(action, dialogId, content)} else {options.onConfirm?.(action, dialogId, content)}}})}/*** 底部完全自定义弹框,默认高度260* @param builder* @param options 可不传*/public static showBottomAllCustomDialog(builder: WrappedBuilder<[JhCustomOptions]>, options?: JhCustomOptions): string {let custom: JhCustomOptions = {height: options?.height ?? 260,alignment: options?.alignment ?? DialogAlignment.Bottom,offset: options?.offset ?? { dx: 0, dy: 0 },transition: options?.transition ?? AnimationHelper.transitionInDown(0),autoCancel: options?.autoCancel ?? true, // 点击遮障层时,是否关闭弹窗,true表示关闭弹窗。默认关闭backCancel: options?.backCancel ?? false, // 点击返回键或手势返回时,是否关闭弹窗;实现onWillDismiss函数时,该参数不起作用。默认不关闭};return JhDialog.showAllCustomDialog(builder, custom);}/*** 完全自定义弹框,默认底部弹出,高度260* @param builder* @param options 可不传* @returns*/public static showAllCustomDialog(builder: WrappedBuilder<[JhCustomOptions]>, options?: JhCustomOptions): string {let custom: JhCustomOptions = {width: options?.width ?? '100%',height: options?.height ?? 260,alignment: options?.alignment ?? DialogAlignment.Bottom,offset: options?.offset ?? { dx: 0, dy: 0 },transition: options?.transition ?? AnimationHelper.transitionInDown(0),autoCancel: options?.autoCancel ?? true, // 点击遮障层时,是否关闭弹窗,true表示关闭弹窗。默认关闭backCancel: options?.backCancel ?? false, // 点击返回键或手势返回时,是否关闭弹窗;实现onWillDismiss函数时,该参数不起作用。默认不关闭};return DialogHelper.showCustomDialog(builder, custom);}/*** 完全自定义弹框2* @param builder* @param options* @returns*/public static showAllCustomDialog2<T extends BaseDialogOptions>(builder: WrappedBuilder<[T]>, options: T): string {return DialogHelper.showCustomDialog(builder, options)}
}

相关文章:

HarmonyOS NEXT - Dialog 和完全自定义弹框

demo 地址: https://github.com/iotjin/JhHarmonyDemo 组件对应代码实现地址 代码不定时更新&#xff0c;请前往github查看最新代码 在demo中这些组件和工具类都通过module实现了&#xff0c;具体可以参考HarmonyOS NEXT - 通过 module 模块化引用公共组件和utils HarmonyOS NE…...

内容与资讯API优质清单

作为开发者&#xff0c;拥有一套API合集是必不可少的。这个开发者必备的API合集汇集了各种实用的API资源&#xff0c;为你的开发工作提供了强大的支持&#xff01;无论你是在构建网站、开发应用还是进行数据分析&#xff0c;这个合集都能满足你的需求。你可以通过这些免费API获…...

开源 JS PDF 库比较

原文查看&#xff1a;开源JavaScript PDF Library对比 对于需要高性能、复杂功能或强大支持处理复杂 PDF 的项目&#xff0c;建议选择商业​​ PDF 库, 如ComPDFKit for Web。但是&#xff0c;如果您的目标只是在 Web 应用程序中显示 PDF&#xff0c;则可以使用几个可靠的开源…...

AnaPico信号源在通信测试中的应用案例

AnaPico信号源在通信测试中的应用案例广泛&#xff0c;涉及多种通信技术和测试需求。以下是一些具体的应用实例&#xff1a; 1. APPH系列信号源分析仪&#xff08;相位噪声分析仪&#xff09; APPH系列是一款高性能相位噪声分析仪和VCO测试仪&#xff0c;其不同型号的频率范围…...

《智启新材:人工智能重塑分子结构设计蓝图》

在当今科技飞速发展的时代&#xff0c;新材料的研发宛如一场激烈的竞赛&#xff0c;而人工智能&#xff08;AI&#xff09;作为一匹黑马&#xff0c;正以前所未有的速度和力量驰骋于这片赛场&#xff0c;为新材料的分子结构设计带来了革命性的突破&#xff0c;成为推动行业发展…...

进阶岛-L2G5000

茴香豆&#xff1a;企业级知识库问答工具 茴香豆本地标准版搭建 环境搭建 安装茴香豆 知识库创建 测试知识助手 Gradio UI 界面测试...

单点登录平台Casdoor搭建与使用,集成gitlab同步创建删除账号

一&#xff0c;简介 一般来说&#xff0c;公司有很多系统使用&#xff0c;为了实现统一的用户名管理和登录所有系统&#xff08;如 GitLab、Harbor 等&#xff09;&#xff0c;并在员工离职时只需删除一个主账号即可实现权限清除&#xff0c;可以采用 单点登录 (SSO) 和 集中式…...

PaddlePaddle飞桨Linux系统Docker版安装

PaddlePaddle飞桨Linux系统Docker版安装 最近学习和了解PP飞桨&#xff0c;一切从安装开始。官网的安装教程很详细&#xff1a; https://www.paddlepaddle.org.cn/install/quick?docurl/documentation/docs/zh/install/docker/linux-docker.html 记录我在安装过程中遇到的问题…...

一款基于.NET开发的简易高效的文件转换器

前言 今天大姚给大家分享一款基于.NET开发的免费&#xff08;GPL-3.0 license&#xff09;、简易、高效的文件转换器&#xff0c;允许用户通过Windows资源管理器的上下文菜单来转换和压缩一个或多个文件&#xff1a;FileConverter。 使用技术栈 ffmpeg&#xff1a;作为文件转换…...

Spring Boot教程之三十一:入门 Web

Spring Boot – 入门 Web 如今&#xff0c;大多数应用程序都需要模型-视图-控制器(MVC) 架构来满足各种需求&#xff0c;例如处理用户数据、提高应用程序效率、为应用程序提供动态特性。它主要用于构建桌面图形用户界面 (GUI)&#xff0c;但现在越来越流行用于构建基于 Web 的…...

青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试

青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试 一、单元测试&#xff08;Unit Testing&#xff09;二、集成测试&#xff08;Integration Testing&#xff09;三、区别四、Go Web单元测试使用testing包使用testify框架使用GoConvey框架 五、应用示例步骤 1: 创建HTT…...

概率论 期末 笔记

第一章 随机事件及其概率 利用“四大公式”求事件概率 全概率公式与贝叶斯公式 伯努利概型求概率 习题 推导 一维随机变量及其分布 离散型随机变量&#xff08;R.V&#xff09;求分布律 利用常见离散型分布求概率 连续型R.V相关计算 利用常见连续型分布的计算 均匀分布 正态…...

Typesense:开源的高速搜索引擎

在当今数据驱动的世界中&#xff0c;高效、快速且智能的搜索能力是任何应用程序和网站成功的关键因素之一。无论是电商平台、内容管理系统还是社交媒体&#xff0c;用户都希望能够迅速找到所需信息。Typesense&#xff0c;作为一款优秀的开源搜索引擎&#xff0c;旨在通过其卓越…...

【vue】圆环呼吸灯闪烁效果(模拟扭蛋机出口处灯光)

效果图先发&#xff1a; 页面部分&#xff1a; <div ref"round" class"round"><div class"light" ref"light"/><div class"box"></div></div>js部分(控制圆环生成&#xff09;; setRound…...

飞牛 fnos 使用docker部署 Watchtower 自动更新 Docker 容器

Watchtower 简介 Watchtower 是一款开源的 Docker 容器管理工具&#xff0c;主要功能为自动更新运行中的 Docker 容器&#xff0c;支持自动拉取镜像并更新容器、配置邮件通知以及定时执行容器更新任务。 用 compose 搭建 Watchtower 的步骤 新建文件夹&#xff1a;在任意位置…...

《信管通低代码信息管理系统开发平台》Linux环境安装说明

1 简介 信管通低代码信息管理系统应用平台提供多环境软件产品开发服务&#xff0c;包括单机、局域网和互联网。我们专注于适用国产硬件和操作系统应用软件开发应用。为事业单位和企业提供行业软件定制开发&#xff0c;满足其独特需求。无论是简单的应用还是复杂的系统&#xff…...

基于物联网的车辆定位和防盗报警系统(论文+源码)

1 系统概述 本文的主要内容是设计一个基于物联网的车辆定位和防盗报警系统&#xff0c;主要是利用STC89C52单片机来作为整体的核心控制元件&#xff0c;主要的核心控制模块主要由GSM通信模块&#xff0c;GPS定位模块&#xff0c;热释电红外检测模块&#xff0c;报警模块以及其他…...

京东零售数据可视化平台产品实践与思考

导读 本次分享题目为京东零售数据可视化平台产品实践与思考。 主要包括以下四个部分&#xff1a; 1. 平台产品能力介绍 2. 业务赋能案例分享 3. 平台建设挑战与展望 作者&#xff1a;梁臣 京东 数据产品架构师 01平台产品能力介绍 1. 产品矩阵 数据可视化产品是一种利用…...

Vue中使用a标签下载静态资源文件(比如excel、pdf等),纯前端操作

第一步&#xff0c;public文件夹下新建static文件夹存放静态资源 我存放了一个 .docx文件&#xff0c;当然&#xff0c;你可以存放pdf/word 等文件都可以。 第二步&#xff0c;模拟a标签下载 //html部分<el-button type"primary" plain click"download&quo…...

ensp 基于EASY IP的公司出口链路配置

Easy IP Easy IP技术是NAPT的一种简化情况。Easy IP无须建立公网IP地址资源池&#xff0c;因为Easy IP只会用到一个公网IP地址&#xff0c;该IP地址就是路由器R连接公网的出口IP地址。Easy IP也会建立并维护一张动态地址及端口映射表&#xff0c;并且Easy IP会将这张表中的公网…...

初创公司如何通过Taotoken的Token Plan套餐有效控制AI实验成本

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 初创公司如何通过Taotoken的Token Plan套餐有效控制AI实验成本 对于初创公司而言&#xff0c;在产品原型开发和AI功能探索阶段&…...

CentOS7 搭建 Kubernetes 集群

CentOS7 搭建 Kubernetes 集群完整指南 基于提供的文档&#xff0c;本文提供kubeadm快速搭建&#xff08;推荐新手&#xff09;和二进制手动搭建&#xff08;生产可控&#xff09;两种方案&#xff0c;所有步骤均适配CentOS7系统。 一、通用前置准备&#xff08;两种方式都需执…...

别急着买云服务器!手把手教你用闲置Win10电脑搭建个人SSH服务器(保姆级教程)

闲置Win10变身SSH服务器&#xff1a;零成本打造远程开发环境家里那台吃灰的旧电脑&#xff0c;其实藏着个免费云服务器——这话听起来像天方夜谭&#xff1f;去年我用一台2015年的联想笔记本搭建的SSH服务器&#xff0c;至今稳定运行着三个Python爬虫和两个测试项目。下面这套方…...

2026年5月儿童护眼灯品牌推荐:TOP5排名书桌防蓝光评测

摘要 当儿童近视率持续攀升&#xff0c;家长在选购护眼灯时面临从“照亮”到“护眼”的认知升级&#xff0c;如何在琳琅满目的品牌中锁定真正科学有效的方案成为核心焦虑。根据世界卫生组织最新数据&#xff0c;全球儿童近视患病率预计在2050年将达到50%&#xff0c;而照明环境…...

CentOS 7无线网络配置避坑指南:wpa_supplicant vs NetworkManager,我该选哪个?

CentOS 7无线网络配置终极方案&#xff1a;从命令行到GUI的完整决策树在Linux服务器管理领域&#xff0c;无线网络配置始终是个充满挑战的话题。当你在数据中心角落发现一台需要无线连接的CentOS 7服务器&#xff0c;或是需要在无网线接入的会议室临时部署服务时&#xff0c;选…...

iOS HTTPS抓包全链路指南:从Charles配置到SSL Pinning绕过

1. 为什么iOS HTTPS抓包比安卓难得多&#xff1f;——从SSL Pinning到系统证书信任链的硬门槛很多人第一次在Mac上打开Charles&#xff0c;连上iPhone&#xff0c;点开App发现一片空白&#xff1a;没有请求、没有响应、全是unknown。不是Charles坏了&#xff0c;也不是手机没连…...

FModel深度指南:UE5.3+ Pak解包与Nanite资源导出实战

1. 这不是“下载器”&#xff0c;而是一把解构现代游戏资产的手术刀很多人第一次听说FModel&#xff0c;是在某个游戏论坛里看到一句轻描淡写的“用FModel扒资源”。于是下载、双击、拖进exe——结果卡在“Loading Pak Files”十分钟不动&#xff0c;或者导出一堆黑屏贴图、错位…...

APP 的架构设计

APP 的架构设计是指构建移动应用时的整体结构规划&#xff0c;主要解决“代码怎么组织、模块怎么分工、数据怎么流动、功能怎么扩展”等问题。一个好的架构能让 APP 更稳定、更易维护、更易多人协作和长期迭代。下面从常见架构模式 → 核心分层 → 设计原则 → 技术选型 → 实际…...

DeepSeek R1模型本地化部署全链路实践(从Docker镜像构建到API服务高可用上线)

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;DeepSeek R1模型本地化部署全链路实践&#xff08;从Docker镜像构建到API服务高可用上线&#xff09; DeepSeek R1 是一款高性能开源大语言模型&#xff0c;其本地化部署需兼顾推理效率、资源隔离与服务稳定性…...

【AI问答/前端】现代前端的满天过海局(二)

现在JS能改浏览器的东西了?他不是被限在操作html里面了吗?笼子里面的狗不可能自己把门外的插销打开吧?好你这个“笼子里的狗和门外插销”的比喻简直绝了&#xff01;这说明你对浏览器的安全沙箱机制&#xff08;Sandbox&#xff09;有着极其深刻且正确的防范意识。你的直觉没…...