Vue代码执行与浏览器渲染顺序

这篇文章是解释“如果同一个watcher被多次触发,只会被推入到队列中一次”。

例子1

那么这是什么意思呢?举个例子:

我有这样一段代码,当点击按钮时,就让sum+=1执行两次,那么当我点击按钮时,addTwice方法里的第一行代码执行,sum此时等于1,第二行代码执行,sum等于2,然后你才会发现页面上的数据会变换,会变成2。而并不是先变成1,然后再变成2。

其实这就是上面那句话的含义。只会被推入到队列中一次,这样做的目的是"在缓冲时去除重复数据对于避免不必要的计算和DOM操作是非常重要的",也就是说不会多次更新页面,而是代码都执行完了才更新页面,这样就避免浏览器多次渲染,浪费性能和时间。

例子2 

可能上面这个例子并不能然你感觉到有多么妙,但下面这个例子结合nextTick你就会感觉到有多么秒了。

有这么一个需求,输入框一开始是隐藏的,当点击按钮后:输入框显示且已经获取了焦点。

    <div id="root">
        <button @click="show">点击显示</button>
        <input type="text" ref="testRef" v-show="ishow">
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:"#root",
            data:{
                ishow:false
            },
            methods:{
                show(){
                    this.ishow = true
                    this.$refs.testRef.focus()
                }
            }
        })
    </script>

大家可以去复制代码验证一下,这样根本达不到需求。

解释:为什么达不到需求呢,原理和上面一样,vue为了避免多次渲染页面只会把show方法里的代码全部执行完后才会去渲染页面。所以上面第一行代码执行时,页面确实v-show等于true了,但是页面上没显示出来呀,所以你此时再执行第二行获取焦点,根本获取不了,因为执行这段代码时页面上根本没有输入框,要执行完这段代码后浏览器才会渲染页面,才会出现输入框。

如何解决:还记得nextTick吗,在所有dom节点更新完成后再执行,具体可以查看我这篇文章,戳我前往所以加上nextTick就可解决。

    <div id="root">
        <button @click="show">点击显示</button>
        <input type="text" ref="testRef" v-show="ishow">
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:"#root",
            data:{
                ishow:false
            },
            methods:{
                show(){
                    this.ishow = true
                    this.$nextTick( () => {
                        this.$refs.testRef.focus()
                    })
                }
            }
        })
    </script>

最近学习中发现要理解vue底层原理的话,如果知道JavaScript实现原理会更加容易理解,比较Vue是基于JavaScript写的嘛,后期会看《JavaScript高级程序设计》红宝石书,届时会将一些醍醐灌顶的知识以较容易理解的方式分享给大家! 

猜你喜欢

转载自blog.csdn.net/huiaixing/article/details/124904443