背景

近段时间想使用ivew重构一下原来的后面管理,免不了一些列表的呈现和编辑,想着在列表页面做某种耗时相当长一些的操作时,按钮能为一个loading状态,一来让用户知道正在请求中,二来防止多次点击。可是在实现的过程中遇到了问题,折腾了很久,终于在同事的指点下解决了,遂记录如下。

详情

效果图

最终想实现的效果图如下

效果图

实现

Html部分

利用ivew 3.2.*以后的slot-scope特性加入一段模板,并在相应的Button上增加了loading属性,通过改变变量loading1[index]的值来控制加载状态

<template slot-scope="{row, index}" slot="action">
    <ButtonGroup shape="circle">
        <Button @click="modifyItem(row.id)" type="primary">修改</Button>
        <Button type="warning" :loading="loading1[index]">
        <Poptip @on-ok="syncDailyItem(row.id, index)" title="你确定要同步吗?" :transfer="true" :confirm="true">同步</Poptip>
        </Button>
    </ButtonGroup>
</template>

Js部分

接口请求时,设置loading1[index]true,则显示加载状态,请求成功或者失败后,移除加载状。

错误写法

syncDailyItem (id, index) {
    this.loading1[index] = true
    syncDaily({ id: id }).then(res => {
        this.$Message.success(res.data.result.message)
        this.tableData[index].mediaId = res.data.result.mediaId
        this.loading1[index] = false
    }).catch(err => {
        this.loading1[index] = false
    })
}

正确写法

syncDailyItem (id, index) {
    this.$set(this.loading1, index, true)
    syncDaily({ id: id }).then(res => {
        this.$Message.success(res.data.result.message)
        this.tableData[index].mediaId = res.data.result.mediaId
        this.$set(this.loading1, index, false)
    }).catch(err => {
        this.$set(this.loading1, index, false)
    })
}

区别?

this.loading1[index] = truethis.$set(this.loading1, index, true) 两者有很大的区别,第一种写法变量只会在方法内生效,并不会改变全局数组元素的值,因此如果写成第一种,其实按钮是不会有loading效果的。(ps:坑了我大半个小时)