日常遇到的小问题汇总, 内容小篇幅少的就全放这里了,
内容多的会在Vue专栏单独分享~
目录
【Q】 el-form-item值为 null 或 undefined显示““
【Q】dialog内组件数据刷新总是延迟慢一拍
问题背景描述
解决方案
代码简单模拟
JS
【Q】el-input 不能输入的解决办法
方法1:标签嵌套太深
方法2:使用了 template 作为 el-input 的父标签
方法3:v-model
【Q】npm ERR A complete log of this run can be found in: npm ERR
【Q】el-tabs表格右下角按钮被遮挡
【Q】this.$refs.xxx 报错undefined解决办法
【Q】this.$refs[‘form’].resetFields()
【Q】this.defParams = {...this.params}
【Q】Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value
【Q】数据还没获取就已渲染页面
【Q】页面跳转后没有重新请求接口
a、updated刷新组件内的方法更新数据
b、监听路由去请求方法更新数据
【Q】调用子组件提示this.$refs["xxxRef"].xx() underfined
a、首次渲染不调用
b、加载完数据再请求
【Q】Error in callback for watcher "$route": "TypeError: this.$refs.xxxRef is undefined"
【Q】 el-form-item值为 null 或 undefined显示““
可以在 `el-form-item` 中使用表达式,使用 `v-if` 指令判断当前表单项的值是否为 null 或 undefined,如果为 null 或 undefined,就显示空字符串。
例如:
<template>
<el-form ref="form" :model="formData" :rules="formRules" label-position="left">
<el-form-item label="姓名" :label-width="labelWidth">
<el-input v-model="formData.name" clearable v-if="formData.name !== null && formData.name !== undefined"></el-input>
<span v-else> </span>
</el-form-item>
<el-form-item label="性别" :label-width="labelWidth">
<el-select v-model="formData.gender" clearable v-if="formData.gender !== null && formData.gender !== undefined">
<el-option label="男" value="male"></el-option>
<el-option label="女" value="female"></el-option>
</el-select>
<span v-else> </span>
</el-form-item>
<el-form-item label="年龄" :label-width="labelWidth">
<el-input type="number" v-model.number="formData.age" clearable v-if="formData.age !== null && formData.age !== undefined"></el-input>
<span v-else> </span>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
formData: {
name: null,
gender: null,
age: null
},
formRules: {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' }
],
gender: [
{ required: true, message: '请选择性别', trigger: 'change' }
],
age: [
{ required: true, message: '请输入年龄', trigger: 'blur' },
{
validator: (rule, value, callback) => {
if (value < 0) {
callback(new Error('年龄不能小于0岁'));
} else {
callback();
}
},
trigger: 'blur'
}
]
},
labelWidth: '120px'
};
}
};
</script>
在上面的代码中,我们在每个表单项中使用 `v-if` 判断当前表单项的值是否为 null 或 undefined,如果为 null 或 undefined,则将当前表单项的值设置为空字符串。这样就可以将值为 null 或 undefined 的表单项显示为空。我们使用 ` ` 来占位,使表单外观更美观。
注意:如果在 `el-form-item` 的 `label` 属性和 `v-if` 判断条件中都使用了表达式,那么应该将所有表达式放在一对花括号中。例如:
<el-form-item :label="'年龄:' + labelSuffix" :label-width="labelWidth" v-if="formData.age !== null && formData.age !== undefined">
<el-input type="number" v-model.number="formData.age" clearable></el-input>
</el-form-item>
<span v-else> </span>
在上面的代码中,我们在 `el-form-item` 的 `label` 属性和 `v-if` 判断条件中都使用了表达式,因此应该将它们放在一对花括号中。
【Q】dialog内组件数据刷新总是延迟慢一拍
问题背景描述
用dialog做了一个一个新增功能,有个多层复选框,关联一个文本域。
选中复选框时,文本域刷新,但是总是慢一拍。
:destroy-on-close="true", v-if, $nextTick,用个遍了,都不好使。
同样的功能在编辑页面就是正常的,区别仅仅是因为新增是dialog子页面,
由此入手排查问题,发现竟然是...
解决方案
代码简单模拟
源码不便展出,凑合看解决问题就好~
<el-dialog :destroy-on-close="true" title="国服李白" :visible.sync="dialogEdit">
<span>这是一段信息</span>
<flow-chart :dialogNodes="dialogNodes" :key="timer0"></flow-chart>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
组件上添加 :key="timer1"
data 中定义 timer0
为 ''
在获取数据成功后 将 timer0 赋值为 this.timer1 = new Date().getTime()
JS
const res = await ApiUserManage.execDiagram(param)
if (res.success){
this.timer0 = new Date().getTime()
this.dialogNodes = res.result.nodes
【Q】el-input 不能输入的解决办法
输入框动态填充值,但是填充后不能编辑了,
就像是被禁止了一样, 就很无语...
查了下资料, v-model填写了, 也没有templete标签嵌套
最终方法一即可解决问题...
方法1:标签嵌套太深
如果标签嵌套太深,会导致无法获取到 DOM,这是我们需要 $forceUpdate() 强制刷新,才可获取
<el-input type='text' v-model='value' @change='change()'></el-input>
data(){
return {
value:'',
}
}
change(){
this.$forceUpdate(); //强制刷新
}
方法2:使用了 template 作为 el-input 的父标签
这种情况需要在 template 中添加 slot-scope 属性,
<template slot-scope="scope">
方法3:v-model
el-input 中没有 v-model
【Q】npm ERR A complete log of this run can be found in: npm ERR
总是提示这个错误,以为是nodejs版本v16太高的问题,换成v12后,还是不行...
npm i后总是提示这个
nnpm ERR! Unexpected token '.'
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\admin\AppData\Local\npm-cache\_logs\2022-08-29T15_07_28_136Z-debug-0.log
后来发现管理员打开VSCode就好了...
【Q】el-tabs表格右下角按钮被遮挡
该列设置了 fixed="right", 去掉 fixed="right"即可
常规方法: 看下是否是下方组件margin设置过大
【Q】this.$refs.xxx 报错undefined解决办法
【Vue】this.$refs.xxx 报错undefined解决办法
【Q】this.$refs[‘form’].resetFields()
要想this.$refs[‘form’].resetFields()方法有效,必须配置el-form :model 属性和el-form-item中的prop属性才可以
this.$refs[‘form’].resetFields()这个做法其实是重置表单到初始值,不是清空表单,当表单第一次在页面中渲染时所用的数据就是初始数据,
【Q】this.defParams = {...this.params}
this.params=this.defParam;初始化默认参数, vue2会把内存地址也复制过去,当params里面的值修改后, this.defParams也会相应改动,所以要先复制一份再赋值给this.params
this.defParams = {...this.params},
这样它们之间的值才不会相互影响, 不过这在Vue3里面都已经解决了
【Q】Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value
改动了子组件中引用的父组件的变量,也就是props中的数据
中组件props中的数据只能单向流动,即只能从父组件通过组件的DOM属性attribute传递props给子组件,子组件只能被动接收父组件传递过来的数据,并且在子组件中,不能修改由父组件传来的props数据。
props:{
cid:{
type:String,
},
},
methods: {
//父组件刷新子组件数据1
flush(cid){
const params = {cid:cid};
this.getData(params);
},
//父组件刷新子组件数据2, 这种情况就会出现上述问题
flush(cid){
this.cid= cid;
const params = {cid:this.cid};
this.getData(params);
},
【Q】数据还没获取就已渲染页面
简单举例
...
v-if="loading"
...
data(){
return{
loading:false,
}
}
created(){
this.init();
},
methods: {
init() {
this.getList();
},
getList() {
queryListData(this.params)
.then((res) => {
if(res.code==='200'){
...
this.loading = true;
}
})
.finally(() => {
...
});
},
}
【Q】页面跳转后没有重新请求接口
a、updated刷新组件内的方法更新数据
简单举例
...
ref="demoRef"
...
created() {},
mounted() {},
updated() {
this.init();
},
methods: {
init() {
this.$refs["demoRef"].flush();
}
},
}
b、监听路由去请求方法更新数据
简单举例
...
ref="demoRef"
...
created() {},
mounted() {},
updated() {},
watch: {
$route(a, b) {
if (a.path != b.path) {
this.init();
}
},
//-----或-----
$route(-) {
this.init();
},
},
methods: {
init() {
this.detail();
...
}
},
}
【Q】调用子组件提示this.$refs["xxxRef"].xx() underfined
a、首次渲染不调用
b、加载完数据再请求
简单举例
...
ref="demoRef"
...
data() {
return {
loadingData:false,
},
}
created() {
this.init();
},
mounted() {},
updated() {
if(loadingData){
this.$refs["demoRef"].flush();
}
},
methods: {
init() {
queryListData(this.params)
.then((res) => {
...
this.loadingData= true;
});
}
},
}
【Q】Error in callback for watcher "$route": "TypeError: this.$refs.xxxRef is undefined"
父页面监控路由变动时刷新子组件提示, 这里是同一个页面路由参数改变,
Error in callback for watcher "$route": "TypeError: this.$refs.tableOneRef is undefined"
困扰许久, this.nextTick(){}等等都不好使, 原因是在Vue中,当路由发生变化时,组件的实例会被销毁然后重新创建。因此,在路由切换后,组件的this上下文会发生改变。
当你监听路由变化时,如果在回调函数中使用了this关键字,它将指向新创建的组件实例,而不是之前的组件实例。这意味着你无法直接访问之前组件实例中的数据和方法。
为了解决这个问题,你可以在监听路由变化时,将需要保留的数据和方法保存到其他变量中,或者使用Vue提供的beforeRouteUpdate导航守卫来处理组件的更新逻辑。
beforeRouteUpdate(to, from, next) {
// 保存需要保留的数据和方法
const preservedData = this.data;
const preservedMethod = this.method;
// 执行路由变化前的逻辑
// ...
// 调用next()继续路由更新
next();
// 在路由更新后恢复数据和方法
this.data = preservedData;
this.method = preservedMethod;
}
依然不好使哈
这里说下最后的解决思路:
定义一个状态isReloadChild:true
监控路由变化时, 先false, 然后更改状态为true, 需要控制的组件v-if控制
简化代码如下
this.isReloadChild = false;
setTimeout(() => {
this.isReloadChild = true;
}, 0);
有用请点赞,养成良好习惯!
疑问、交流、鼓励请留言!