【Vue实例生命周期】

為{幸葍}努か 提交于 2019-11-28 08:24:31

原文: http://blog.gqylpy.com/gqy/278

有时候,我们需要在实例创建过程中进行一些初始化的工作,以帮助我们完成项目中更复杂更丰富的需求开发,针对这样的需求,Vu e提供给我们一系列的钩子函数。

本文将详细介绍Vue实例在创建和销毁的过程中我们可以使用的钩子函数。

这是官方文档提供的Vue实例生命周期图,我们结合这张图来进行钩子函数的解析。


@
***

实例创建之前执行——beforeCreate

==除标签外,所有的vue需要的数据(data)、事件(methods)、标签(el)都不存在.==

<body> <div id="app">     {{ name }}     <button @click="myClick">点击修改数据</button> </div> <script>     new Vue({         el: '#app',         data: {             name: 'zyk',         },         methods: {             init: function () {                 console.log(this.name);             },             myClick: function () {                 this.name = 'ZYK';             }         },         // 实例创建之前执行         beforeCreate() {             console.group('beforeCreate');             console.log('el:', this.$el);             console.log('data:', this.$data);             console.log('name:', this.name);             console.log('init:', this.init);             console.log('innerHTML:', document.getElementById('app').innerHTML);         },     }); </script> </body>

打印结果如下图:


***

实例创建之后执行——created

==数据和事件被解析到,标签(el)还未被解析.==

<body> <div id="app">     {{ name }}     <button @click="myClick">点击修改数据</button> </div> <script>     new Vue({         el: '#app',         data: {             name: 'zyk',         },         methods: {             init: function () {                 console.log(this.name);             },             myClick: function () {                 this.name = 'ZYK';             }         },         // 实例创建之后执行         created() {             console.group('created');             console.log('el:', this.$el);             console.log('data:', this.$data);             console.log('name:', this.name);             console.log('init:', this.init);             console.log('innerHTML:', document.getElementById('app').innerHTML);         },     }); </script> </body>

打印结果如下图:


***

挂载之前执行——beforeMount

==数据、事件、标签都已被解析,但数据还未被渲染.==

<body> <div id="app">     {{ name }}     <button @click="myClick">点击修改数据</button> </div> <script>     new Vue({         el: '#app',         data: {             name: 'zyk',         },         methods: {             init: function () {                 console.log(this.name);             },             myClick: function () {                 this.name = 'ZYK';             }         },         // 挂载之前执行         beforeMount() {             console.group('beforeMount',);             console.log('el:', this.$el);             console.log('data:', this.$data);             console.log('name:', this.name);             console.log('init:', this.init);             console.log('myClick:', this.myClick);             console.log('innerHTML:', document.getElementById('app').innerHTML);         },     }); </script> </body>

打印结果如下图:


***

挂载之后执行——mounted

==开始渲染数据,开始监听事件.==

<body> <div id="app">     {{ name }}     <button @click="myClick">点击修改数据</button> </div> <script>     new Vue({         el: '#app',         data: {             name: 'zyk',         },         methods: {             init: function () {                 console.log(this.name);             },             myClick: function () {                 this.name = 'ZYK';             }         },         // 挂载之后执行         mounted() {             console.group('mounted',);             console.log('el:', this.$el);             console.log('data:', this.$data);             console.log('name:', this.name);             console.log('init:', this.init);             console.log('myClick:', this.myClick);             console.log('innerHTML:', document.getElementById('app').innerHTML);         },     }); </script> </body>

打印结果如下图:


***

数据更新之前执行——beforeUpdate

==数据己被修改在虚拟DOM,但还未被渲染到页面上==

数据更新时(之前)被调用,发生在虚拟DOM打补丁之前.
适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器.

==该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行.==

<body> <div id="app">     {{ name }}     <button @click="myClick">点击修改数据</button> </div> <script>     new Vue({         el: '#app',         data: {             name: 'zyk',         },         methods: {             init: function () {                 console.log(this.name);             },             myClick: function () {                 this.name = 'ZYK';             }         },         // 数据更新之前执行         beforeUpdate() {             console.group('beforeUpdate',);             console.log('el:', this.$el);             console.log('data:', this.$data);             console.log('name:', this.name);             console.log('init:', this.init);             console.log('myClick:', this.myClick);             console.log('innerHTML:', document.getElementById('app').innerHTML);         },     }); </script> </body>

打印结果如下图:


***

数据更新之后执行——updated

==将虚拟DOM中的数据应用到页面上,此时真实的DOM数据被修改了.==

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

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之.

<body> <div id="app">     {{ name }}     <button @click="myClick">点击修改数据</button> </div> <script>     new Vue({         el: '#app',         data: {             name: 'zyk',         },         methods: {             init: function () {                 console.log(this.name);             },             myClick: function () {                 this.name = 'ZYK';             }         },         // 数据更新之后执行         updated() {             console.group('updated',);             console.log('el:', this.$el);             console.log('data:', this.$data);             console.log('name:', this.name);             console.log('init:', this.init);             console.log('myClick:', this.myClick);             console.log('innerHTML:', document.getElementById('app').innerHTML);         },     }); </script> </body>

打印结果如下图:


***

实例销毁之前执行——beforeDestroy

==所有的数据都存在.==

实例销毁之前调用,在这一步,实例仍然完全可用.
频繁地创建和销毁组件对性能的影响很大,因此可使用activated和deactivated(将在下面介绍这两个钩子).

==该钩子在服务端渲染期间不被调用.==

<body> <div id="app"></div> <script>     let Laside = {         template: `             <div>                 <h1>{{ mes }}</h1>             </div>         `,         data() {             return {                 mes: 'Hello Vue!',             };         },         methods: {             changeData: function () {                 this.mes = 'Pizza is here!';             },         },         // 实例销毁之前执行         beforeDestroy() {             console.log("beforeDestroy");             console.log("el: ", this.$el);             console.log("data: ", this.$data);             console.log("mes: ", this.mes);             console.log("changeData: ", this.changeData);         },     };      let App = {         template: `             <div>                 <Laside v-if="isShow"></Laside>                 <button @click="showHide">创建消除组件</button>             </div>         `,         // 判断是否有嵌套的子组件         components: {             'Laside': Laside,         },         methods: {             showHide: function () {                 this.isShow = !this.isShow;             }         },         data() {             return {                 isShow: true,             };         },     };      new Vue({         el: '#app',         template: `<App/>`,         components: {             App,         },     }); </script> </body>

打印结果如下图:


***

实例销毁之后执行——destroyed

==所有的数据都存在(虚拟DOM找的).==

Vue实例销毁后调用,调用后,Vue实例指示的所有东西都将会解除绑定,所有的事件监听器会被移除,所有的子实例也会被销毁.

<body> <div id="app"></div> <script>     let Laside = {         template: `             <div>                 <h1>{{ mes }}</h1>             </div>         `,         data() {             return {                 mes: 'Hello Vue!',             };         },         methods: {             changeData: function () {                 this.mes = 'Pizza is here!';             },         },         // 实例销毁之后执行         destroyed() {             console.log("destroyed");             console.log("el: ", this.$el);             console.log("data: ", this.$data);             console.log("mes: ", this.mes);             console.log("changeData: ", this.changeData);         },     };      let App = {         template: `             <div>                 <Laside v-if="isShow"></Laside>                 <button @click="showHide">创建消除组件</button>             </div>         `,         // 判断是否有嵌套的子组件         components: {             'Laside': Laside,         },         methods: {             showHide: function () {                 this.isShow = !this.isShow;             }         },         data() {             return {                 isShow: true,             };         },     };      new Vue({         el: '#app',         template: `<App/>`,         components: {             App,         },     }); </script> </body>

打印结果如下图:


***

keep-alive组件激活时执行——activated

Vue提供的用来缓存被消除的标签,keep-alive组件激活时调用.

==使用activated和deactivated可分别取代取代beforeDestroy和destroyed的执行.==

==< keep-alive >包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们.==

<body> <div id="app"></div> <script>     let Laside = {         template: `             <div>                 <h1>{{ mes }}</h1>             </div>         `,         data() {             return {                 mes: 'Hello Vue!',             };         },         methods: {             changeData: function () {                 this.mes = 'Pizza is here!';             },         },         // keep-alive组件激活后不会被调用         beforeDestroy() {             console.log("destroyed");             console.log("el: ", this.$el);             console.log("data: ", this.$data);             console.log("mes: ", this.mes);             console.log("changeData: ", this.changeData);         },         // keep-alive组件激活时执行         activated() {             console.log("destroyed");             console.log("el: ", this.$el);             console.log("data: ", this.$data);             console.log("mes: ", this.mes);             console.log("changeData: ", this.changeData);         },     };      let App = {         // 激活keep-alive组件         template: `             <div>                 <keep-alive>                     <Laside v-if="isShow"></Laside>                 </keep-alive>                 <button @click="showHide">创建消除组件</button>             </div>         `,         // 判断有没有嵌套的子组件         components: {             'Laside': Laside,         },         methods: {             showHide: function () {                 this.isShow = !this.isShow;             },         },         data() {             return {                 isShow: true,             };         },     };      new Vue({         el: '#app',         template: `<App/>`,         components: {             App,         },     }); </script> </body>

打印结果如下图:


***

keep-alive组件停用时执行——deactivated

<body> <div id="app"></div> <script>     let Laside = {         template: `             <div>                 <h1>{{ mes }}</h1>             </div>         `,         data() {             return {                 mes: 'Hello Vue!',             };         },         methods: {             changeData: function () {                 this.mes = 'Pizza is here!';             },         },         // keep-alive组件停用时执行         deactivated() {             console.log("destroyed");             console.log("el: ", this.$el);             console.log("data: ", this.$data);             console.log("mes: ", this.mes);             console.log("changeData: ", this.changeData);         },     };      let App = {         // 激活keep-alive组件         template: `             <div>                 <keep-alive>                     <Laside v-if="isShow"></Laside>                 </keep-alive>                 <button @click="showHide">创建消除组件</button>             </div>         `,         // 判断有没有嵌套的子组件         components: {             'Laside': Laside,         },         methods: {             showHide: function () {                 this.isShow = !this.isShow;             },         },         data() {             return {                 isShow: true,             };         },     };      new Vue({         el: '#app',         template: `<App/>`,         components: {             App,         },     }); </script> </body>

打印结果如下图:



原文: http://blog.gqylpy.com/gqy/278

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!