需求:点击刷新按钮后显示倒计时5s,倒计时结束后才能继续刷新。
项目框架:vue + uView
预期效果:
点击“刷新” ——>
// html代码
<view v-for="item in list" :key="item.id">
...
<view class="refresh">
<u-button type="primary" plain size="mini" v-if="item.showCount" disabled>
<u-count-down :autoplay="false" :timestamp="5" :ref="'uCountDown'+item.id" @end="()=>countEnd(item)"
:show-days="false" :show-hours="false" :show-minutes="false" color="#2979ff" font-size="22">
</u-count-down>
</u-button>
<u-button type="primary" plain size="mini" @click="()=>refresh(item)" v-else>
刷新
</u-button>
</view>
...
</view>
原list中没有showCount这个字段,触发刷新后手动加上的。问题来了,在倒计时结束后明明将showCount设为false了但是视图还停留在倒计时,没有显示刷新按钮。
代码如下:
methods: {
refresh(obj) {
...
this.list.forEach(item => {
if (obj.id === item.id) {
item.showCount = true
}
})
// 开启5s倒计时
this.$nextTick(() => {
this.$refs['uCountDown' + item.id][0].start()
})
...
},
countEnd(item) {
this.list.forEach((i) => {
if (i.id === item.id) {
// 关闭倒计时
i.showCount = false
}
})
}
}
原因:showCount这个参数是在数据初始化之后手动添加,并没有绑定vue的setter/getter方法,因此不具备响应式的能力。
修改方案一:在拿到list数据赋值时,给所有对象添加showCount
// 从后端获取数据
...
this.list = list.map((i) => {
return { ...i, showCount: false }
})
(推荐) 修改方案二:通过vue的set方法添加showCount
methods: {
refresh(obj) {
...
let ind = ''; let obj
this.list.forEach(item => {
if (obj.id === item.id) {
ind = index
obj = {
...i,
showCount: true
}
}
})
this.$set(this.list, ind, obj)
// 开启5s倒计时
this.$nextTick(() => {
this.$refs['uCountDown' + item.id][0].start()
})
...
}
}