【基于vue的大量表单数据,动态生成表单性能优化篇】解决输入延迟,卡顿问题
需求分析需求:根据后端返回的字段,生成多条表单数据( 实质是批量发布商品 ),预留可增删改功能实现思路后端返回的数据格式是一个一维数组(一个商品的所有字段)let product_item =[{prop:'name',value:'',type:'input',//表单类型--输入框},{prop:'img',value:'',type:'img'//表单类型--图片},{prop:'type'
需求分析
需求:根据后端返回的字段,生成多条表单数据( 实质是批量发布商品 ),预留可增删改功能
实现思路
后端返回的数据格式是一个一维数组(一个商品的所有字段)
let product_item = [
{
prop:'name',
value:'',
type:'input',//表单类型--输入框
},
{
prop:'img',
value:'',
type:'img'//表单类型--图片
},
{
prop:'type',
value:'',
type:'select'//表单类型--下拉框
},
{
prop:'type',
value:'',
type:'selectSearch'//表单类型--下拉搜索
}
...
]
这是一个商品的,可以直接通过遍历生成表单就行,那么现在我们的需求是发布多个商品的,需要进行一个处理,也就是变成二维数组
product_list = [
product_item,
product_item,
...
]
这一步需要注意的是,每一个product_item里面的字段的引用位置不能相同,否则输入表单时会相互映射,所以每一个product_item都做一个深拷贝。
写法一
代码集中在一个组件里面,我想大多数人第一遍写的代码大多数是这样的,这样子写也并不是错的,但是表单的量一多(product_list)就会出现卡顿现象,比如输入、下拉的时候,在测试过程中,10个商品卡顿现象还不明显,当增加到30-100条时就非常卡顿了,甚至不能使用。至于卡顿的原因往后看
<div v-for="(row,i) in product_list " :key="i">
<div v-for="(v,k) in row" :key="k">
<div v-if="v.type==='input'">
<el-input></el-input>
</div>
<div v-else-if="xxx"></div>
....
</div>
</div>
写法二
将代码拆分成多个组件,将表单换为原生的表单(样式采用element ui的)
product.vue页面
渲染多条商品表单的
<div v-for="(row,i) in product_list " :key="i">
<product-item :row="row" :index="i"></product-item>//每一条商品表单组件
</div>
product-item组件
渲染单个商品表单的
<div v-for="(item,i) in row" :key="i">
<product-item-form :item="item"></product-item-form>
</div>
product-item-form组件
根据类型渲染表单,此处使用了:lazy修饰符避免频繁更新,以提高流畅度
<div>
<div v-if="item.type==='input'">
<input v-model.lazy="item[item.prop]" />//绑定到prop上,使用原生标签,性能翻倍
</div>
<div v-else-if="xxx"></div>
...
</div>
由于item的引用位置依然是product_list的,所以不必担心拿不到最终的值的问题。
利用方法二的写法进行测试
测试的发布于商品个数100个,总的表单的个数100*11 = 1100(相当于1100个输入框),结果是输入不卡,下拉框也不卡,整体流畅,与写法一差距的性能巨大。
总结
也许在少量表单时(20个以内)的时候,俩者差距不大,但是当超过30个商品时就差距很大。
优化点:
- 拆分组件,在组件更新的时候只需要更新组件,而不用整个页面,这跟vue的patch虚拟dom效率有关
- 使用lazy修饰符,避免输入更新data太频繁造成卡顿,这个相当于节流吧…
- 其实UI框架封装的太臃肿,缝合了各种功能,初始化的时间长,判断条件多等等,所以尽量使用原生的标签,性能强上好几倍(样式可以直接copy UI框架的)。
存在的问题: 因为渲染的数据量多,如果一次性加载100条,页面初次加载的时候会有点慢(渲染慢),我个人认为最好的方法还是分步加载,一次加载30-40条,当用户滚动到一定的位置再追加30-40条,以此类推。如果大家有更好的优化方法,欢迎在评论区讨论。
更多推荐
所有评论(0)