这周学到了-(2)

86 阅读2分钟

axios 中止请求

将cancelToken的cancel导出,注意这个不可以用await包裹起来,要在外面,调用的地方await

import axios, {Canceler, AxiosResponse} from 'axios'

public getCourseChapters(courseId: number): CourseChaptersResponse {
        const CancelToken = axios.CancelToken
        let _cancel = null
        const res = this.request.get<Chapters>(`${this.uuid}/xxx?course_id=${courseId}`, {
            cancelToken: new CancelToken(function executor(cancel) {
                _cancel = cancel
            })
        })

        return {
            query: res,
            cancel: _cancel
        }
    }

使用queryOld来记录之前的请求,当有新的请求后,中止之前的请求

// 获取课程章节
    protected async getCourseChapters(): Promise<void> {
        const getCourseChapters = tenantServiceV2.getCourseChapters(this.selectCourse.course_id)
        if (this.queryOld) {
            const cancel = this.queryOld
            cancel()
            this.queryOld = null
        }
        this.queryOld = getCourseChapters.cancel
        this.listLoading = true
        const res = await getCourseChapters.query
        this.courseContent = res.data.chapters
        this.listLoading = false
    }

上周modal扩展

通常modal的open方法会接收一个配置config参数,用来在打开弹窗时进行初始化等操作,两个问题: 1.config字段类型都是非必要的,可能会这样写

interface Config {
    title?: string
    content?: string
    width?: number
    cancleText?: string
    okText?: string
    time?: number
}
type DeleteDialog = VueConstructor<Vue> & {
    open: (config?: Config) => Promise<number>
}

可以使用用Partial,他将里面字段都变为可选类型

export interface Config {
    title: string
    content: string
    width: number
    cancleText: string
    okText: string
    time: number
}
type DeleteDialog = VueConstructor<Vue> & {
    open: (config?: Partial<Config>) => Promise<number>
}

2.在open接收config时,因为有默认config的情况,而且config字段都是可选的,如果是下面这样会有调用两次open导致第二次可能使用了第一次config字段的情况。

protected option: Config = {
        title: '',
        width: 416,
        cancleText: '取消',
        okText: '仍然删除',
        time: 5,
        content: ''
    }
public async open(config: Config): Promise<number> {
        this.visible = true
        if (config) {
            Object.keys(config).forEach((str: string) => {
                const keyStr = str as keyof Config
                if (config[keyStr]) {
                    this.$set(this.option, keyStr, config[keyStr])
                }
            })
        }
        return new Promise<number>((resolve, reject) => {
            this.deferred = {resolve, reject}
        })
    }

这时需要一个默认的config来重置this.option

const defaultOption = {
    title: '',
    width: 416,
    cancleText: '取消',
    okText: '仍然删除',
    time: 5,
    content: ''
}
protected option: Config = {
        title: '',
        width: 0,
        cancleText: '',
        okText: '',
        time: 0,
        content: ''
    }
public async open(config?: Partial<Config>): Promise<number> {
        this.visible = true
        this.option = {...defaultOption, ...config}
        return new Promise<number>((resolve, reject) => {
            this.deferred = {resolve, reject}
        })
    }

关于计时器setInterval的优化

封装了一个延时按钮,在涉及到计时器部分逻辑时,老大提出了一个建议,窗口在冻结的时候,计时器可能会失效,可以通过添加两个时间来解决 原代码:

protected mounted(): void {
        // 这里的this.time就是要延时的时间单位s
        // this.currentTime在html中展示
        this.currentTime = this.time
        this.timer = setInterval(() => {
            this.currentTime -= 1
            if (this.currentTime <= 0) {
                this.disabled = false
                clearInterval(this.timer)
            }
        }, 1000)
    }

优化后:

protected mounted(): void {
        this.currentTime = this.time
        const firstTime = new Date().getTime()
        this.timer = setInterval(() => {
            this.currentTime -= 1
            const lastTime = new Date().getTime()
            if (lastTime - firstTime > this.time * 1000) {
                this.currentTime = 0
                this.disabled = false
                clearInterval(this.timer)
            }
        }, 1000)
    }