Error in beforeDestroy hook: “Error: [ElementForm]unpected width “
使用 element 的 form 时候报错:
vue.runtime.esm.js:3065 Error: [ElementForm]unpected width
at VueComponent.getLabelWidthIndex (element-ui.common.js:23268:1)
at VueComponent.deregisterLabelWidth (element-ui.common.js:23281:1)
at VueComponent.updateLabelWidth (element-ui.common.js:23483:1)
at VueComponent.beforeDestroy (element-ui.common.js:23510:1)
原因:el-form-item 的 label 组件有个 beforeDestroy 生命同期,el-form 组件的 display: none 获取labelWidth 有问题导致的
解决办法:el-form 上加 v-if,用 el-dialog 的 :visible.sync="dialogVisible" 的话,也加 v-if="dialogVisible"
由于 el-form 标签 label-width 设为 "auto" ,而 el-form-item 会继承这个属性,在某种情况下页面销毁时获取这个 el-form-item 的 label 的 width 为 'auto',然后用 parseFloat 转换后为 NaN 就报错了。
这个方法是在 element-ui 共通方法里写的 node_modules\element-ui\lib\element-ui.common.js
或是
computedWidth 为 “auto" 或 "" 都会返回 NaN
网上说是因为代码中使用了 v-show 以及 el-form 标签中使用了label-width="auto",导致离开页面后产生报错
解决方法一:label-width 换成固定值
解决方法二: v-show 换成 v-if
但我的原因是因为使用了 keep-alive 用下面代码可以再现出来
src\router\index.js
import Vue from 'vue';
import Router from 'vue-router';
import Home from '../views/Home.vue';
import Layout from '../views/management/Layout.vue';Vue.use(Router);const router = new Router({mode: 'history',routes: [{path: '/',name: 'home',component: Home},{path: '/management',component: Layout,children: [{path: '/management/audit',component: () => import("@/views/management/audit/index.vue"),name: "memberAudit",},{path: '/management/detail',component: () => import("@/views/management/detail/index.vue"),name: "memberAudit",}]}]
});export default router;
src\views\management\Layout.vue
<template><div class="main"><el-scrollbar><div class="left"><el-menudefault-active="$route.path"background-color="#545c64"text-color="#fff"router><el-menu-item :router="true" index="/management/audit"><i class="el-icon-menu"></i><span slot="title">审核</span></el-menu-item><el-menu-item :router="true" index="/management/detail?label=menu"><i class="el-icon-menu"></i><span slot="title">详情</span></el-menu-item><el-menu-item :router="true" index="/management/about"><i class="el-icon-menu"></i><span slot="title">About</span></el-menu-item></el-menu></div><div class="right"><keep-alive><router-view /></keep-alive></div></el-scrollbar></div>
</template><style lang="scss">
.left {float: left;width: 200px;
}
.right {float: left;width: 80%;
}
</style>
src\views\management\audit\index.vue
<template><div class="hello1" style="margin-top: 100px">audit<span @click="detail">click</span></div>
</template><script>
export default {methods: {detail() {this.$router.push("/management/detail?label=测试");},},
};
</script>
src\views\management\detail\index.vue
<template><div><el-form:model="ruleForm"status-iconref="ruleForm"label-width="auto"class="demo-ruleForm"><el-form-item label="年龄" prop="age"><el-input v-model.number="ruleForm.age"></el-input></el-form-item><el-form-item :label="$route.query.label" prop="name"><el-input v-model.number="ruleForm.name"></el-input></el-form-item><el-form-item><el-button @click="resetForm()">重置</el-button></el-form-item></el-form></div>
</template>
<script>
export default {name: "Home",components: {},data() {return {ruleForm: {age: "",name: "",},};},methods: {resetForm() {this.$router.push("/management/audit");},},
};
</script>
点击详情
点击重置
再点击 about
报错了,这里注意报错的主要写法
1、src\views\management\Layout.vue
使用 keep-alive
2、src\router\index.js
这里我没设置 about 页面路由,可能这样会触发 VueComponent.beforeDestroy
3、src\views\management\detail\index.vue
el-form-item 必须两个以上,并且其中一个的 label 使用动态值 :label="$route.query.label"
我的这种情况即使设置 label-width 为固定值也不行,因为最后页面消失,获取 label-width 为空
parseFloat(label-width) 为 NaN 就报错了
去掉 keep-alive 就不会报错
去掉后就不会走 'update' 分支,因为页面切换时因为有个 label 是动态赋值的,所以即使页面销毁因为是 keep-alive 且 label 动态值变没了,导致 el-form 认为是 label 值 update ,走的这个方法,而这个时候页面找不到元素, label-width 就是空,所以报错了。
其实是因为 el-form-item 的 label 设为响应式的了,而且在页面销毁时响应式值还更新,可以换一种响应式使它在页面销毁时不更新值
<el-form-item :label="qLabel" prop="name">
created() {
this.qLabel = this.$route.query.label;
},
<template><div><el-form:model="ruleForm"status-iconref="ruleForm"label-width="auto"class="demo-ruleForm"><el-form-item label="年龄" prop="age"><el-input v-model.number="ruleForm.age"></el-input></el-form-item><el-form-item :label="qLabel" prop="name"><el-input v-model.number="ruleForm.name"></el-input></el-form-item><el-form-item><el-button @click="resetForm()">重置</el-button></el-form-item></el-form></div>
</template>
<script>
export default {name: "Home",components: {},created() {this.qLabel = this.$route.query.label;},data() {return {qLabel: "",ruleForm: {age: "",name: "",},};},methods: {resetForm() {this.$router.push("/management/audit");},},
};
</script>
这么写不会报错,算是完美避开了这个 bug
但是公司的是另一个问题,是用 el-dialog 组件包裹 el-form 也出这个 bug了
<el-dialogtitle="提示":visible.sync="dialogVisible"width="30%":before-close="handleClose":destroy-on-close="true"><el-form:model="ruleForm"status-iconref="ruleForm"label-width="auto"class="demo-ruleForm"><el-form-item :span="24" label="年龄" prop="age"><el-input v-model.number="ruleForm.age"></el-input></el-form-item><el-form-item><el-button @click="resetForm()">重置</el-button></el-form-item></el-form></el-dialog>resetForm() {this.dialogVisible = false;this.$router.push("/management/detail");},
查看源码仔细分析发现,虽然报错在 element-ui.common.js 但其实报错是在源码里 label-wrap.vue
<script>export default {props: {isAutoWidth: Boolean,updateAll: Boolean},inject: ['elForm', 'elFormItem'],render() {const slots = this.$slots.default;if (!slots) return null;if (this.isAutoWidth) {const autoLabelWidth = this.elForm.autoLabelWidth;const style = {};if (autoLabelWidth && autoLabelWidth !== 'auto') {const marginLeft = parseInt(autoLabelWidth, 10) - this.computedWidth;if (marginLeft) {style.marginLeft = marginLeft + 'px';}}return (<div class="el-form-item__label-wrap" style={style}>{ slots }</div>);} else {return slots[0];}},methods: {getLabelWidth() {if (this.$el && this.$el.firstElementChild) {const computedWidth = window.getComputedStyle(this.$el.firstElementChild).width;return Math.ceil(parseFloat(computedWidth));} else {return 0;}},updateLabelWidth(action = 'update') {if (this.$slots.default && this.isAutoWidth && this.$el.firstElementChild) {if (action === 'update') {this.computedWidth = this.getLabelWidth();} else if (action === 'remove') {this.elForm.deregisterLabelWidth(this.computedWidth);}}}},watch: {computedWidth(val, oldVal) {if (this.updateAll) {this.elForm.registerLabelWidth(val, oldVal);this.elFormItem.updateComputedLabelWidth(val);}}},data() {return {computedWidth: 0};},mounted() {this.updateLabelWidth('update');},updated() {this.updateLabelWidth('update');},beforeDestroy() {this.updateLabelWidth('remove');}
};
</script>
因为 form-item 组件用了 label 组件,而 label 组件是用上面的 label-wrap 包裹的,所以 el-dialog 关闭并跳转到新页面时就调用了 label-wrap beforeDestroy生命周期函数,这个时候因为 el-dialog 是用的 v-show 所以 display 为 none,这个时候获取 label 的 width
if (this.$el && this.$el.firstElementChild) 这个判断条件是获取 label 标签因为用了 <keep-alive>,所以还是能找到的,但是window.getComputedStyle(this.$el.firstElementChild).width 获取的值就是 空或者 ’auto'
解决办法 v-show 改为 v-if 就是让 this.$el.firstElementChild 根本查询不到 label 标签,就不会走这个条件分支了,就不会报错了,对功能也没影响。
所以可以在 el-dialog 上加 v-if 和 visible 用一个变量即可,或是在 el-form 上加,或是 el-form-item上加 v-if 但是这种情况得所有 el-form-item 都加上
测试解决了
相关文章:

