需求场景
近期需求中,要做一个列表。列表中每项数据会有一个快捷启用禁用入口。
目前,项目使用的是 element-ui,里边有 Switch 组件,画界面是非常容易的。
问题
大概的逻辑是:用户点击这个 Switch 组件后,会发送一个请求。请求获得正确结果后,再切换 Switch 组件的状态。
其中一种场景:用户会快速连续点击这个 Switch 组件,这样请求就会连续被发送。
还一种场景:请求结果是异常的,状态不应该被改变。
思考和方案
第一个问题处理方式可以是:发送一个请求的时候,吧这个请求缓存起来,如果请求发送成功,再把这个缓存值清空。每次发请求之前都检查这个缓存值是否为空。如果缓存值存在,就取消上一次的请求。
还一种方法:添加一个disable的状态,发送请求前把 Switch 组件变成 disable 状态,请求发送有结果后,再把组件变成正常状态。
第二个问题:element-ui 中其实要变更当前 Switch 按钮状态就是改变绑定值就可以了。但是我们再一个数据条数不确定的列表中,并不合适去手动设定一个可控的绑定值。所以需要有一个作用域来控制变更单个 Switch 组件的状态。所以想到了再次封装 Switch 组件。
实现与编码
首先,确认我们组件要传入:
- val: 当前状态
- reqUrl: 改变状态 接口url
- id: 标识这个状态的id 要传数据的 值
- idName: 改变状态要传的数据字段名
其次,我们再组建中创建一个变量,来绑定改组件的值。在创建这个组件的时候,把传进来的状态赋值给组件内的变量值。这样就实现了局部控制。同时,用了一个 isDisabled 变量来控制组件的可用状态。
当然,用了禁用方案,就不会怕用户连续发送变更组件状态了,所以检测请求重复就取消上一个请求的操作是多余的。不过这里既然讲了,就再组件中写了实现的方法。
封装后的组件源码如下:
<template>
<div>
<el-switch
:value="value"
@change="changeStatus"
active-color="#13ce66" :disabled="isDisabled"
inactive-color="#ff4949">
</el-switch>
</div>
</template>
<script>
/**
* val: 当前状态
* reqUrl: 改变状态 接口url
* id: 标识这个状态的id 要传数据的 值
* idName: 改变状态要传的数据字段名
* */
export default {
name:'switchItem',
props:[
'val',
'reqUrl',
'id',
'idName',
],
data() {
return {
value:false,
setStatusHttp: null,
isDisabled: false,
}
},
created() {
let self = this;
self.value = self.val
},
methods:{
changeStatus(){
let self = this;
self.isDisabled=true
self.setStatus()
},
// setStatus
setStatus(){
let self = this;
if (!self.setStatusHttp) { // 判断是否已经有请求正在发送
self.setStatusHttpReq();
} else {
// abort 正在发送的请求 然后再次发送请求
self.setStatusHttpReq();
}
},
setStatusHttpReq(){
let self = this;
let CancelToken = self.$http.CancelToken
let postData = {}
postData[self.idName] = self.id
self.$http.post(self.reqUrl,postData,{
cancelToken: new CancelToken(function executor(c) {
// An executor function receives a cancel function as a parameter
self.setStatusHttp = c;
})
}).then(res => {
if(res.data.error_code == '00000'){
self.$message({
type: 'success',
message: '操作成功!'
});
self.value = !self.value
}else{
self.$message({
type: 'error',
message: res.data.message
});
}
self.isDisabled=false
})
},
}
}
</script>
总结
当一个列表中,某个组件需要一个局部作用域来操作或者控制一些状态的的时候,可以对该组件再次进行封装,这样就会有一个组件的作用域,再这个作用域里边,我们就可以做一些骚操作来实现特殊场景的需求了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。