Vuejs for 循环内如何更新页面状态

2017-08-24 10:36:05 +08:00
 hoythan

在点击按钮触发一个 for 循环事件

that.progress = xxx

that.progress = Math.ceil((i / fileNumber) * 100)

dom 中没有刷新状态,

console.log(that.progerss)

是正常的

因为这不是对象也不是数组的,不知道为啥会这样

let that = this
let filePath = that.filePath
let fileNumber = that.filesNumber
let files = that.files
let i = 0
async.whilst(() => {
        return i < fileNumber
    },
    (callback) => {
        let newPath = path.normalize(files[i]).replace(path.normalize(filePath), path.normalize("C:\\Users\\xxx\\xxx"))
        fs.copySync(files[i], newPath)
        i++

        that.progress = Math.ceil((i / fileNumber) * 100)
        console.log(that.progress)
        callback()
    },()=> {
        alert('ok')
    })
3654 次点击
所在节点    Vue.js
19 条回复
littlepanzh
2017-08-24 10:36:58 +08:00
talk is cheap, show me your code
hoythan
2017-08-24 10:40:08 +08:00
@littlepanzh 就是 for 循环里面修改参数,console 显示正常,dom 不刷新
SourceMan
2017-08-24 10:41:55 +08:00
Vue.set()
hoythan
2017-08-24 10:43:26 +08:00
@SourceMan 我这不是数组对象呀?
hoythan
2017-08-24 10:45:44 +08:00
@SourceMan 我先试一下
hoythan
2017-08-24 10:50:21 +08:00
@SourceMan 果然不行
66beta
2017-08-24 10:55:28 +08:00
如果 console.log 都看到变化了,应该没毛病
watch 下看看呢
hoythan
2017-08-24 11:01:03 +08:00
@66beta watch 只有触发了一次
Lothar
2017-08-24 11:01:07 +08:00
一个循环里的更新,统一被放在一个缓存队列里,循环结束后一起更新。你想啊,如果不这么做,一个循环你的页面不就崩了。
Lothar
2017-08-24 11:03:45 +08:00
> In case you haven ’ t noticed yet, Vue performs DOM updates asynchronously. Whenever a data change is observed, it will open a queue and buffer all the data changes that happen in the same event loop. If the same watcher is triggered multiple times, it will be pushed into the queue only once. This buffered de-duplication is important in avoiding unnecessary calculations and DOM manipulations. Then, in the next event loop “ tick ”, Vue flushes the queue and performs the actual (already de-duped) work. Internally Vue tries native Promise.then and MutationObserver for the asynchronous queuing and falls back to setTimeout(fn, 0).
hoythan
2017-08-24 11:07:32 +08:00
@Lothar 所以我要实现的话是不是得直接自己修改 dom 比较好一点?
hoythan
2017-08-24 11:14:13 +08:00
@Lothar 好像是我想多了,直接修改 dom 为啥也不会改变 555

document.getElementById('xxx').innerHTML
loveyu
2017-08-24 11:16:45 +08:00
Var.nextTick
hoythan
2017-08-24 11:24:46 +08:00
@loveyu
that.progress = Math.ceil((i / fileNumber) * 100)
Vue.nextTick()

还是无法刷新 dom,循环结束才更新
qiqico
2017-08-24 11:27:56 +08:00
试试 this.$forceUpdate() ?
maplerecall
2017-08-24 11:32:29 +08:00
用$forceUpdate 试试,另外如果循环操作阻塞了主线程也是不会更新 dom 的
hoythan
2017-08-24 11:34:23 +08:00
@qiqico
@maplerecall

看来真的是阻塞了主线程,我的异步用的方法可能不对
jin5354
2017-08-24 11:49:04 +08:00
你想在每次循环时都更新 DOM,制造一种高频率渲染的效果?
用 requestAnimationFrame 循环来写异步
jin5354
2017-08-24 11:52:51 +08:00
你即使用 for 循环直接改 DOM 也没用,且不说 vue 自带事件队列,每个 tick 里的数据变动会做合并。你一个 for 循环在一个 eventloop 的 task 里就跑完了,最多就渲染一次 DOM。必须把 for 任务用 requestAnimationFrame 打碎到每一帧里

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/385377

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX