Vue LifeCycle

MVVM

MVVM是Model-View-ViewModel的缩写

  • Model代表数据模型,可在Model中定义数据修改等操作的业务逻辑。
  • View代表UI界面组件,负责将数据模型Model转化为UI进行展示。
  • ViewModel表示监听模型中数据的改变并控制视图的行为,用于处理用户交互。简单来说,ViewModel是一个同步View和Model的对象,用来连接View和Model。
4933701-34f1b00a91c9a079.png
MVVM

MVVM架构中View和Model之间并没有直接的联系,而是通过ViewModel进行交互。

Model和ViewModel之间的交互是双向的,因此View上数据的变化会同步到Model中,而Model数据的变化也会立即反映到View上。

ViewModel通过双向数据绑定将View层和Model层连接起来,而View和Model之间的同步工作完全是自动的,无需人为干预。开发者只需要关注业务逻辑,无需手动操作DOM,无需关注数据状态的同步问题,复杂的数据状态维护完全由MVVM来统一管理。

Vue双向数据绑定

Vue最显著的两个核心是数据驱动和组件系统

Vue实现数据双向绑定的原理是Object.defineProperty()方法,即采用数据劫持并结合发布者-订阅者模式,通过Object.defineProperty()方法来劫持属性的setter/getter。当数据变动时发布消息给订阅者,触发对应监听回调。当将一个普通的JavaScript对象传递给Vue实例作为data选项时,Vue会遍历其属性,并使用Object.defineProperty()方法将他们转换为getter/setter。用户是看不到setter/getter方法,但在内部它们会让Vue追踪依赖,在属性被访问和修改时会通知其变化。

4933701-3e790f93b19413f9.png
数据绑定

Vue的数据双向绑定会见MVVM作为数据绑定的入口,整合Observer、Compile、Watcher三者,通过Observer来监听自己Model数据的变化,通过Compile解析编译模板指令,最终利用Watcher搭建起Observer和Compile之间的通信桥梁,以达到数据变化视图更新,视图交互变化数据模型Model变更的双向绑定效果。

Vue生命周期

Vue实例都具有一个完整的生命周期,从开始创建、初始化数据、编译模板、挂载DOM、渲染更新渲染、卸载等一系列的过程。简单来说,就是Vue实例从创建到销毁的过程。

为什么会存在Vue的生命周期呢?Vue生命周期的作用是因为其生命周期内存在多个事件钩子,用以控制整个Vue实例的过程时更容易形成清晰的逻辑。Vue实例生命周期中,提供了一系列事件,使其在事件触发时注册JS方法,以使用自己注册的JS方法控制整个大局,在这些事件响应方法中this直接指向的是Vue实例。

Vue生命周期可分为4大阶段8小阶段,分别是

  • 创建前后beforeCreate/created
  • 载入前后beforeMount/mounted
  • 更新前后beforeUpdate/updated
  • 销毁前后beforeDestroy/destroyed

当第一次页面加载时会触发beforeCreatecreatedbeforeMountmounted钩子函数,DOM渲染则在mounted中就已经完成了。

Vue实例生命周期钩子

每个Vue实例在被创建时都需经过一系列初始化过程,例如,设置数据监听、编译模板、将实例挂在到DOM并在数据变化时更新DOM等。同时在此过程中也会运行一些称为生命周期钩子的函数,以方便用户在不同阶段添加代码。

钩子描述
beforeCreate组件实例刚刚被创建,组件属性计算之前。
created用来在实例创建之后执行代码,组件实例创建完成,属性已绑定,DOOM未生成,$el属性不存在。
beforeMount模板编译或挂载之前
mounted模板编译或挂载之后,此时并不能保证组件已在document中。
beforeUpdate组件更新之前
updated组件更新之后
beforeDestroy组件销毁前调用
destroyed组件销毁后调用

生命周期钩子是在Vue对象生命周期的某个阶段执行的已定义的方法,从初始化到被销毁,对象都会遵循不同的生命阶段。

4933701-98875a2679ca449f.png
Vue实例生命周期
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>vue</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <input type="text" v-model="input.msg" ref="msg" />
        <button @click="onHandle">更新</button>
    </div>
    <script>
        const vm = new Vue({
            //DOM
            el:"#app",
            //数据
            data(){
                return {
                    input:{msg:"hello world"}
                };
            },
            //生命周期钩子函数
            beforeCreate(){
                console.log(1, "before create", this.$el, this.input);
            },
            created(){
                console.log(2, "created", this.$el, this.input);
            },
            beforeMount(){
                this.$set(this.input, "msg", "helo");
                console.log(3, "before mount", this.$el, this.input);
            },
            mounted(){
                console.log(4, "mounted", this.$el, this.input, this.$refs.msg);
            },
            beforeUpdate(){
                console.log(5, "before update", this.$el, this.input);
            },
            updated(){
                console.log(6, "updated", this.$el, this.input);
            },
            beforeDestroy(){
                console.log(7, "before destroy", this.$el, this.input);
            },
            destroyed(){
                console.log(8, "destroyed", this.$el, this.input);
            },
            //
            methods:{
                onHandle(){
                    this.input.msg = "hi";
                }
            }
        });
    </script>
</body>
</html>

Vue内置方法属性和生命周期的运行顺序

运行顺序属性方法
1props
2methods
3data
4computed
5watch

创建期间的生命周期函数

创建前beforeCreate

  • 组件创建会执行生命周期函数beforeCreate,可在当前生命周期中创建一个Loading,当页面加载完成后再移除Loading。
  • beforeCreate在当前生命周期函数中是访问不到其他生命周期函数以及data属性的。

Vue实例化后会创建一个Vue类的对象用来处理DOM元素,这个对象的生命周期可以通过beforeCreate钩子函数来访问。

Vue实例刚从内存中被创建出来,此时还没有初始化好datamethods属性。

在Vue实例初始化之后,数据观测data observerevent/watcher事件配置之前被调用。

beforeCreate实例创建前会遍历data对象下所有属性并将其转化为setter/getter,也就是为其添加一个被观察者,后续添加新属性时视图不用更新即可使用,后续添加的属性并不会放到观察者对象中,此时数据并没有和模板建立联系,因此不能操作该属性。如果要在实例挂在完成后使添加的属性触发视图的更新,可使用$set方法,$set方法会向被观察者对象中新增自定义的属性。

创建后created

  • 当created生命周期函数执行时会将data和methods身上的属性和方法添加到vm实例上
  • created执行时会遍历data的属性并为属性添加setter和getter方法
  • 可以在created生命周期函数中发起AJAX数据请求

created阶段,对象及其事件已经完全初始化, created是访问此阶段并编写代码的钩子,简单来说,此阶段是具有默认特性的对象。

Vue实例已经创建完成后被调用,在这一步Vue实例已经完成配置:数据观测(data observer)、属性和方法的运算(computed)、watch/event事件回调。然而,挂载阶段还没开始,$el属性目前尚不可见。

在模板渲染成HTML前调用,即通常初始化某些属性值,然后再渲染成视图。

Vue实例已经在内存中创建完成,此时datamethods已经创建完成,此时还未开始编译模板。

created阶段Vue实例已经被创建完毕,属性已经绑定,属性是可以操作的。但DOM还不存在,$el属性也还不可以操作。此时也可以使用axios请求,但页面还未被渲染出来,若请求时间过长则会出现长时间的白屏的现象,因此推荐添加Loading界面。

挂载前 beforeMount

  • 生命周期函数beforeMount可以对data中的数据做最后修改
  • beforeMount生命周期函数中添加的属性没有settergetter方法,若需要则需使用$set方法。
  • beforeMount生命周期函数中模板和数据未进行结合

beforeMount钩子调用阶段会检查是否具有模板用于要在DOM中呈现的对象,若没有模板则将定义元素的外部HTML视为模板。

beforeMount在挂载开始之前被调用,相关的render函数首次被调用。beforeMount阶段已经完成了模板的编译但还未挂在到页面中。

挂载后mounted

  • mounted挂载后数据和模板会进行结合并生成真正的DOM结构
  • mounted函数中可访问到真实的DOM结构
  • mounted函数中可用于插件实例化

一旦模板准备就绪,就会将数据放入模板并创建可呈现元素。使用新数据填充元素替换DOM元素。mounted钩子表示DOM已准备就绪并放置到页面中。

el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。

在模板渲染成HTML后调用,通常是初始化页面完成后,再对HTML的DOM节点进行一些需要的操作。

mounted阶段此时已经将编译好的模板挂载到了页面指定的容器中显示。

运行期间的生命周期函数

更新前beforeUpdate

  • beforeUpdate会多次执行,当数据更新前会执行。
  • beforeUpdate更新前数据还未和模板结合,可在此函数中做更新数据的最后修改。

当外部事件或用户输入时,beforeUpdate钩子在反映原始DOM元素的更改之前被触发,此阶段表示更改已经完成,但尚未准备好更新DOM。

数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。可以在狗子中进一步地更改状态,这不会出发附加的重渲染过程。

状态更新之前执行beforeUpdate钩子函数,此时data中的状态值是最新的,但界面上显示的数据还是旧的,因为此时还没有开始重新渲染DOM节点。

更新后updated

  • updated函数是更新的数据和模板进行组合的位置
  • 可在updated函数中获取到数据更新后最新的DOM结构
  • 可在updated函数中做插件的实例化,但需添加判断条件否则会非常消耗性能。

updated钩子表示在DOM中程序的更改,通过实际更新DOM对象并触发updated方法,屏幕上的变化才得以呈现。

由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。

当这个钩子被调用时,组件DOM已经更新,所以现在可以执行依赖于DOM的操作。然而大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。

updated函数在Vue实例更新完毕后调用,此时data中的状态值和界面上显示的数据都已经完成了更新,界面已经被重新渲染好了。

销毁期间的生命周期函数

销毁前beforeDestroy

  • beforeDestroy函数中可访问到真实的DOM结构,可在当前生命周期函数中做事件的解绑、监听移除等操作。

当Vue对象被破坏并从内存中释放之前beforeDestroy钩子被触发

Vue实例销毁之前调用,在这一步中Vue实例仍然完全可用。

beforeDestroy钩子函数在Vue实力销毁之前调用,此时Vue实力仍然完全可用。

销毁后destroyed

  • destroyed函数执行时会将vm和模板之间的关联断开
  • destroyed函数中无法通过ref访问到真实DOM结构

destroyed钩子被成功运行销毁对象上调用,对象停止并从内存中删除。

Vue实例销毁后调用,调用后Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不会被调用。

destroyed钩子函数在Vue实例销毁后调用,调用后Vue实例指向会解除绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

created 与 mounted

  • beforeCreatedeldata并未初始化
  • created阶段完成data数据的初始化,此时el还不存在。
  • beforeMount阶段完成了eldata的初始化
  • mounted阶段完成挂载。

created在模板渲染成HTML前调用,即通常初始化某些属性值,然后再渲染成视图。

mounted在模板渲染成HTML后调用,通常是初始化页面完成后再对HTML的DOM节点进行一些需要的操作。

通常created使用的次数多,而mounted通常是在一些插件的使用或组件的使用中进行操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值