Vue 正确理解mounted、beforeUpdate、updated三个钩子函数的关系

    科技2022-07-13  123

    目录

    官方图

    理解beforeUpdate:视图层的数据改变时触发

    beforeUpdate的测试

    updated的测试


    官方图

    mounted表示vue实例挂载完成;

    beforeUpdate在data数据被改变后触发

    updated表示更新DOM完成。

    理解beforeUpdate:视图层的数据改变时触发

    这里需要注意的是beforeUpdate是在data数据被改变后触发,这里的data数据改变如何理解,仅从字面上理解只要data数据值改变就会触发beforeUpdate吗?答案是否定的,我们做个测试。

    我们在mounted里修改data的值,mounted表示实例已经挂载完成,因此从理论上来说在在mounted里修改data会触发beforeUpdate,测试代码如下:

    App.vue中:

    <template> <div id="app"> </div> </template> <script> export default { data() { return { message: 10, } }, mounted: function() { console.group('------mounted 挂载结束状态(父)------'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); this.message += 1 console.log("%c%s", "color:red","message: " + this.message); }, beforeUpdate: function () { console.group('beforeUpdate 更新前状态(父)===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, updated: function () { console.group('updated 更新完成状态(父)===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); } } </script> <style> .eac{ background: lightgreen; } li{ display: inline; margin: 10px; } </style>

    可以看到,初始的message为10,mounted里+1后变为11,data数据改变,但是没有触发beforedate,这是为什么?原因在于beforedate是针对视图层,视图层的数据发生改变才会触发,我们在模板中加上一个显示标签

    <template> <div id="app"> <p>{{message}}</p> </div> </template>

    这时的结果是:

    beforeUpdate的测试

    如果视图层数据被改变后,会触发beforeUpdate,如果在beforeUpdate里再一次改变数据,此时会再一次触发beforeUpdate吗?

    测试代码如下:

    mounted: function() { console.group('------mounted 挂载结束状态(父)------'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); this.message += 1 console.log("%c%s", "color:red","message: " + this.message); }, beforeUpdate: function () { console.group('beforeUpdate 更新前状态(父)===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); this.message += 1 console.log("%c%s", "color:red","message: " + this.message); }

    可以看到没有,原因和上边一样,mounted改变了message,视图层的message发生变化,此时触发beforeUpdate,尽管beforeUpdate再次改变了message,但此时mounted改变过后的message还没有更新到视图层,因此在beforeUpdate里再次变化message的是没有更新到视图层的message,当然不会再次触发beforeUpdate。

    updated的测试

    那假如在updated里改变数据呢?此时的由mounted改变的message已经跟新至视图层,此时在updated改变message就会触发beforeUpdate。测试代码如下:

    beforeUpdate: function () { console.group('beforeUpdate 更新前状态(父)===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); }, updated: function () { console.group('updated 更新完成状态(父)===============》'); console.log("%c%s", "color:red","el : " + this.$el); console.log(this.$el); console.log("%c%s", "color:red","data : " + this.$data); console.log("%c%s", "color:red","message: " + this.message); this.message = 12 }

    可以看到,在updated里改变message后触发了beforeupdate,如果将

    this.message = 12

    改为

    this.message += 1

    程序将会无限循环下去,陷入死循环

    Processed: 0.009, SQL: 8