Error in beforeDestroy hook: “Error: [ElementForm]unpected width “
使用 element 的 form 时候报错: vue.runtime.esm.js:3065 Error: [ElementForm]unpected width at VueComponent.getLabelWidthIndex (element-ui.common.js:23268:1) at VueComponent.deregisterLabelWidth (element-ui.common.js:23281:1) at Vue…...
vscode包含工程文件路径
在 VSCode 中配置 includePath 以自动识别并包含上层目录及其所有子文件夹,需结合通配符和相对/绝对路径实现。以下是具体操作步骤及原理说明: 1. 使用通配符 ** 递归包含所有子目录 在 c_cpp_properties.json 的 includePath 中,${workspac…...

私有知识库 Coco AI 实战(七):摄入本地 PDF 文件
是否有些本地文件要检索?没问题。我们先对 PDF 类的文件进行处理,其他的文件往后稍。 Coco Server Token 创建一个 token 备用。 PDF_Reader 直接写个 python 程序解析 PDF 内容,上传到 Coco Server 就行了。还记得以前都是直接写入 Coco …...
GitLab 18.0 正式发布,15.0 将不再受技术支持,须升级【二】
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料: 极狐GitLab 官网极狐…...
NtfsLookupAttributeByName函数分析之和Scb->AttributeName的关系
第一部分: VOID FindFirstIndexEntry ( IN PIRP_CONTEXT IrpContext, IN PSCB Scb, IN PVOID Value, IN OUT PINDEX_CONTEXT IndexContext ) { 。。。。。。 // // Lookup the attribute record from the Scb. // if (!NtfsLookupAt…...
STM32H7系列USART驱动区别解析 stm32h7xx_hal_usart.c与stm32h7xx_ll_usart.c的区别?
在STM32H7系列中,stm32h7xx_hal_usart.c和stm32h7xx_ll_usart.c是ST提供的两种不同层次的USART驱动程序,主要区别在于设计理念、抽象层次和使用场景: 1. HAL库(Hardware Abstraction Layer) 文件:stm32h7x…...
网络原理 | TCP与UDP协议的区别以及回显服务器的实现
目录 TCP与UDP协议的区别 基于 UDP 协议实现回显服务器 UDP Socket 编程常用 Api UDP 服务器 UDP 客户端 基于 TCP 协议实现回显服务器 TCP Socket 编程常用 Api TCP 服务器 TCP 客户端 TCP 服务端常见的 bug 客户端发送数据后,没有响应 服务器仅支持…...
IP动态伪装开关
IP动态伪装开关 在OpenWrt系统中,IP动态伪装(IP Masquerading)是一种网络地址转换(NAT)技术,用于在私有网络和公共网络之间转换IP地址。它通常用于允许多个设备共享单个公共IP地址访问互联网。以下是关于O…...

【Unity3D】将自动生成的脚本包含到C#工程文件中
我们知道,在用C#开发中,通过vs编辑器新建的脚本,会自动包含到vs工程中,而通过外部创建,比如复制别的工程或代码创建的C#脚本不会包含到vs工程。 在我们的日常开发中,通常会自动创建C#脚本,特别…...
解决leetcode第3509题.最大化交错和为K的子序列乘积
3509.最大化交错和为K的子序列乘积 难度:困难 问题描述: 给你一个整数数组nums和两个整数k与limit,你的任务是找到一个非空的子序列,满足以下条件: 它的交错和等于k。 在乘积不超过limit的前提下,最大…...

【Python 深度学习】1D~3D iou计算
一维iou 二维 import numpy as npdef iou_1d(set_a, set_b):# 获得集合A和B的边界 x1, x2 set_ay1, y2 set_b# 计算交集的上下界low max(x1,y1)high - min(x2, y2)# 计算交集if high - low < 0:inter 0else:inter high - low# 计算并集union (x2 -x1) (y2 - y1) - in…...

java23
1.美化界面 添加背景图片 所以我们添加背景图片要放在后面添加 添加图片边框 绝对路径: 相对(模块)路径: 第一个是绝对路径,第二个是相对路径,但是斜杠的方向不对 总结: 2.图片移动 先实现KeyListener接口…...
嵌入式工程师常用软件
1、 Git Git 是公司常用的版本管理工具,人人都要会。在线的 git 教程可以参考菜鸟教程: https://www.runoob.com/git/git-tutorial.html 电子书教程请在搜索栏搜索: git Git 教程很多,常用的命令如下,这些命令可…...

LitCTF2025 WEB
星愿信箱 使用的是python,那么大概率是ssti注入 测试{{5*5}} 发现需要包含文字,那么添加文字 可以看到被waf过滤了,直接抓包查看参数上fenjing 可以看到这里是json格式,其实fenjing也是支持json格式的 https://github.com/Marv…...
Redisson WatchDog会一直续期吗?
取决于加锁的方式。 Lock 方法有2种形式,如果指定了leaseTime (且不为-1), 不会启用watchDog机制. 如果没有指定leaseTime, 则会启动watchDog机制,且会一直续期,除非线程宕调或者续期失败。 p…...

Linux 下VS Code 的使用
这里以创建helloworld 为例。 Step 0:准备工作: Install Visual Studio Code. Install the C extension for VS Code. You can install the C/C extension by searching for c in the Extensions view (CtrlShiftX). Step 1: 创建工作目录 helloworld࿰…...
Android开发namespace奇葩bug
Android开发namespace奇葩bug namespace "com.yibanxxx.yiban"buildFeatures {buildConfig true}namespace 对应你的module的清单下的package...
watchEffect
在处理复杂异步逻辑时,Vue 3 的 watchEffect 相比传统的 watch 具有以下优势: 1. 自动追踪依赖 watchEffect 会自动收集其回调中使用的所有响应式依赖,无需手动指定监听源: import { ref, watchEffect } from vue;const count …...

Qt 布局管理器的层级关系
1、HomeWidget.h头文件: #ifndef HOMEWIDGET_H #define HOMEWIDGET_H#include <QWidget> #include <QPushButton> #include <QVBoxLayout> #include <QHBoxLayout>class HomeWidget : public QWidget {Q_OBJECTpublic:HomeWidget(QWidget …...
Android 之 kotlin 语言学习笔记一
参考官方文档:https://developer.android.google.cn/kotlin/learn?hlzh-cn 1、变量声明 Kotlin 使用两个不同的关键字(即 val 和 var)来声明变量。 val 用于值从不更改的变量。使用 val 声明的变量无法重新赋值。var 用于值可以更改的变量…...

maven模块化开发
使用方法 将项目安装到本地仓库 mvn install 的作用 运行 mvn install 时,Maven 会执行项目的整个构建生命周期(包括 compile、test、package 等阶段),最终将构建的 artifact 安装到本地仓库(默认路径为 ~/.m2/repos…...
为什么要使用stream流
总的来说就是 它支持链式调用,方便 不会修改原始数据源,而是生成一个新的流或结果 中间操作不会立即执行,只有在终端操作触发时才会真正执行 注意事项 无状态操作:Stream 操作应该是无状态的,不要依赖外部变量的状…...
语义分割的image
假设图像的尺寸为 3x3,并且是 RGB 图像(有 3 个通道)。每个通道的像素值范围为 [0, 1],我们将构造一个 batch_size 2 的图像批次。 Image: tensor([[[[0.1347, 0.4583, 0.7102], # 第一张图像的红色通道[0.1774, 0.0328, 0.308…...

云原生安全之网络IP协议:从基础到实践指南
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 IP协议(Internet Protocol)是互联网通信的核心协议族之一,负责在设备间传递数据包。其核心特性包括&…...

C++——QT 文件操作类
QFile 概述 QFile是Qt框架中用于文件操作的类(位于QtCore模块),继承自 QIODevice,提供文件的读写、状态查询和路径管理功能。它与 QTextStream、QDataStream 配合使用,可简化文本和二进制数据的处理,并具备…...
【排错】kylinLinx环境python读json文件报错UTF-8 BOM
kylin Linux环境python读json文件报错UTF-8 BOM 报错描述: windows环境下,python代码读取json文件正常,但是sftp到linux环境下 报错信息: json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column …...

[spring] spring 框架、IOC和AOP思想
目录 传统Javaweb开发的困惑 loC、DI和AOP思想提出 Spring框架的诞生 传统Javaweb开发的困惑 问题一:层与层之间紧密耦合在了一起,接口与具体实现紧密耦合在了一起 解决思路:程序代码中不要手动new对象,第三方根据要求为程序提…...
LInux—shell编程
一、Shell 编程核心特性 解释型语言 无需编译,直接由 bash、sh 等解释器逐行执行。 类似 PHP 的解释执行,不同于 C 的编译型。 系统命令集成 可直接调用 Linux 命令(如 ls、grep、awk),实现系统管理自动化。 与 C/…...

尚硅谷redis7 37-39 redis持久化之AOF简介
37 redis持久化之AOF简介 AOF 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工…...

GitLab 备份所有仓库(自动克隆)
一、准备工作 1. 环境要求 已安装 Git(版本 2.10)本地磁盘空间充足(根据仓库总大小预估)已配置 SSH 密钥到 GitLab(推荐方式) 2. 获取 GitLab API 访问权限 登录 GitLab,点击右上角头像 → …...