李维亮_前端开发攻城狮 - admin
type: channel
link: https://www.liweiliang.com/author/1/
description: admin
items: vue 给动态的component增加过度动画
items: nodejs v24 Error: No such module: http_parser
items: vue LogicFlow 流程图基础配置
items: element的tree树形菜单回显、父级设置半选状态
items: ElementUI 中 Table expend嵌套另一个子Table，fixed+嵌套多选实现
items: 解决elementui中el-radio或el-cascader报错：Blocked aria-hidden on an element because its descendant retained focus.
items: 一些有意思的package
items: java 学习笔记
items: vue与flutter交互——vue
items: 双击事件（dblclick）时,不触发鼠标按下(mousedown) 动作事件

vue 给动态的component增加过度动画
type: item
date: 2026-02-11T14:59:00+08:00
description: 过渡的类名在进入/离开的过渡中，会有 6 个 class 切换。1、v-enter：定义进入过渡的开始状态。在元素被插入之前生效，在元素被插入之后的下一帧移除。2、v-enter-active：定义进入过渡生效时的状态。在整个进入过渡的阶段中应用，在元素被插入之前生效，在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间，延迟和曲线函数。3、v-enter-to：2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除)，在过渡/动画完成之后移除。4、v-leave：定义离开过渡的开始状态。在离开过渡被触发时立刻生效，下一帧被移除。5、v-leave-active：定义离开过渡生效时的状态。在整个离开过渡的阶段中应用，在离开过渡被触发时立刻生效，在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间，延迟和曲线函数。6、v-leave-to：2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除)，在过渡/动画完成之后移除。自定义过渡的类名我们可以通过以下 attribute 来自定义过渡类名：enter-classenter-active-classenter-to-class (2.1.8+)leave-classleave-active-classleave-to-class (2.1.8+)纯class过渡deom<transition name="module-fade" mode="out-in"> <component ref="activeModule" :is="activeModule"></component> </transition> 在<transition>中切换的类名来说需要注意：如果你使用了 ，那么 v-enter 会替换为 my-transition-enter。对应css过度动画.module-fade-enter-active, .module-fade-leave-active { transition: all 1s; } .module-fade-enter, .module-fade-leave-to { opacity: 0; transform: translateY(30px); } JavaScript 钩子<transition name="module-fade" mode="out-in" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter" @enter-cancelled="enterCancelled" @before-leave="beforeLeave" @leave="leave" @after-leave="afterLeave" @leave-cancelled="leaveCancelled" > <component ref="activeModule" :is="activeModule"></component> </transition> 对应钩子的方法：// -------- // 进入中 // -------- beforeEnter (el) { console.log('1 beforeEnter') }, // 回调函数 done 是可选的 enter (el, done) { console.log('2 enter') done() }, afterEnter (el) { console.log('3 afterEnter') }, enterCancelled: function (el) { // ... }, // -------- // 离开时 // -------- beforeLeave (el) { this.$refs['activeModule'].handleSave(); console.log('4 beforeLeave') }, // 当与 CSS 结合使用时 // 回调函数 done 是可选的 leave (el, done) { console.log('5 leave') done() }, afterLeave (el) { console.log('6 afterLeave') }, // leaveCancelled 只用于 v-show 中 leaveCancelled: function (el) { // ... } 这些钩子函数可以结合 CSS transitions/animations 使用，也可以单独使用。enter (el) { el.style.opacity…

nodejs v24 Error: No such module: http_parser
type: item
date: 2026-01-07T18:01:31+08:00
description: 最近跑了个老项目由于node版本太高启动的时候报如下错误对应报错的文件C:\code\siemens\bsceba\node_modules\http-deceiver\lib\deceiver.js主要问题 process.binding('http_parser') 是 Node已弃用。解决方法：HTTPParser = process.binding('http_parser').HTTPParser; 改成：HTTPParser = require('http-parser-js').HTTPParser; 兼容修改成如下：try { // 尝试使用原生绑定 HTTPParser = process.binding('http_parser').HTTPParser; } catch (e) { // 降级到 JavaScript 实现 HTTPParser = require('http-parser-js').HTTPParser; }

vue LogicFlow 流程图基础配置
type: item
date: 2026-01-06T17:35:00+08:00
description: LogicFlow 配置项：LogicFlow 流程图上所有的节点实例操作以及事件new LogicFlow()初始化的详情 点击这里跳转官方说明 图片显示demo在文章底部用到的依赖包 "@logicflow/core": "^2.1.7", "@logicflow/extension": "^2.1.9", "@logicflow/layout": "^2.0.7", LogicFlow apinew LogicFlow 初始化基础DEMO CODEthis.lf = new LogicFlow({ container: this.$refs.container, grid: true, // 等同于默认属性如下 // grid: { // size: 20, // 设置网格大小 // visible: true, // 设置是否可见，若设置为false则不显示网格线但是仍然保留size栅格的效果 // type: "dot", // 设置网格类型，目前支持 dot 点状和 mesh 线状两种 // config: { // color: "#ababab", // 设置网格的颜色 // thickness: 1, // 设置网格线的宽度 // }, // }, keyboard: { enabled: true, }, // edgeTextDraggable: true, // adjustEdgeStartAndEnd: true, edgeType: 'bezier', // idGenerator(type) { // return type + '_' + Math.random(); // }, }); render渲染图数据的时候可以增加初始化数据renderData是在data中配置的默认初始化数据，可以不填this.lf.render(this.renderData); LogicFlow 事件文档接口 外部拖入节点添加时触发demothis.lf.on("node:dnd-add", (data) => { // 拖拽进入面板内执行 console.log("node:dnd-add", data) }); 基于node:click事件输出的API各个模块默认初始化方法LogicFlow 构造函数graphModel 画布数据属性nodeModel 节点数据属性graphModel 事件transformModel 控制画布的放大、缩小、平移editConfigModel 控制页面编辑状态this.lf.on("node:click", (data) => { console.log("node:click", data) const {lf} = this; let {id} = data.data; // 获取节点的model console.log("getNodeModelById", lf.getNodeModelById(id)) // 获取节点的model数据 console.log("getNodeDataById", lf.getNodeDataById(id)) // 获取流程绘图数据 console.log("getGraphData", lf.getGraphData()) // 获取流程绘图原始数据 console.log("getGraphRawData", lf.getGraphRawData()) // 获取指定区域内的所有元素，此区域必须是 DOM 层。 console.log("getAreaElement", lf.getAreaElement([100, 100], [200, 200])) console.log('========LogicFlow==================') console.log("lf", lf) console.log('========画布数据属性=================') const graphModel = lf.graphModel; console.log("graphModel", graphModel) console.log("graphModel", graphModel.height) console.log('========节点数据属性=================') const nodeModel = lf.getNodeModelById(id); console.log("nodeModel", nodeModel) nodeModel.updateText("hello world"); console.log('========事件====================…

element的tree树形菜单回显、父级设置半选状态
type: item
date: 2025-06-10T17:03:00+08:00
description: 主要代码： keyList.forEach(key => { const node = this.$refs.weiTree.getNode(key); console.log(node.isLeaf) if (node.isLeaf) { this.$refs.weiTree.setChecked(node, true); } }); 完整demo <el-dialog title="tree" class="bp-dialog" :visible.sync="treeVisible" width="850px" append-to-body :close-on-click-modal="false"> {{ item.title }} <el-tree ref="weiTree" :data="treeData" :props="defaultProps" show-checkbox node-key="code" default-expand-all :expand-on-click-node="false"> <span v-if="node.label.length<28">{{ node.label }} <el-tooltip v-else placement="top" effect="light"> {{ node.label }} {{ node.label }} </el-tooltip> <el-image v-if="/.(png|jpg|jpeg)$/.test(item.dfsPath)" :src="item.dfsPath" :preview-src-list="[item.dfsPath]"> </el-image> 文件 <el-tag v-if="!data.notCheck">检查</el-tag> <el-tag v-else type="success">只读</el-tag> <el-tag v-if="[1,2].includes(data.checkResultType)"> {{ checkResultTypeObj[data.checkResultType] }} </el-tag> <el-tag v-else type="succcess"> {{ checkResultTypeObj[data.checkResultType] }} </el-tag> {{ data.sort }} </el-tree> <el-button type="primary" @click="handleInit">初始化</el-button> <el-button type="primary" @click="handleSubmit">确定</el-button> <el-button @click="handleCancel">取消</el-button> </el-dialog>

ElementUI 中 Table expend嵌套另一个子Table，fixed+嵌套多选实现
type: item
date: 2025-04-28T17:28:00+08:00
description: 比较忙，直接贴代码 <el-button size="mini" @click="handleExpand" class="bp-primary-plain" type="primary" plain>一键展开 </el-button> <el-button size="mini" @click="handlePutAway" class="bp-primary-plain" type="primary" plain>一键收起 </el-button> <el-table ref="tableItemRef" class="bp-table" border :data="tableData"> <el-table-column width="50" fixed="left" align="center"> <el-checkbox v-model="globelCheckedAll" @change="clickCheckAll(scope)" :indeterminate="isIndeterminateAll"></el-checkbox> <el-checkbox v-model="scope.row.isChecked" :indeterminate="scope.row.isIndeterminate" @change="handleSelectionChange(scope.row)"></el-checkbox> </el-table-column> <el-table-column align="center" fixed="left" type="expand"> <el-table class="bp-table" :data="props.row.children" row-key="id"> <el-table-column width="97" align="center"> <el-checkbox v-model="props.row.isChecked" :indeterminate="props.row.isIndeterminate" @change="handleSelectionChange(props.row)"></el-checkbox> <el-checkbox v-model="scope.row.isChecked" @change="clickCheckItemFn(props.row, scope.row)"></el-checkbox> </el-table-column> <el-table-column align="center" prop="" min-width="150" label="" show-overflow-tooltip/> <el-table-column align="center" prop="itemFunction" width="150" label="工步" show-overflow-tooltip/> <el-table-column align="center" prop="potentialFailureMode" min-width="150" label="潜在失效模式" show-overflow-tooltip/> <el-table-column align="center" prop="potentialEffectOfFailure" min-width="150" label="潜在失效影响" show-overflow-tooltip/> <el-table-column align="center" prop="sev" label="严重度" min-width="70" show-overflow-tooltip/> <el-table-column align="center" prop="potentialCauseMechanismOfFailure" min-width="120" label="失效起因/机理" show-overflow-tooltip/> <el-table-column align="center" prop="occur" label="频度" min-width="60" show-overflow-tooltip/> <el-table-column align="center" prop="currentDesignControls" min-width="180" label="现行过程控制" show-overflow-tooltip/> <el-table-column align="center" prop="det" label="探测度" min-w…

解决elementui中el-radio或el-cascader报错：Blocked aria-hidden on an element because its descendant retained focus.
type: item
date: 2025-01-07T15:01:00+08:00
description: 在使用elment中el-radio的时候发现控制台报错，Blocked aria-hidden on an element because its descendant retained focus. The focus must not be hidden from assistive technology users. Avoid using aria-hidden on a focused element or its ancestor. Consider using the inert attribute instead, which will also prevent focus. For more details, see the aria-hidden section of the WAI-ARIA specification at https://w3c.github.io/aria/#aria-hidden. Element with focus: input Ancestor with aria-hidden: ​ 解决方案一：::v-deep input[aria-hidden="true"] { display: none !important; } ::v-deep .el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) .el-radio__inner { box-shadow: none !important; } 解决方案二：自定义指令 Vue.directive('removeAriaHidden', { bind(el, binding) { const ariaEls = el.querySelectorAll('.el-radio__original') ariaEls.forEach((item) => { item.removeAttribute('aria-hidden') }) } }) 页面使用<el-radio-group v-model="tableRadio" class="new_radio" @change="changeRadio" v-removeAriaHidden></el-radio-group>

一些有意思的package
type: item
date: 2024-05-11T16:55:16+08:00
description: viser-vue可视化插件vue-cropper一个优雅的图片裁剪插件vue-clipboard2复制粘贴插件

java 学习笔记
type: item
date: 2023-11-28T17:38:00+08:00
description: jdk 推荐11.xjava -version第一个程序 hello Worldpublic class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } int 用来表示一个整数，取值范围在-2^31 ~ 2^31-1,计算出来是-2147483648 ~ 2147473647关键字 public class static void int 表达式（expression）： java 中最基本的一个运算，比如一个加法运算表达式。 1+2是一个表达式 a+b 也是一个表达式语句（statement）: 类似于平时说话时的一句话，有表达式组成，以；结束。int a=3; y=a+9; System.out.println(y); 都是语句。代码块： 一对大括号括起来的就是一个代码块。整数类型：byte 占用1个byte,值域是-128~127short 占用2个byte,值域是-32768~32767int 占用4个byte,值域是-2147483648 ~ 2147483547long 展鸿8个byte,值域是-9223372036854774808~9223372036854774807浮点（小数）类型float占用4个byte,有精度，值域复杂+-340282346638528859811704183484516925440double精度是float的两倍，占用8个byte. java中浮点数缺省是double类型符号位布尔类型和字符串类型boolean 占用1个byte，值域true,false。char 占用2个byte,值域是所有的字符串。整数类型相除只能是整数位移运算符>>: 符号位不动，其余位右移，符号位后边正数补0，负数补1.又称带符号右移。 >>>: 符号位一起右移，左边补0，又称无符号右移 <<: 左移，右边补0.左移没有带符号位一说，因为符号位在最左侧

vue与flutter交互——vue
type: item
date: 2023-10-27T17:38:08+08:00
description: 一. vue向flutter发送消息定义一个方法，在方法内部使用如下语句即可。注意‘MessageDeal’方法名要与flutter端定义的方法名一致MessageDeal.postMessage('4') // 向flutter发送数字4 二. vue接收来自flutter的消息注意‘flutterCallJsMethod’方法名要与flutter端定义的方法名一致暴露方法名// 在挂载时将方法名挂载到window上，把方法名暴露给flutter mounted() { window.flutterCallJsMethod = this.flutterCallJsMethod } 2.在methods中定义同名方法flutterCallJsMethod(message) { // message是flutter发送来的消息 if (message==='back') { this.showSharePage = false } }

双击事件（dblclick）时,不触发鼠标按下(mousedown) 动作事件
type: item
date: 2023-10-20T11:42:29+08:00
description: 在一个dom节点的事件绑定中，如果同时绑定了dblclick和mousedown那么想要执行双击事件(dblclick)时能就会触发两次mousedown事件。在说mousedown就不得不说下 click事件click事件指的是，用户在同一个位置先完成mousedown动作，再完成mouseup动作。因此，触发顺序是，mousedown首先触发，mouseup接着触发，click最后触发。dblclick事件则会在mousedown、mouseup、click之后触发。mouseover事件和mouseenter事件，都是鼠标进入一个节点时触发。两者的区别是，mouseenter事件只触发一次，而只要鼠标在节点内部移动，mouseover事件会在子节点上触发多次。在单击的时候（也就是鼠标按下的时候）不会执行双击，但是双击的时候会执行两次单击再执行双击事件。解决的思路：要想双击时不执行单击事件，就使用定时器清除掉两个单击事件，留下一个双击事件。解决思路，使用setTimeout//data定义变量 data(){ return{ timeOut: null } } {{ item.name }} handleMousedown(event, node, index) { clearTimeout(this.timeOut); // 清除第一个鼠标单击按下事件 this.timeOut = setTimeout(() => { console.log(event.target, 'handleMousedown dom'); console.log('handleMousedown', event.offsetX, event.clientX); }, 200) }, handleDblclick(event, item) { clearTimeout(this.timeOut) console.log(event.target, 'handleDblclick'); }, 关于实现原理 在setTimeout 中的 time=200，大家知道js的事件循环机制，点击事件会添加一个任务队列。time=0， 也会添加一个任务队列。那么time=0与time=200有什么区别呢？因为第一次单击事件后，主线程没有任何任务，就会立马执行这个单击事件的任务。待第二次单击的时候，假设距离第一次单击事件是150ms, 如果你的定时器小于150ms, 那么第一次的任务队列就会执行完。要想不执行第一次的任务队列，那么定时器时间间隔就必须大于两次单击的时间间隔了。这样才能清除第一次的单击事件，所以，这个200是酌情值，大于间隔就行。第一次单击任务不执行了，是被定时器延时，然后第二次点击的时候给清除了。那么第二次点击事件呢？在两次单击之后，会立马执行一个双击事件，双击事件的一开头就把这个第二次点击事件给清除了。至此两个单击时间全部被清除了。