<p><code></p> <p>“你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。” </p> <p>现在项目中遇到了,好好回头总结一波<a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a>生命周期,以后用到的时候再来翻翻。</p> <h2 id="articleHeader0">啥叫<a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a>生命周期?</h2> <p>每个 <a href="http://www.js-code.com/tag/vue" title="浏览关于“Vue”的文章" target="_blank" class="tag_link">Vue</a> 实例在被创建时都要经过一系列的初始化过程。</p> <p>例如:从开始创建、初始化数据、编译模板、挂载Dom、数据变化时更新<a href="http://www.js-code.com/tag/dom" title="DOM" target="_blank">DOM</a>、卸载等一系列过程。</p> <p>我们称 <strong>这一系列的过程</strong> 就是Vue的生命周期。</p> <p>通俗说就是Vue实例从创建到销毁的过程,就是生命周期。</p> <p>同时在这个过程中也会运行一些叫做<strong><a href="http://www.js-code.com/tag/%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f%e9%92%a9%e5%ad%90" title="生命周期钩子" target="_blank">生命周期钩子</a></strong>的函数,这给了用户在不同阶段添加自己的代码的机会,利用各个钩子来完成我们的业务代码。</p> <h2 id="articleHeader1">啥也不说,先来个干货</h2> <p>这是对于Vue生命周期,官网给的那张图的标注图,图片网上看到的,我觉得标注地很nice,建议一步步仔细看完图片,然后把图片自己悄悄保存下来,对照着图片的内容看第二部分的举例说明。</p> <p><span class="img-wrap"><img data-src="/img/remote/1460000016841233?w=1200&amp;h=3039" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <h2 id="articleHeader2">我相信程序员看代码比看文字更容易理解</h2> <p>对照着上图标注的内容,我们一个钩子一个钩子地举例说明。</p> <h3 id="articleHeader3">1.beforeCreate</h3> <p>实例初始化之后、创建实例之前的执行的钩子事件。<br />如下例子:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<body></p> <div id=&quot;root&quot;>{{test}}</div> <p><script type=&quot;text/javascript&quot;> <a href="http://www.js-code.com/tag/const" title="const" target="_blank">const</a> vm = new Vue({ el: '#root', data: { test: '天王盖地虎' }, beforeCreate() { console.log('beforeCreate钩子事件:'); console.log($<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>.data); console.log($<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>.el); } }) </script><br /> </body>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs xml"><code><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name"><a href="http://www.js-code.com/tag/div" title="浏览关于“div”的文章" target="_blank" class="tag_link">div</a></span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>&gt;</span>{{test}}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span>&gt;</span><span class="javascript"> <span class="hljs-keyword"><a href="http://www.js-code.com/tag/const" title="浏览关于“const”的文章" target="_blank" class="tag_link">const</a></span> vm = <span class="hljs-keyword">new</span> Vue({ <span class="hljs-attr">el</span>: <span class="hljs-string">'#root'</span>, <span class="hljs-attr">data</span>: { <span class="hljs-attr">test</span>: <span class="hljs-string">'天王盖地虎'</span> }, beforeCreate() { <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'beforeCreate钩子事件:'</span>); <span class="hljs-built_in">console</span>.log($<span class="hljs-keyword"><a href="http://www.js-code.com/tag/this" title="浏览关于“this”的文章" target="_blank" class="tag_link">this</a></span>.data); <span class="hljs-built_in">console</span>.log($<span class="hljs-keyword">this</span>.el); } }) </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span></code></pre> <p>得到的结果是:</p> <p><span class="img-wrap"><img data-src="/img/remote/1460000016841234?w=279&amp;h=120" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <p><strong>小总结</strong>:创建实例之前,数据观察和事件配置都没好准备好。也就是数据也没有、<a href="http://www.js-code.com/tag/dom" title="DOM" target="_blank">DOM</a>也没生成。</p> <h3 id="articleHeader4">2.created</h3> <p>实例创建完成后执行的钩子 <br />在上一段代码例子中,我们再来console一下。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<body></p> <div id=&quot;root&quot;>{{test}}</div> <p><script type=&quot;text/javascript&quot;> <a href="http://www.js-code.com/tag/const" title="const" target="_blank">const</a> vm = new Vue({ el: '#root', data: { test: '天王盖地虎' }, created() { console.log('created钩子事件:'); console.log(this.$data); console.log(this.$el); } }) </script><br /> </body>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs xml"><code><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</span>&gt;</span>{{test}}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span>&gt;</span><span class="javascript"> <span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue({ <span class="hljs-attr">el</span>: <span class="hljs-string">'#root'</span>, <span class="hljs-attr">data</span>: { <span class="hljs-attr">test</span>: <span class="hljs-string">'天王盖地虎'</span> }, created() { <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'created钩子事件:'</span>); <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.$data); <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.$el); } }) </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span></code></pre> <p>得到的结果是:<br /><span class="img-wrap"><img data-src="/img/remote/1460000016841235?w=309&amp;h=124" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <p><strong>小总结</strong>:实例创建完成后,我们能读取到数据data的值,但是<a href="http://www.js-code.com/tag/dom" title="浏览关于“DOM”的文章" target="_blank" class="tag_link">DOM</a>还没生成,挂载属性el还不存在。</p> <h3 id="articleHeader5">3.beforeMount</h3> <p>将编译完成的html挂载到对应的<strong>虚拟DOM</strong>时触发的钩子<br />此时页面并没有内容。<br />即此阶段解读为: 即将挂载<br />我们打印下此时的$el</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="beforeMount() { console.log('beforeMount钩子事件:'); console.log(this.$el); }" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs typescript"><code>beforeMount() { <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'beforeMount钩子事件:'</span>); <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.$el); }</code></pre> <p>得到的结果是:<br /><span class="img-wrap"><img data-src="/img/remote/1460000016841236?w=342&amp;h=129" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <p><strong>小总结</strong>:此时的el不再是undefined,成功关联到我们指定的dom节点。但是此时的{{test}}还没有成功渲染成data中的数据,页面没有内容。</p> <p>PS:相关的render函数首次被调用。</p> <h3 id="articleHeader6">4.mounted</h3> <p>编译好的html挂载到页面完成后所执行的事件钩子函数。</p> <p>此时的阶段解读为: 挂载完毕阶段</p> <p>我们再打印下此时$el看看:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="mounted() { console.log('mounted钩子事件:'); console.log(this.$el); }" title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs typescript"><code>mounted() { <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'mounted钩子事件:'</span>); <span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">this</span>.$el); }</code></pre> <p>得到的结果是:</p> <p><span class="img-wrap"><img data-src="/img/remote/1460000016841237?w=295&amp;h=130" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <p>可见, {{test}}已经成功渲染成data里面test对应的值“天王盖地虎”了。</p> <p><strong>小总结</strong>:此时编译好的<a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a>已经挂载到了页面上,页面上已经渲染出了数据。一般会利用这个钩子函数做一些ajax请求获取数据进行数据初始化。<br />PS:mounted在整个实例中只执行一次。</p> <h3 id="articleHeader7">5.beforeUpdate</h3> <p><strong>小总结</strong>:当修改vue实例的data时,vue就会自动帮我们更新渲染视图,在这个过程中,vue提供了beforeUpdate的钩子给我们,在检测到我们要修改数据的时候,更新渲染视图之前就会触发钩子beforeUpdate。</p> <h3 id="articleHeader8">6.updated</h3> <p><strong>小总结</strong>:此阶段为更新渲染视图之后,此时再读取视图上的内容,已经是最新的内容。</p> <p>PS:<br />1、该钩子在服务器端渲染期间不被调用。<br />2、应该避免在此期间更改状态,因为这可能会导致更新无限循环。</p> <h3 id="articleHeader9">7.beforeDestroy</h3> <p><strong>小总结</strong>:调用实例的destroy( )方法可以销毁当前的组件,在销毁前,会触发beforeDestroy钩子。</p> <h3 id="articleHeader10">8.destroyed</h3> <p><strong>小总结</strong>:成功销毁之后,会触发destroyed钩子,此时该实例与其他实例的关联已经被清除,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。</p> <h2 id="articleHeader11">话在最后</h2> <p>其实还有三个<a href="http://www.js-code.com/tag/%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f%e9%92%a9%e5%ad%90" title="生命周期钩子" target="_blank">生命周期钩子</a>没列出来:activated、deactivated、errorCaptured。这三个大家遇到了自行了解哈,暂且这样吧。</p> <p></code></p>

本文固定链接: http://www.js-code.com/vue-js/vue-js_26652.html