深究之前先声明一个问题,
layui是基于jquery直接操控dom的
而vue是操控虚拟dom的,虚拟dom不理解的可以参考一下这篇文章
深究vue核心之虚拟DOM(vdom)
深究Javascript的加载与执行顺序
希望看到此篇博文的人先去看一下这两篇文章,以便你理解我在说什么.
直接写大坑描述.
最近写完的一个项目里, 纯html css js写的一个后台, 用的vue.js+layui.js ,属实是恶心到了我
很多页面的select下拉,radio单选 复选, 总之的总之,只要涉及到layui的form表单回显加载的问题, 都有可能出现偶发性的加载不出来的问题
如同这种
打开F12,查看标签以及ajax, 有数据返回!! 这个option标签是用vue的 v-for循环出来的下拉
再如下这种
偶发性渲染失败时
渲染成功时
共同点是两者都是有返回数据的,都是用的v-for循环
不同点是到html上面时,解析没有渲染出来
思考了一下, 应该是vue 和 layui实例的加载顺序问题
举几个错误的实例顺序写法(如果服务器带宽足够,则错误不成立)
layui.use(['layer', 'form', 'tree'], function () {
var layer = layui.layer,
form = layui.form,
tree = layui.tree;
//自定义验证规则
form.verify({
addDepartment: function (value) {
var han = /[\u4e00-\u9fa5]/g;
if (value.length > 10) {
return '部门名称不得超过10个字';
}else if (!han.test(value)) {
return '请输入汉字作为部门名称';
}
},
sort: function (value) {
if (value.length == 0) {
return '请输入排序编码';
} else if (value.length > 20) {
return '标题长度不得大于20个字!';
}
},
});
//监听提交
form.on('submit(subBtn)', function (data) {
var datas = {
name: data.field.name,
sort: data.field.sort,
parentId: data.field.parentId,
};
vm.submitForm(datas);
});
form.render();
});
var vm = new Vue({
el: '#open_cn',
mounted() {
var _this = this;
//_this.getList();
layui.use(['layer', 'form', 'tree'], function () {
var layer = layui.layer,
form = layui.form,
tree = layui.tree;
//自定义验证规则
form.verify({
addDepartment: function (value) {
var han = /[\u4e00-\u9fa5]/g;
if (value.length > 10) {
return '部门名称不得超过10个字';
}else if (!han.test(value)) {
return '请输入汉字作为部门名称';
}
},
sort: function (value) {
if (value.length == 0) {
return '请输入排序编码';
} else if (value.length > 20) {
return '标题长度不得大于20个字!';
}
},
});
//监听提交
form.on('submit(subBtn)', function (data) {
var datas = {
name: data.field.name,
sort: data.field.sort,
parentId: data.field.parentId,
};
vm.submitForm(datas);
});
form.render();
});
_this.getDepartment();
},
亦或者把layui实例放在created周期里面
以上这三种写法,在服务器带宽不足的时候,vue.js jq.js layui.js加载过慢或者失败的时候,页面里面要么就是一片空白,要么循环出来的标签循环失败,属于偶发性的bug,还有一点,有时间的同学可以去深扒一下两者共用时页面的性能问题,我觉得好不到哪去.
**
解决
- ajax成功的回调里面,数据赋值加settimeout延时器,200或者300ms都可以
if (res.code == 0) {
setTimeout(() => {
_this.typeList = res.data
}, 200);
} else {
layer.msg(res.msg, {
icon: 2
});
}
- 将layui的实例放在updated周期里面重新的加载一次
updated: function () {
layui.use(['form'], function () {
layui.form.render();
});
},
虽然我知道这两种写法很垃圾,但是没办法,这次混合用完之后,不会再混合用了