问题

1.使用avue form表单,avue form表单当使用axios,fetch,ajax等异步获取数据时,在mount中给model赋值,数据是改变了,但视图可能不更新显示

2.Vue 异步请求导致页面数据渲染错误

相关浏览器:firefox(新版,我的是114.0 (64 位))出现机率大,edge和chrome偶尔出现

一、问题分析

经过页面数据输出及debugger断点调试,发现在页面渲染结束前,异步数据并未处理完毕,导致页面数据渲染问题。

当vue实例生成后,再次给对象赋值时,并不会自动更新到视图上去; 当我们去看vue文档的时候,会发现有这么一句话:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。

受 ES5 限制,Vue.js 不能检测到对象属性的添加或删除,即Vue未做到脏数据检查。因为 Vue.js 在初始化实例时将属性转为 getter/setter,所以属性必须在 data 对象上才能让 Vue.js 转换它,才能让它是响应的。

二、解决措施

已尝试的方法1:通过this.$set()方法处理,要对控件用的prop值set才会有用。

1.有效的this.$set(),这对大对象赋值将是麻烦事,不如用v-if方便

this.$set(this.model, "account", data.account);

this.$set(this.model, "address", data.address);

2.无效的this.$set();

this.$set(this, "model", data);//无效,并不会重新渲染

已尝试的方法2:通过this.$nextTick(方法处理,但这个方法在我的firefox中偶尔也会出问题。

this.$nextTick(function () {

this.$axios

.get(url, {

responseType: "json",

})

.then((res) => {

if (res.status == 200) {

let data = JSON.parse(JSON.stringify(res.data.data));

this.model = data;

}

});

});

终级且超级简单的方法,用Object.assign()给data对象属性赋值(使用修改栈能触发视图更新的特性)。

this.$axios

.get(url, {

responseType: "json",

})

.then((res) => {

if (res.status == 200) {

let data = JSON.parse(JSON.stringify(res.data.data));

// this.model = data; //不用这个

this.model = Object.assign(this.model, data);

}

});

相对方便的有效方法:可通过v-if控制页面渲染、销毁逻辑,在异步方法请求前销毁相应数据,异步方法请求成功后新建相应数据段,这样用this.model = data赋值,相对方便。

三、相关代码(详见DialogBindDataComponent.vue)

1.页面AvueDialogBindData.vue

2.option文件 AvueDialogBindDataOption.js

/*

* @Description:

* @Version: 1.0

* @Autor: Tj

* @Date: 2023-03-21 11:02:42

*/

export const AvueDialogBindDataOption = (vueObj) => {

return {

labelWidth: 100, //整体列标签宽度

submitText: "提交",

span: 24,

size: "small", //medium/small/mini

emptyBtn: false,

menuPosition: "right",

column: {

account: {

label: "账号",

prop: "account",

},

address: {

label: "地址",

prop: "address",

type: "textarea",

minRows: 2,

maxRows: 3,

labelTip: "地址必填",

labelTipPlacement: "bottom-start",

rules: [

{

required: true,

message: "请选择收货地址",

trigger: "blur",

},

],

},

},

};

};

3.组件文件DialogBindDataComponent.vue

总结:

在同一组件中,使用多个avue-form或avue-crud时,v-model绑定的对象不能用同一个,否则部分视图更新可能会失败加载时推荐使用Object.assign()和this.$set()给model赋值用Object.assign()赋值时不能用Object.assign({}, data),只能用Object.assign(this.model, data)Object.assign()赋值后用this.$set()赋值,不能用“=”给model赋值,如this.model.member={…}this.$set()前后都不能用“=”给model赋值

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: