从同事写的代码中,学习如何写代码1

120 阅读3分钟

不评价、只学习

getLeaveDays(leaveObj) {
                let days = 0
                this.leaveInfo.leaveDetails.forEach(item => {
                    days += item.leaveDays
                })
                this.totalLeaveDays = days;

                // 如果是已办
                if (this.done) return

                let params = []
                this.leaveInfo.leaveDetails.forEach(item => {
                    let obj = {
                        emplId: this.applicant && this.applicant.cmEmplId,
                        endDate: item.leaveEndDate,
                        holidayType: item.leaveType,
                        leaveEndHalf: item.leaveEndHalf,
                        leaveStartHalf: item.leaveStartHalf,
                        startDate: item.leaveStartDate,
                        holiday: item.leaveDays
                    }
                    if (!item.leaveDaysLock) {  //未修改销假天数,不传 holiday
                        delete obj.holiday
                    }
                    params.push(obj)
                })
                Loading.start({
                    message: '请假天数计算中...'
                })
                queryLeaveDays({
                    queryLeaveDays: params,
                }).then(res => {
                  if (!this.respSuccess(res)) {
                    this.isAccessSubmit = false
                    Message.danger('获取请假请求天数接口异常')
                    return
                  }
                  this.isAccessSubmit = true
                  this.listLeaveDays(res.data.data || [])
                }).catch(err => {
                  this.isAccessSubmit = false
                  Message.danger(err.message)
                }).finally(() => {
                  Loading.end()
                })
            }

映入眼帘的totalLeaveDays、应该是休息日期,作为Vue这个属性应该为计算属性

totalLeaveDays() {
    return this.leaveInfo.leaveDetails.reduce((days, { leaveDays }) => days + leaveDays, 0)
}

现在getLeaveDays函数为

getLeaveDays(leaveObj) {
                // 如果是已办
                if (this.done) return

                let params = []
                this.leaveInfo.leaveDetails.forEach(item => {
                    let obj = {
                        emplId: this.applicant && this.applicant.cmEmplId,
                        endDate: item.leaveEndDate,
                        holidayType: item.leaveType,
                        leaveEndHalf: item.leaveEndHalf,
                        leaveStartHalf: item.leaveStartHalf,
                        startDate: item.leaveStartDate,
                        holiday: item.leaveDays
                    }
                    if (!item.leaveDaysLock) {  //未修改销假天数,不传 holiday
                        delete obj.holiday
                    }
                    params.push(obj)
                })
                Loading.start({
                    message: '请假天数计算中...'
                })
                
                queryLeaveDays({
                    queryLeaveDays: params,
                }).then(res => {
                  if (!this.respSuccess(res)) {
                    this.isAccessSubmit = false
                    Message.danger('获取请假请求天数接口异常')
                    return
                  }
                  this.isAccessSubmit = true
                  this.listLeaveDays(res.data.data || [])
                }).catch(err => {
                  this.isAccessSubmit = false
                  Message.danger(err.message)
                }).finally(() => {
                    Loading.end()
                })
            }

将请求API提出来(职责单一)

getLeaveDaysApi() {
    const params = this.leaveInfo.leaveDetails.map((item) => {
        const obj = {
            emplId: this.applicant && this.applicant.cmEmplId,
            endDate: item.leaveEndDate,
            holidayType: item.leaveType,
            leaveEndHalf: item.leaveEndHalf,
            leaveStartHalf: item.leaveStartHalf,
            startDate: item.leaveStartDate,
            holiday: item.leaveDays
        }
        if (!item.leaveDaysLock) {  //未修改销假天数,不传 holiday
            obj.holiday = null
        }
        return obj
    })
    return new Promise((resolve, reject) => {
        queryLeaveDays({
            queryLeaveDays: params,
        }).then(res => {
          if (!this.respSuccess(res)) {
            reject(new Error('获取请假请求天数接口异常'))
            return
          }
          resolve(res.data.data)
        }).catch(err => {
          reject(err)
        })
    })
}

现在函数变更为

async getLeaveDays(leaveObj) {
                // 如果是已办
                if (this.done) return
                Loading.start({
                    message: '请假天数计算中...'
                })
                try {
                    const data = await this.getLeaveDaysApi()
                    this.isAccessSubmit = true
                    this.listLeaveDays(data)
                } catch(err) {
                    this.isAccessSubmit = false
                    Message.danger(err.message)
                } finally {
                   Loading.end()
                }
}

函数看起来清爽了,loading跟api分离了,api里面的参数细节getLeaveDays函数不想知道,分工不同

现在我们再看listLeaveDays这个函数

listLeaveDays(data) {
                let days = 0

                this.firstAnnualLeave = false
                this.leaveInfo.leaveDetails.forEach((item, idx) => {

                    item.leaveNumberInfo = data[idx]
                    let restBalance = 0
                    item.leaveNumberInfo.balanceSurplus && Object.values(item.leaveNumberInfo.balanceSurplus).forEach(value => {
                        restBalance += value
                    })
                    item.leaveNumberInfo.restBalance = restBalance

                    let dataItem = data[idx]
                    if (dataItem.holiType === 'LV01' && dataItem.firstAnnualLeave === 'Y') {
                        this.firstAnnualLeave = true
                    }

                    if (!item.leaveDaysLock) {
                        item.leaveDays = dataItem.holiday

                        // 处理因私出国请假,请假天数,延迟到下一次变动展示的问题
                        setTimeout(() => {
                            item.leaveDays = ''
                            this.$nextTick(() => {
                                item.leaveDays = dataItem.holiday
                            })
                        }, 300)
                    }

                    item.holidayBalance = dataItem.holidayBalance
                    item.showHolidayBalance = typeof dataItem.holidayBalance === 'number'
                    item.flag = dataItem.flag
                    item.warnFlag = dataItem.warnFlag
                    item.itemMsg = dataItem.itemMsg
                    item.holidayDtl = dataItem.holidayDtl
                    item.annualUsedHoliday = dataItem.annualUsedHoliday
                    item.isArrangePerson = dataItem.arrangePerson == '1' ? true : false
                    days += item.leaveDays

                    //不对排班人员验证,提交时验证
                    /*if(item.isArrangePerson && item.itemMsg === "假期余额不足") {
                        item.flag = true
                    }*/
                })

                this.totalLeaveDays = days
                this.$forceUpdate()
            },

看到了totalLeaveDays先移除掉

listLeaveDays(data) {
                this.firstAnnualLeave = false
                this.leaveInfo.leaveDetails.forEach((item, idx) => {

                    item.leaveNumberInfo = data[idx]
                    let restBalance = 0
                    item.leaveNumberInfo.balanceSurplus && Object.values(item.leaveNumberInfo.balanceSurplus).forEach(value => {
                        restBalance += value
                    })
                    item.leaveNumberInfo.restBalance = restBalance

                    let dataItem = data[idx]
                    if (dataItem.holiType === 'LV01' && dataItem.firstAnnualLeave === 'Y') {
                        this.firstAnnualLeave = true
                    }

                    if (!item.leaveDaysLock) {
                        item.leaveDays = dataItem.holiday

                        // 处理因私出国请假,请假天数,延迟到下一次变动展示的问题
                        setTimeout(() => {
                            item.leaveDays = ''
                            this.$nextTick(() => {
                                item.leaveDays = dataItem.holiday
                            })
                        }, 300)
                    }

                    item.holidayBalance = dataItem.holidayBalance
                    item.showHolidayBalance = typeof dataItem.holidayBalance === 'number'
                    item.flag = dataItem.flag
                    item.warnFlag = dataItem.warnFlag
                    item.itemMsg = dataItem.itemMsg
                    item.holidayDtl = dataItem.holidayDtl
                    item.annualUsedHoliday = dataItem.annualUsedHoliday
                    item.isArrangePerson = dataItem.arrangePerson == '1' ? true : false

                    //不对排班人员验证,提交时验证
                    /*if(item.isArrangePerson && item.itemMsg === "假期余额不足") {
                        item.flag = true
                    }*/
                })
                this.$forceUpdate()
            },

看到了firstAnnualLeave的变化过程,职责单一抽离出来

getFirstAnnualLeave(data) {
    this.firstAnnualLeave = data.some(({ holiType, firstAnnualLeave }) => {
        return holiType === 'LV01' && firstAnnualLeave === 'Y'
    })
}

listLeaveDays(data) {
                this.firstAnnualLeave = this.getFirstAnnualLeave(data)
                this.leaveInfo.leaveDetails.forEach((item, idx) => {

                    item.leaveNumberInfo = data[idx]
                    let restBalance = 0
                    item.leaveNumberInfo.balanceSurplus && Object.values(item.leaveNumberInfo.balanceSurplus).forEach(value => {
                        restBalance += value
                    })
                    item.leaveNumberInfo.restBalance = restBalance

                    let dataItem = data[idx]

                    if (!item.leaveDaysLock) {
                        item.leaveDays = dataItem.holiday

                        // 处理因私出国请假,请假天数,延迟到下一次变动展示的问题
                        setTimeout(() => {
                            item.leaveDays = ''
                            this.$nextTick(() => {
                                item.leaveDays = dataItem.holiday
                            })
                        }, 300)
                    }

                    item.holidayBalance = dataItem.holidayBalance
                    item.showHolidayBalance = typeof dataItem.holidayBalance === 'number'
                    item.flag = dataItem.flag
                    item.warnFlag = dataItem.warnFlag
                    item.itemMsg = dataItem.itemMsg
                    item.holidayDtl = dataItem.holidayDtl
                    item.annualUsedHoliday = dataItem.annualUsedHoliday
                    item.isArrangePerson = dataItem.arrangePerson == '1' ? true : false
                })
                this.$forceUpdate()
            },

有下面4个问题

  1. 能看到直接更改了this.leaveInfo.leaveDetails每个子项的数据,非常不推荐
  2. if一定要用大括号 代码直观
  3. setTimeout直觉上根本不需要
  4. $forceUpdate()更不可能需要
listLeaveDays(data) {
                this.firstAnnualLeave = this.getFirstAnnualLeave(data)
                const leaveDetails = deepClone(this.leaveInfo.leaveDetails)
                this.leaveInfo.leaveDetails = leaveDetails.map((item, idx) => {
                    const obj = deepClone(item)
                    const dataItem = deepClone(data[idx])
                    obj.leaveNumberInfo = dataItem
                    if (Array.isArray(obj.leaveNumberInfo.balanceSurplus)) {
                        obj.leaveNumberInfo.restBalance = Object.values(obj.leaveNumberInfo.balanceSurplus).reduce((restBalance, value) => restBalance + value, 0)
                    }
                    if (!obj.leaveDaysLock) {
                        obj.leaveDays = dataItem.holiday
                    }
                    obj.holidayBalance = dataItem.holidayBalance
                    obj.showHolidayBalance = typeof dataItem.holidayBalance === 'number'
                    obj.flag = dataItem.flag
                    obj.warnFlag = dataItem.warnFlag
                    obj.itemMsg = dataItem.itemMsg
                    obj.holidayDtl = dataItem.holidayDtl
                    obj.annualUsedHoliday = dataItem.annualUsedHoliday
                    obj.isArrangePerson = dataItem.arrangePerson === '1'
                    return obj
                })
            },

至此代码基本上OK,我们可以更进一步,listLeaveDays不需要知到leaveDetails的创建数据的过程

genLeaveDetails(data) {
    const leaveDetails = deepClone(this.leaveInfo.leaveDetails)
    return leaveDetails.map((item, idx) => {
                    const obj = deepClone(item)
                    const dataItem = deepClone(data[idx])
                    obj.leaveNumberInfo = dataItem
                    if (Array.isArray(obj.leaveNumberInfo.balanceSurplus)) {
                        obj.leaveNumberInfo.restBalance = Object.values(obj.leaveNumberInfo.balanceSurplus).reduce((restBalance, value) => restBalance + value, 0)
                    }
                    if (!obj.leaveDaysLock) {
                        obj.leaveDays = dataItem.holiday
                    }
                    obj.holidayBalance = dataItem.holidayBalance
                    obj.showHolidayBalance = typeof dataItem.holidayBalance === 'number'
                    obj.flag = dataItem.flag
                    obj.warnFlag = dataItem.warnFlag
                    obj.itemMsg = dataItem.itemMsg
                    obj.holidayDtl = dataItem.holidayDtl
                    obj.annualUsedHoliday = dataItem.annualUsedHoliday
                    obj.isArrangePerson = dataItem.arrangePerson === '1'
                    return obj
                })
}

listLeaveDays(data) {
                this.firstAnnualLeave = this.getFirstAnnualLeave(data)
                this.leaveInfo.leaveDetails = this.genLeaveDetails(data)
},

函数更多的应该是组合而成,将细节抽离出去(比如genLeaveDetails),将过程描述出来(比如listLeaveDays),代码会变得更清晰,我们去阅读代码会更有效率

因为是接手项目可以问下产品 补充必要注释