每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会( Vue.js官网教程 )。

Vue实例基础生命周期函数共有8个,分别为“创建之前(beforeCreate)”、“创建完成(created)”、“挂载之前(beforeMount)”、“挂载完成(mounted)”、“更新之前(beforeUpdate)”、“更新完成(updated)”、“销毁之前(beforeDestroy)”、“销毁完成(destroyed)”。

每天,带着好心情去学习(图片来自 Pinterest

以下示例代码用来演示各个生命周期钩子函数。

<body>
    <div id="app" v-on:click="changeHtml">{{text}}</div>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                text: "foo bar"
            },
            methods: {
                changeHtml() {
                    this.text = this.text.split(' ').reverse().join(' ');
                }
            }
        })
    </script>
</body>

当执行 new Vue() 操作之后,实例将被初始化,随后自动调用 beforeCreate() 钩子函数。这一阶段数据监听还未开启(还未将数据加入 Vue 的响应式系统),无法操作 data 属性内的数据。

beforeCreate() {
                console.log("It is before created");
                console.log(this.text);//输出 undefined
}

执行完 beforeCreate 阶段后,Vue 实例将设置数据监听、watch/event 事件回调、属性和方法的运算,随后调用 created() 钩子函数,说明至此实例已经创建完成。此时还未执行挂载阶段,$el 属性不可见。

created() {
                console.log("It is created");
                console.log(this.text);//输出 foo bar
                console.log(this.$el);//输出 undefined
}

接下来 Vue 会判断实例中是否有 el (挂载点)属性,如果有,则接着判断是否有 template(模板) 属性,如果有,则把此 template 编译进渲染(render)函数等待实例挂载。如果存在 el 属性不存在 template 属性,则将整个 el 属性指代的元素当成实例模板进行编译。如果不存在 el 属性,则等待 vm.$mount(el) 函数被手动调用来确定挂载点。

beforeMount() {
                console.log("It is before mounted");
                console.log(this.text);//输出 foo bar
                console.log(this.$el);//输出 <div id="app" v-on:click="changeHtml">
}

执行挂载阶段:原始 DOM 元素 el 被新创建的虚拟 DOM vm.$el 替换,随后挂载至 Vue 实例,mounted() 钩子函数被调用。

数据更新阶段:beforeUpdate 钩子发生在数据更新时,可以在这个时候访问现有的 DOM。

beforeUpdate() {
                console.log("It is before updated");
                console.log(this.text);//输出 bar foo(数据已改变)
                console.log(document.getElementById("app").innerHTML);//输出 foo bar(DOM 还未更新)
}

updated 钩子发生在虚拟 DOM 重新渲染之后。

updated() {
                console.log("It is updated");
                console.log(this.text);//输出 bar foo
                console.log(document.getElementById("app").innerHTML);//输出 bar foo(DOM 已更新)
}

实例销毁阶段:beforeDestroy 钩子发生在实例销毁之前,此时实例仍然完全可用。经测试,此时数据仍可修改,但是响应式系统已失效,视图不再随着数据变化而更新。

beforeDestroy() {
                console.log("It is before destroyed");
                console.log(this.text);//输出 bar foo
                this.text = "before destroyed";//执行数据修改
                console.log(this.text);//输出 before destroyed
                console.log(document.getElementById("app").innerHTML);//输出 bar foo
}

destroyed 钩子发生在实例销毁之后, 调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁,但是数据仍然存在并可修改,效果同上 beforeDestroy 阶段,此时再点击 DOM 不会有任何反应。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据