【sgTree】自定义组件:加载el-tree树节点整棵树数据,实现增删改操作。
特性
- 可以自定义主键、配置选项
- 支持预定义节点图标:folder文件夹|normal普通样式
- 多个提示文本可以自定义
- 支持动态接口增删改节点
- 可以自定义根节点id
- 可以设置最多允许添加的层级深度
- 支持拖拽排序,排序过程还可以针对拖拽的节点深度进行自定义限制
- 支持隐藏一级节点(根节点)复选框☑
- 支持屏蔽一级节点(根节点)勾选☑
sgTree源码
<template><div :class="$options.name"><div class="tree-header" v-if="!(readonly || readonly === '')"><div class="sg-left"><template v-if="uploadData"><el-tooltippopper-class="sg-el-tooltip":enterable="false"effect="dark":content="`支持拖拽到树上传文件`"placement="top-start"><el-buttontype="text"icon="el-icon-upload"size="mini"@click="(d) => $refs.sgUpload.triggerUploadFile()">批量导入</el-button></el-tooltip><el-button type="text" icon="el-icon-download" size="mini" @click="downloadTpl">下载模板</el-button></template></div><div class="sg-right"><el-button type="text" size="mini" @click.stop="addRoot">{{ (data.text || {}).addRootButtonText || `添加根节点`}}<i class="el-icon-circle-plus-outline"></i></el-button></div></div><div class="tree-container"><el-tree:class="hideRootNodeCheckbox === '' || hideRootNodeCheckbox? 'hideRootNodeCheckbox': ''"ref="tree":data="treeData":node-key="mainKey":props="data.props || {label: 'label', //指定节点标签为节点对象的某个属性值children: 'children', //指定子树为节点对象的某个属性值disabled: 'leaf', //指定节点选择框是否禁用为节点对象的某个属性值isLeaf: 'leaf', //指定节点是否为叶子节点,仅在指定了 lazy 属性的情况下生效}":icon-class="`${data.iconType}-tree-node`":indent="data.indent || 10"@current-change="current_change"@node-click="nodeClick"highlight-current@node-drag-start="nodeDragStart"@node-drag-enter="nodeDragEnter"@node-drag-leave="nodeDragLeave"@node-drag-over="nodeDragOver"@node-drag-end="nodeDragEnd"@node-drop="nodeDrop":draggable="draggable === '' || draggable":allow-drop="allowDrop":allow-drag="allowDrag":show-checkbox="showCheckbox":default-checked-keys="defaultCheckedKeys"@check-change="handleCheckChange"><el-popoverpopper-class="tree-el-popover"placement="right"trigger="hover"title=""content="":disabled="readonly || readonly === ''"slot-scope="{ node, data }"><span class="right"><el-buttontitle="添加"type="text"size=""icon="el-icon-circle-plus-outline"@click.stop="addNode(node, data)"v-if="showAddButton(node)">添加</el-button><el-buttontitle="删除"type="text"size=""icon="el-icon-remove-outline"@click.stop="remove(node, data)">删除</el-button></span><div slot="reference" class="node-label"><div class="left" :title="node.label">{{ node.label }}</div></div></el-popover></el-tree><!-- 上传组件 --><sgUpload:disabledWhenShowSels="['.v-modal']":drag="uploadData ? dragUpload : false"ref="sgUpload":data="uploadData"@uploadSuccess="uploadSuccess"@uploadError="uploadError"@importError="importError"@showLoading="showLoading"@hideLoading="hideLoading"hideUploadTray/></div></div>
</template><script>
import sgUpload from "@/vue/components/admin/sgUpload";
export default {name: "sgTree",components: {sgUpload,},data() {return {// 动态树:增删改_________________________________________________________rootNode: null, //根节点rootResolve: null, //根节点focusNodeId: null, //聚焦高亮新添加IDmainKey: "id", //默认主键defaultRootId: "root", //默认根节点ID就是rootmaxAddLevel: null, // 最多允许添加的层级dragUpload: true, //在拖拽节点过程中控制上传组件能否拖拽上传// _________________________________________________________};},props: ["treeData","data","readonly","draggable", //是否开启拖拽节点功能"uploadData",/* 例子 uploadData: {accept: '.xls,.xlsx',actionUrl: `${this.$d.API_ROOT_URL}/core/resource/upload`,}, */"allowNodeDrag","allowNodeDrop","showCheckbox", //节点是否可被选择"hideRootNodeCheckbox", //隐藏一级节点复选框☑"disabledRootNode", //屏蔽一级节点勾选☑"defaultCheckedKeys", //默认勾选的节点的 key 的数组],watch: {data: {/* data.iconType= 节点图标:folder 文件夹normal 普通样式plus 加减符号样式*/handler(d) {d.nodeKey && (this.mainKey = d.nodeKey); //主键d.rootId && (this.defaultRootId = d.rootId); //根节点IDd.maxAddLevel && (this.maxAddLevel = d.maxAddLevel); // 最多允许添加的层级},deep: true,immediate: true,},},methods: {showLoading(file) {this.$emit(`showLoading`, file);},hideLoading(file) {this.$emit(`hideLoading`, file);},// 取消选中unCheckAll(d) {this.$refs.tree.setCheckedKeys([]);this.handleCheckChange([], []);},handleCheckChange(data, checked, indeterminate) {this.$emit(`checkChange`, {checkedNodes: this.$refs.tree.getCheckedNodes(),checkedLeafOnlyNodes: this.$refs.tree.getCheckedNodes(true, false), //(leafOnly, includeHalfChecked) 接收两个 boolean 类型的参数,1. 是否只是叶子节点,默认值为 false 2. 是否包含半选节点,默认值为 false【注意:懒加载树形不管用!必须要明确叶子节点展开后面没有子节点了才能识别!】data,checked,indeterminate,});},// 拖拽----------------------------------------nodeDragStart(node, ev) {this.dragUpload = false;this.$emit(`nodeDragStart`, node, ev);},nodeDragEnter(draggingNode, dropNode, ev) {this.$emit(`nodeDragEnter`, draggingNode, dropNode, ev);},nodeDragLeave(draggingNode, dropNode, ev) {this.$emit(`nodeDragLeave`, draggingNode, dropNode, ev);},nodeDragOver(draggingNode, dropNode, ev) {this.$emit(`nodeDragOver`, draggingNode, dropNode, ev);},nodeDragEnd(draggingNode, dropNode, dropType, ev) {// dropType有'before'、'after'、'inner'和'none'4种情况this.dragUpload = true;this.$emit(`nodeDragEnd`, draggingNode, dropNode, dropType, ev);},nodeDrop(draggingNode, dropNode, dropType, ev) {// dropType有'before'、'after'、'inner'和'none'4种情况this.$emit(`nodeDrop`, draggingNode, dropNode, dropType, ev);},allowDrop(draggingNode, dropNode, dropType) {// 拖拽时判定目标节点能否被放置。dropType 参数有三种情况:'prev'、'inner' 和 'next',分别表示放置在目标节点前、插入至目标节点和放置在目标节点后(注意:很奇葩上面node开头的绑定方法dropType有before、after、inner和none4种情况)return this.allowNodeDrop? this.allowNodeDrop(draggingNode, dropNode, dropType): true;},allowDrag(draggingNode) {return this.allowNodeDrag ? this.allowNodeDrag(draggingNode) : true;},// ----------------------------------------showAddButton(node) {if (this.maxAddLevel) {return node.level < this.maxAddLevel; // 最多允许添加的层级} else return true;},downloadTpl(d) {this.$emit(`downloadTpl`);},uploadSuccess(d, f) {this.$emit(`uploadSuccess`, d, f);},uploadError(d, f) {this.$emit(`uploadError`, d, f);},importError(d, f) {this.$emit(`importError`, d, f);},// 聚焦到某一个节点focusNode(id) {if (!id) return;this.$nextTick(() => {this.$refs.tree.setCurrentKey(id); //高亮显示某个节点this.$emit(`currentChange`, this.$refs.tree.getCurrentNode());this.$nextTick(() => {let dom = document.querySelector(`.el-tree-node.is-current`);dom &&dom.scrollIntoView({behavior: "smooth",block: "nearest",inline: "nearest",}); //缓慢滚动});});},// 添加根节点addRoot() {this.addNode(this.$refs.tree.root, { [this.mainKey]: this.defaultRootId });},// 通过id展开指定节点(通常是用于外部调用)expandNodeById(id) {let node = this.$refs.tree.getNode(id);node.expand();},//通过id勾选节点setCheckedKeys(ids) {this.$refs.tree.setCheckedKeys(ids);},// 添加节点addNode(node, data) {let resolve = (d) => {if (data.ID === this.defaultRootId) {this.treeData.unshift(d);} else {data.children || this.$set(data, "children", []);data.children.push(d);}node.expand();};let reject = (d) => {this.rootLoading = false;node.loading = false;this.$message.error(d.msg); //添加节点失败};this.$emit(`addNode`, { node, data, resolve, reject });},// 删除节点remove(node, data) {this.$confirm((this.data.text || {}).removeConfirmTip ||`此操作将永久删除该节点及其下面的节点,是否继续?`,(this.data.text || {}).removeConfirmTitle || `提示`,{dangerouslyUseHTMLString: true,confirmButtonText: `确定`,cancelButtonText: `取消`,type: "warning",}).then(() => {this.removeNodeData(node, data);}).catch(() => {});},// 删除节点数据(通过接口向后台删除数据)removeNodeData(node, data) {node.loading = true; //出现加载动画let resolve = (d) => {node.loading = false;this.$message.success(`删除成功`);// 从父节点异步删除子节点const parent = node.parent;const children = parent.data.children || parent.data;const index = children.findIndex((d) => d[this.mainKey] === data[this.mainKey]);children.splice(index, 1);// 从显示界面删除节点(有bug,只是删除了树节点的Virtual DOM,实际数据还在)/* let childNodes = node.parent.childNodes; childNodes.splice( childNodes.findIndex((d) => d.data[this.mainKey] === data[this.mainKey]), 1 ); */};let reject = (d) => {this.rootLoading = false;node.loading = false;this.$message.error(d.msg); //删除失败};this.$emit(`removeNode`, { node, data, resolve, reject });},// 当前选中节点变化时触发的事件current_change(d) {this.$emit(`currentChange`, d);},//点击节点nodeClick(d) {this.focusNodeId = null;this.$emit(`nodeClick`, d);},},
};
</script><style lang="scss" scoped>
@import "~@/css/sg";.sgTree {$treeHeaderHeight: 30px;width: 100%;height: 100%;display: flex;flex-wrap: nowrap;flex-direction: column;white-space: nowrap;flex-shrink: 0;flex-grow: 1;position: relative;.tree-header {display: flex;justify-content: space-between;align-items: center;height: $treeHeaderHeight;& > .sg-left {}& > .sg-right {}}.tree-container {position: relative;overflow: auto;box-sizing: border-box;height: calc(100% - #{$treeHeaderHeight});flex-shrink: 0;flex-grow: 1;user-select: none;@include scrollbarHover();/* >>> .tree-container .el-tree .el-tree-node__content {cursor: pointer;} */>>> .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {background-color: #409eff22; // 高亮当前选中节点背景}>>> .el-tree {* {transition: none;}.el-tree-node__children {min-width: max-content; //这样才会出现水平滚动条}.normal-tree-node,.plus-tree-node,.folder-tree-node {& + label:not(.el-checkbox) {/*单行省略号*/overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}flex-shrink: 0;display: block;padding: 0 !important;margin: 0;width: 20px;height: 20px;margin-right: 5px;background: transparent url("~@/../static/img/fileType/folder/folder.svg")no-repeat center / contain;margin-left: 20px;& ~ span:not(.el-icon-loading) {width: 100%;.node-label {height: 40px;display: flex;align-items: center;}}&.expanded {flex-shrink: 0;transform: rotate(0deg);background-image: url("~@/../static/img/fileType/folder/folder-open.svg");}&.is-leaf {background-image: none;}}.normal-tree-node {margin-left: 10px;background-image: url("~@/../static/img/fileType/folder/arrow-right.svg");&.expanded {transform: rotate(90deg);background-image: url("~@/../static/img/fileType/folder/arrow-right.svg");}&.is-leaf {background-image: none;}}.plus-tree-node {margin-left: 10px;background-image: url("~@/../static/img/fileType/folder/plus.svg");&.expanded {background-image: url("~@/../static/img/fileType/folder/minus.svg");}&.is-leaf {background-image: none;}}// 隐藏一级节点的复选框&.hideRootNodeCheckbox > div > .el-tree-node__content .el-checkbox {display: none;}}}
}.tree-el-popover {.el-button {padding-top: 0;padding-bottom: 0;}
}
</style>
应用
<template><div :class="$options.name"><sgTreev-loading="loading":key="$route.query.BMID + sgTree_fresh":treeData="treeData":data="treeConfigData"@currentChange="currentChange"@addNode="addNode"@removeNode="removeNode":uploadData="{name: `file`,accept: '.xls,.xlsx',actionUrl: `${$d.API_ROOT_URL}/core/column/importColumn`, //批量导入树结构接口actionData: {BMID: $global.getBMID(),PID: `root`,sgLog: `强哥请求来源:${$options.name}导入栏目xls`,},}"@uploadSuccess="uploadSuccess"@uploadError="uploadError"@importError="importError"@downloadTpl="downloadTpl"draggable:allowNodeDrop="allowNodeDrop"@nodeDragEnd="nodeDragEnd"/></div>
</template><script>
import sgTree from "@/vue/components/admin/sgTree";
export default {name: "sgBody",components: {sgTree,},data() {return {sgTree_fresh: false,autoId: 0, //自增编号treeConfigData: {nodeKey: `ID`, //主键props: { label: "MC", isLeaf: "leaf" }, //配置选项iconType: "plus", //节点图标:folder文件夹|normal普通样式|plus加减符号样式text: {addRootButtonText: "添加根目录", //添加根节点按钮文本removeConfirmTitle: "警告!!!", //删除节点提示标题removeConfirmTip: "此操作将永久删除该节点及其下面的子节点,是否继续?", //删除节点提示内容},},treeData: [],loading: false,};},created() {this.initTreeData();},methods: {//初始化数据initTreeData({ d } = {}) {this.$global.获取整棵树的数据({cb: (d) => {this.treeData = d;},});},// 拖拽节点相关方法----------------------------------------allowNodeDrop(draggingNode, dropNode, dropType) {// 只允许拖拽同级别前后排序let isPrevOrNext = dropType === "prev" || dropType === "next";// 同在第一级根节点下let isSameRootLevel =draggingNode.level === dropNode.level && draggingNode.level === 1;// 同在一个节点(非根节点)下let isSameChildLevel =draggingNode.parent &&dropNode.parent &&draggingNode.parent.data &&dropNode.parent.data &&draggingNode.parent.data.ID === dropNode.parent.data.ID;return isPrevOrNext && (isSameRootLevel || isSameChildLevel);},nodeDragEnd(draggingNode, dropNode, dropType, ev) {// 只允许拖拽同级别前后排序let isBeforeOrAfter = dropType === "before" || dropType === "after";if (isBeforeOrAfter) {/* console.log("被拖拽的节点", draggingNode.data.MC, draggingNode.data.PXZ); console.log("停靠的节点", dropNode.data.MC, dropNode.data.PXZ); */let theSameLevelDatas = (dropNode.parent.childNodes || []).map((v) => v.data); // 获取同一级节点数据theSameLevelDatas.forEach((v, i) => (v.PXZ = i)); //重新排序// console.log("拖拽排序", theSameLevelDatas); //这里需要调用后台接口let IDS = theSameLevelDatas.map((v) => v.ID); //排序后的ID顺序数组let data = {IDS,sgLog: `强哥请求来源:${this.$options.name}更改同一层级树节点排序值`,};this.$d.修改节点排序({data,r: {s: (d) => {// console.log("【成功】", d);},},});}},// ----------------------------------------// 获取当前聚焦节点的数据currentChange(d) {console.log(``, d);},// 添加节点addNode({ data, resolve }) {this.$d.新增节点({data: {MC: `新增节点名称(${++this.autoId})`,},doing: {l: { show: () => (this.loading = true), close: () => (this.loading = false) },s: (d) => resolve(d),f: (d) => reject(d), //删除失败},});},// 删除节点removeNode({ node, data, resolve, reject }) {this.$d.删除节点({data: { ID: data.ID },doing: {s: (d) => resolve(d),f: (d) => reject(d), //删除失败},});},updateList(d) {},uploadSuccess(d, f) {this.sgTree_fresh = !this.sgTree_fresh;},uploadError(d, f) {this.$message.error(d.msg);},// 导入失败importError(d, f) {},// 下载导入模板downloadTpl(d) {},},
};
</script>
关联懒加载树节点组件【sgLazyTree】自定义组件:动态懒加载el-tree树节点数据,实现增删改、懒加载及局部数据刷新。_el-tree 动态刷新-CSDN博客文章浏览阅读464次。【代码】【sgLazyTree】自定义组件:动态懒加载el-tree节点数据,实现增删改。_el-tree 动态刷新https://blog.csdn.net/qq_37860634/article/details/132639389
相关文章:
【sgTree】自定义组件:加载el-tree树节点整棵树数据,实现增删改操作。
特性 可以自定义主键、配置选项支持预定义节点图标:folder文件夹|normal普通样式多个提示文本可以自定义支持动态接口增删改节点可以自定义根节点id可以设置最多允许添加的层级深度支持拖拽排序,排序过程还可以针对拖拽的节点深度进行自定义限制支持隐藏…...
vue2面试题:vue组件之间的通信方式有哪些?
vue2面试题:vue组件之间的通信方式有哪些? 回答思路:1.组件通信的目的-->2.组件通信的分类-->3.组件通信的方案1.组件通信的目的2.组件通信的分类3.组件通信的方案(1)通过props传递数据(2)…...

Pytorch神经网络模型nn.Sequential与nn.Linear
1、定义模型 对于标准深度学习模型,我们可以使用框架的预定义好的层。这使我们只需关注使用哪些层来构造模型,而不必关注层的实现细节。 我们首先定义一个模型变量net,它是一个Sequential类的实例。 Sequential类将多个层串联在一起。 当给…...
C++-gdb调试常用功能
文章目录 启动gdb运行程序设置断点运行控制查看源码查看信息查看变量线程相关 gdb调试常用功能如下,其中bin为要调试的程序,arg为参数 启动gdb 启动调试 gdb bin带参数启动 gdb --args bin arg1 arg2so预加载LD_PRELOAD/path/to/lib.so && gdb …...

快速上手的AI工具-文心一言辅助学习
前言 大家好晚上好,现在AI技术的发展,它已经渗透到我们生活的各个层面。对于普通人来说,理解并有效利用AI技术不仅能增强个人竞争力,还能在日常生活中带来便利。无论是提高工作效率,还是优化日常任务,AI工…...
Boost 适用 filesystem 库,statx 函数无法找到引用问题的解决方案。
1、boost 高版本使用了 statx 函数,这个函数是在 Linux 内核版本 4.11 之后引入的。 所以:可以升级 Linux 内核版本到4.11之后即可。 2、降低 boost 库版本到 1.70 以下 3、正确的路,改 boost 的编译代码 先看这个: Filesyste…...

MyBatis中一级缓存是什么?SqlSession一级缓存失效的原因?如何理解一级缓存?
一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就 会从缓存中直接获取,不会从数据库重新访问 使一级缓存失效的四种情况: 1) 不同的SqlSession对应不同的一级缓存 2) 同一…...

项目解决方案:多地医馆的高清视频监控接入汇聚联网
目 录 一、背景 二、建设目标及需求 1.建设目标 2.现状分析 3.需求分析 三、方案设计 1.设计依据 2.设计原则 3.方案设计 3.1 方案描述 3.2 组网说明 四、产品介绍 1.视频监控综合资源管理平台介绍 2.视频录像服务器和存储 2.1概述 2.2存储设计 …...

【前端基础--2】
选择器优先级 style标签中: .text{color: pink;}div{color: red;}#box{color: skyblue;} body标签中: <div class"text" id"box">猜猜我是什么颜色的</div> 运行结果: 选择器优先级权重: id选…...

【GitHub项目推荐--提取文字】【转载】
提取视频中的字幕 这个开源项目是提取视频中字幕的开源项目,提取视频中的关键帧,检测视频帧中文本的所在位置,识别视频帧中文本的内容。 不知道大家有没有做笔记的习惯,这个开源项目就很方便的把你一个视频中的字幕提取出来&…...
WebSocket与Shiro认证信息传递的实现与安全性探讨
在现代Web应用程序中,WebSocket已经成为实时双向通信的重要组件。而Shiro作为一个强大的Java安全框架,用于处理身份验证、授权和会话管理。本文将探讨如何通过WebSocket与Shiro集成,实现认证信息的传递,并关注在这一过程中确保安全…...

QT 实现自动生成小学两位数加减法算式
小学生加减法训练 QT实现–自动生成两位数加减法算式,并输出txt文件 可以copy到word文件,设置适当字体大小和行间距,带回家给娃做做题 void MainWindow::test(int answerMax, int count) {// 创建一个随机数生成器QRandomGenerator *gener…...

小程序学习-20
建议每次构建npm之前都先删除miniprogram_npm...

面试题-【消息队列】
消息队列 问题1 如何进行消息队列的技术选型优点解耦 (pub/sub模型)异步(异步接口性能优化)削峰 使用消息队列的缺点几种消息队列的特性 问题2 引入消息队列之后该如何保证其高可用性RabbitMQ的高可用kafka高可用 问题3 在消息队列…...

【江科大】STM32:I2C通信外设(硬件)
在将2C通信外设之前,我们先捋一捋,串口的相关特点来和I2C进行一个对北比。 首先: 1,大部分单片机,设计的PCB板均带有串口通信的引脚(也就是通信基本都借助硬件收发器来实现) 2.对于串口的异步时序ÿ…...
【机器学习300问】15、什么是逻辑回归模型?
一、逻辑回归模型是为了解决什么问题? 逻辑回归(Logistic Regression)是一种广义线性回归分析模型,尤其适用于解决二分类问题(输出为两个类别)。 (1)二分类举例 邮件过滤ÿ…...

C#调用C动态链接库
前言 已经没写过博客好久了,上一篇还是1年半前写的LTE Gold序列学习笔记,因为工作是做通信协议的,然后因为大学时没好好学习专业课,现在理论还不扎实,不敢瞎写; 因为工作原因,经常需要分析一些字…...

前端实现转盘抽奖 - 使用 lucky-canvas 插件
目录 需求背景需求实现实现过程图片示意实现代码 页面效果lucky-canvas 插件官方文档 需求背景 要求实现转盘转动抽奖的功能: 只有正确率大于等于 80% 才可以进行抽奖;“谢谢参与”概率为 90%,“恭喜中奖”概率为 10%; 需求实现 实…...
2024.1.23力扣每日一题——最长交替子数组
2024.1.23 题目来源我的题解方法一 枚举 题目来源 力扣每日一题;题序:2765 我的题解 方法一 枚举 每次都以两个相邻作为满足要求的循环数据,并且以一个布尔变量控制循环的位置 时间复杂度:O(n) 空间复杂度:O(1) pub…...

C语言王道练习题第七周两题
第一题 Description 输入一个学生的学号,姓名,性别,用结构体存储,通过 scanf 读取后,然后再 通过 printf 打印输出 Input 学号,姓名,性别,例如输入 101 xiongda m Output 输出…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...

day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...