最近在做国际化的功能,然后就发现各种问题,最开始是rules在国际化中不随着语言的变化而变化,为了解决这个问题开始踩坑……
vue.runtime.esm.js:619 [Vue warn]: Error in nextTick: "TypeError: Cannot read properties of undefined (reading 'clearValidate')"
found in
--->
at src/views/flowinn/device/index.vue
at src/layout/components/AppMain.vue
at src/layout/index.vue
at src/App.vue
warn @ vue.runtime.esm.js:619
vue.runtime.esm.js:1888 TypeError: Cannot read properties of undefined (reading 'clearValidate')
at VueComponent.eval (VM5890 deviceAdd.vue:136:32)
at Array.eval (vue.runtime.esm.js:1980:1)
at flushCallbacks (vue.runtime.esm.js:1906:1)
把this.$nextTick换成this.$forceUpdate即可解决。
使用了forceUpdate,如果是在引入的页面中使用了该方法,记得resetForm,不然弹出框重新打开后,那个错误的message还是在提示。
-------------------------以下是rules不同情况下的使用方法-------------------------------
在下面的几种情况中,都只用到了nextTick和forceUpdate方法,并没有使用resetFields方法。经过验证resetFields方法有问题,有时候会导致部分的input无法输入,切记不要使用。在网上搜索了一下发现有使用setTimeout方法的,那些基本是做赋值用的,这里还是不适用,经过测试完全没有效果。
这种情况下不需要国际化,只是一个简单的form表单验证,而且不是引入的页面或组件,就是一个完整的单一页面。这种情况下直接在data中定义自己的rules就可以实现功能。
data() {
return {
inputDisabled: true,
title:"",
addErrorMessage:"",
addOpen: false,
// 分组选项
queryGroupOptions: [],
// 用户选项
queryUserOptions: [],
// 表单参数
addForm: {
id:null,
devId:"",
ownerId:"",
name:"",
devDesc:"",
longitude:"",
latitude:"",
groupId:"",
},
rules: {
devId: [
{ required: true, message: '请输入用户账号', trigger: 'blur' }
],
}
};
},
需要实现国际化功能,但是不是引入的页面或组件,就是一个完整的单一页面。这种情况下需要借助nextTick方法来实现。在这种情况下,如果使用第一种写法,就会出现一个问题,就是你切换了不同的语言,这时候输入框的不填写时候的错误消息还是默认的中文的,不会随着语言的切换而切换。
export default {
name: "Device",
data() {
return {
inputDisabled: true,
title:"",
addErrorMessage:"",
addOpen: false,
// 分组选项
queryGroupOptions: [],
// 用户选项
queryUserOptions: [],
// 表单参数
addForm: {
id:null,
devId:"",
ownerId:"",
name:"",
devDesc:"",
longitude:"",
latitude:"",
groupId:"",
},
};
},
computed: {
rules() {
let rules = {
devId: [
{ required: true, message: this.$i18n.t('userInput')+this.$i18n.t('indexTablePrimaryKey'), trigger: 'blur' }
],
};
// 引入的页面必须使用forceUpdate, 单一的页面中可以直接使用nextTick
this.$nextTick( () => {
this.$refs['addForm'].clearValidate();
});
return rules;
}
},
}
需要实现国际化功能,是引入的页面或组件。这种情况下需要借助forceUpdate方法来实现。
这种方法下特别要注意,功能虽然实现了,但是出现了另一个问题。就是弹出框打开后,鼠标离开输入框,错误消息提示,然后关闭弹出框,再次打开弹出框的时候,那个错误消息还在,这时候需要调用resetForm来解决。以下的代码中都有。
export default {
name: "Device",
data() {
return {
inputDisabled: true,
title:"",
addErrorMessage:"",
addOpen: false,
// 分组选项
queryGroupOptions: [],
// 用户选项
queryUserOptions: [],
// 表单参数
addForm: {
id:null,
devId:"",
ownerId:"",
name:"",
devDesc:"",
longitude:"",
latitude:"",
groupId:"",
},
};
},
computed: {
rules() {
let rules = {
devId: [
{ required: true, message: this.$i18n.t('userInput')+this.$i18n.t('indexTablePrimaryKey'), trigger: 'blur' }
],
};
// 引入的页面必须使用forceUpdate, 单一的页面中可以直接使用nextTick
this.$forceUpdate( () => {
this.$refs['addForm'].clearValidate();
});
return rules;
}
},
dialogAddOpenFun(chooseId){
this.addErrorMessage = "";
noPageListUser().then(response => {
this.queryUserOptions = response.rows;
});
listBsGroupNoPage().then(response => {
this.queryGroupOptions = response.rows;
});
if(chooseId == null){
this.inputDisabled = false;
this.title = this.$i18n.t('btnAdd');
this.addForm.id=null,
this.addForm.devId="";
this.addForm.ownerId="";
this.addForm.name="";
this.addForm.devDesc="";
this.addForm.longitude="";
this.addForm.latitude="";
this.addForm.groupId="";
// 特别重要
this.resetForm("addForm");
}else{
this.inputDisabled = true;
this.title = this.$i18n.t('btnEdit');
this.addForm.devId=chooseId;
getDevice(chooseId).then(response => {
this.addForm = response.data;
});
}
this.addOpen = true;
},
}
{{addErrorMessage}}