假如我们需要实现一个功能,页面左边是多选列表,页面右边是根据选中的值进行数据请求之后显示的数据。
一、普通操作
等用户勾选完之后,点击确定按钮后,才向后台发请求,然后右边渲染显示。
这种形式,请求都是一个选中列表作为参数。
这种操作在用户使用上会存在一个问题:
问题一: 用户点击确定后,接口5s之后才返回数据,这个时候用户取消勾选示例4,然后又点击了确定,这时用户要删除的数据4都没有返回,就会导致程序报错。
如果采用这种方式,那么我们需要做两件事:
1、
确定按钮
的防抖
2、 在上次数据请求返回前禁用确定按钮
这样就能保证用户的每次新操作不会对上一次的操作结果进行影响。
二、实时数据响应
实时数据响应就是没有确定按钮的,这里的操作就是,用户勾选一个,立马向后台发请求。即每次勾选一个,或者取消勾选,右边都是实时响应的。
页面采用这种方式实现,用户体验会稍微好点,用户减少了一次按钮点击,右边是实时变化的。
但种方式除了会出现 问题一 ,还会有 :
问题二:用户快速点击选中, 如果用户选中了5个,就向后台发了5次并行请求,如果第四次请求在第五次之后才返回,那么数据显示就会出现问题:
- 如果每次列表数据是全部覆盖上一次的处理,那么右边就只显示4个数据;
- 如果是增量请求,即每次只请求一个,返回一个,页面是按返回的数据进行push,那么顺序会存在错位问题
问题三:如果用户快速选中,又快速取消了所有选中。这时左边没有选中,就不向后台发请求,右边此时清空列表, 但是之前选中的请求可能很久之后返回来了数据,这个时候,页面就会出现左边啥都没选,右边有数据显示。
页面采用这种方式实现,那么我们需要做到:
1、 复选框组的
选中事件
进行节流处理,在1s内触发多次,都只执行最新的一个
2、 在上次数据请求返回前禁用所有复选框
3、在上次数据返回后,才执行新的请求
三、代码实现示例
以解决实时数据显示为例:
1、 节流处理
/**
* lodash的节流函数
*/
handle: _.throttle(function() {
// 处理选中的数据,如发请求等
}, 1000, {
leading: true,
trailing: false
}),
2、禁用处理
比如现在左边是可复选框树(el-tree):
//el-tree中存在一个disabled属性,允许传入一个函数:
:disabled="disabledFunc"
// 全部禁用
const disabledFunc = () => false
// 节点key为1200的禁用
const disabledFunc = (data, node) => {
if (node.key === '1200') {
return true
}
return false
}
3、 请求顺序处理
data() {
return {
preRequest: Promise.resolve(),
}
},
// 每次数据请求赋值给一个变量
getData() {
this.preRequest = getDataByInfo(params).then((res) => {
// 处理代码。。。
return
}
}
// 检测到选中数据变化
handleChange() {
// 保证在下一次请求回来之后再发
this.preRequest.then(() => {
this.getData()
})
}