• 从父子组件的mounted钩子的同步执行与页面的异步渲染看nextTick的用法


    最近复习vue的时候遇到了一个很奇怪的问题,我们直接从实例中看:

    <div id="app">
        <child ref="child"></child>
    </div>
    <template id="child">
        <ul>
            <li v-for='a in arr'>{{a}}</li>
        </ul>
    </template>
    <script src="../../node_modules/vue/dist/vue.js"></script>
    <script>
        let child = {
            template:'#child',
            mounted(){this.arr = [4,5,6]},//改变arr的值
            data:function(){
                return {arr:[1,2,3]};
            },
        };
        
        let vm = new Vue({
            el:'#app',
            data:{
            },
            mounted(){
                console.log(this.$refs.child.$el.innerHTML);//获取挂载到页面中的child子组件的innerHTML
            },
            components:{
                child:child,
            },
        })
    </script>

    整个过程是这样的:

    • 我在子组件的mounted函数中,改变了arr的值,这会重新触发视图的渲染。
    • 然后我紧接着在父组件的mounted函数中获取子组件的innerHTML。

    然而结果是这样的。

    于是开始的苦苦的探索之路。

    我们一起来分析一下整个的执行过程:

    • 首先,页面首次加载时,在子组件的mounted钩子函数之前,已经把$el挂载到了页面。
    • 然后执行子组件的mounted函数,将arr的值改变,导致页面的重新渲染。
    • 再然后执行父组件的mounted函数,将子组件的innerHTML打印出来。

    答案就在页面的重新渲染这。执行完子组件的mounted函数后,会立即执行父组件的mounted函数。也就是说mounted之间的执行是同步执行的。但是我们的页面渲染是一个异步操作。也就是说在执行父组件的mounted方法时,页面还没有渲染完成,所以导致了打印结果的不一致性。

    所幸的是vue给我们提供了一个全局的API:nextTick函数,该函数的功能是:

    在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

    所以,我们对父组件的mounted做如下修改:

    mounted(){
        this.$nextTick(() => console.log(this.$refs.child.$el.innerHTML))
        //console.log(this.$refs.child.$el.innerHTML)
    },
    //打印时异步渲染还未完成,所以打印的不是我们想要的结果.所以为保守起见,都为在执行mounted方法时添加一个this$nextTick()方法

     

    大功告成,在实战中学习,在问题中学习就是这么爽。

  • 相关阅读:
    Service解析
    Android消息处理
    FragmentTransaction.addToBackStack无效的问题
    Activity生命周期
    width 的100% 与 auto
    parseInt 与 parseFloat 解析
    splice
    <c:forEach>
    笔记,遮罩。。
    nginx 的windows 基本配置
  • 原文地址:https://www.cnblogs.com/yuliangbin/p/9492268.html
Copyright © 2020-2023  润新知