脚本宝典收集整理的这篇文章主要介绍了

Vue 进阶 (一)

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。
<blockquote><p><a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a>进阶系列 参考至 <a href="https://github.com/answershuto/VueDemo" rel="nofollow noreferrer" target="_blank">VueDemo</a> </p></blockquote> <h2 id="articleHeader0"><a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a> 运行机制全局概览</h2> <p>内部流程图:</p> <p><span class="img-wrap"><img data-src="/img/remote/1460000015858420" src="/img/remote/1460000015858420" alt="" title="" style="cursor: pointer; display: inline;"></span></p> <p><strong>一、初始化和挂载</strong></p> <p><span class="img-wrap"><img data-src="/img/remote/1460000015858421" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <p>1- <code>初始化</code></p> <p><code>new <a href="http://www.js-code.com/tag/vue" title="浏览关于“Vue”的文章" target="_blank" class="tag_link">Vue</a>()</code>之后会调用 <code>init</code>初始化函数。它会初始化生命周期、时间、methods、data、computed、watch等。</p> <ul> <li>Vue的数据响应。</li> </ul> <p>是通过<code>Object.define<a href="http://www.js-code.com/tag/prop" title="Prop" target="_blank">Prop</a>erty</code>设置 <code>getter</code> 和 <code>setter</code>函数,来实现【响应式】和【依赖收集】。 </p> <p>2- <code>挂载</code></p> <p>初始化后调用<code>$mount</code> 会挂载组件,随后经过编译,通过<code>render function</code> 。如果是运行时编译,那么就不需要<code>render function</code>。</p> <p>但是如果时存在<code>template</code>的情况, 就是需要进行<code>【编译】</code>步骤了。</p> <p><strong>二、编译</strong></p> <p><span class="img-wrap"><img data-src="/img/remote/1460000015858422" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <p>编译分为三个阶段,<code>parse</code> <code>optimize</code> <code>generate</code>.最终需要得到 <code>render function</code>。</p> <ul> <li>parse 【解析器】</li> </ul> <p><code>parse </code>会用正则等方式解析 template 模板中的指令、class、style等数据,形成AST。</p> <ul> <li>optimize 【优化器】</li> </ul> <p><code>optimize</code> 的主要作用是标记 static 静态节点,这是 Vue 在编译过程中的一处优化,后面当 <code>update</code> 更新界面时,会有一个 <code>patch</code> 的过程, <code>diff</code> 算法会直接跳过静态节点,从而减少了比较的过程,优化了 patch 的性能。</p> <ul> <li>generate 【代码生成器】</li> </ul> <p><code>generate</code> 是将<code>AST</code>转换为<code>render function </code>字符串的过程。得到结果的是<code>render function </code>的字符串,以及 <code>staticRenderFns</code> 字符串。</p> <blockquote><p>经过编译的三个阶段后,组件中就会出现渲染VNode 的 <code>render function</code> </p></blockquote> <p><strong>三、响应式</strong></p> <p><span class="img-wrap"><img data-src="/img/remote/1460000015858423" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <p>这里的 <code>getter</code> 跟 <code>setter</code> 已经在之前介绍过了,在 <code>init</code> 的时候通过 <code>Object.define<a href="http://www.js-code.com/tag/prop" title="Prop" target="_blank">Prop</a>erty</code> 进行了绑定,它使得当被设置的对象被读取的时候会执行 <code>getter</code> 函数,而在当被赋值的时候会执行 <code>setter </code>函数。</p> <p>当渲染的时候,需要所需的值,因此会通过getter来进行【依赖搜集】。</p> <p><span class="img-wrap"><img data-src="/img/remote/1460000015858424" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <p>将数据的观察者对象 <code>Watcher</code>对象存放在<code>Dep</code>中,这样当数据发生变化的时候,就会出发<code>setter</code>. setter 通知之前的【依赖搜集】得到的Dep中的<code>watcher</code>对象,如果需要重新渲染试图,watcher 就会调用<code>update</code>来更新<a href="http://www.js-code.com/tag/dom" title="DOM" target="_blank">DOM</a>。当然中间还有<code>patch</code>过程。</p> <p><strong>四、Virtual <a href="http://www.js-code.com/tag/dom" title="DOM" target="_blank">DOM</a> 虚拟<a href="http://www.js-code.com/tag/dom" title="浏览关于“DOM”的文章" target="_blank" class="tag_link">DOM</a></strong></p> <p>我们知道<code>render function</code>会转换成虚拟DOM节点。Virtual DOM 其实是一颗以javascript对象作为基础的树。<br />实际上就是对真实DOM树的一个抽象表示。最终虚拟DOM会通过一系列的操作得到真实的DOM。</p> <p>由于 Virtual DOM 是以 JavaScript 对象为基础而不依赖真实平台环境,所以使它具有了跨平台的能力,比如说浏览器平台、Weex、Node 等。</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="{ tag: 'div', children: [ { tag: 'a', text: 'love me' } ] }" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js">{ <span class="hljs-attr">tag</span>: <span class="hljs-string">'<a href="http://www.js-code.com/tag/div" title="浏览关于“div”的文章" target="_blank" class="tag_link">div</a>'</span>, <span class="hljs-attr">children</span>: [ { <span class="hljs-attr">tag</span>: <span class="hljs-string">'a'</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">'love me'</span> } ] }</code></pre> <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="// 渲染为 <div> <a>love me</a> </div> <p>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="xml hljs"><code class="html">// 渲染为 <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">a</span>&gt;</span>love me<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></code></pre> <p>实际上节点有许许多多的属性,比如<code>isStatic</code>代表是否为静态节点。 <code>isComment</code> 代表是否注释节点。</p> <p><strong>五、更新渲染</strong></p> <p><span class="img-wrap"><img data-src="/img/remote/1460000015858425" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <p>会通过 <code>setter -&gt; Watcher -&gt; update</code> 的流程来修改对应的视图,那么最终是如何更新视图的呢?</p> <p>当数据变化后,执行 <code>render function</code> 就可以得到一个新的 <code>VNode </code>节点,我们如果想要得到新的视图,最简单粗暴的方法就是直接解析这个新的<code> VNode</code> 节点,然后用 <code>inner<a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a></code> 直接全部渲染到真实 DOM 中。但是其实我们只对其中的一小块内容进行了修改,这样做似乎有些「浪费」。</p> <div class="google-auto-placed ap_container" style="text-align: center; width: 100%; height: auto; clear: none;"><ins data-ad-format="auto" class="adsbygoogle adsbygoogle-noablate" data-ad-client="ca-pub-6330872677300335" data-adsbygoogle-status="done" style="display: block; margin: auto; background-color: transparent;"><ins id="aswift_4_expand" style="display: inline-table; border: none; height: 0px; margin: 0px; padding: 0px; position: relative; visibility: visible; width: 697px; background-color: transparent;"><ins id="aswift_4_anchor" style="display: block; border: none; height: 0px; margin: 0px; padding: 0px; position: relative; visibility: visible; width: 697px; background-color: transparent; overflow: hidden; opacity: 0;"><iframe width="697" height="175" frameborder="0" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" allowfullscreen="true" onload="var i=this.id,s=window.google_iframe_oncopy,H=s&amp;&amp;s.handlers,h=H&amp;&amp;H[i],w=this.contentWindow,d;try{d=w.document}catch(e){}if(h&amp;&amp;d&amp;&amp;(!d.body||!d.body.firstChild)){if(h.call){setTimeout(h,0)}else if(h.match){try{h=s.upd(h,i)}catch(e){}w.location.replace(h)}}" id="aswift_4" name="aswift_4" style="left:0;position:absolute;top:0;border:0px;width:697px;height:175px;"></iframe></ins></ins></ins></div> <p>这就要说到<code>patch</code> 了。我们会将新的 <code>VNode</code> 与旧的 <code>VNode</code> 一起传入 <code>patch</code> 进行比较,经过 <code>diff</code> 算法得出它们的「<code>差异</code>」。最后我们只需要将这些「<code>差异</code>」的对应 DOM 进行修改即可。</p> <hr> <blockquote><p>再看全局</p></blockquote> <p><span class="img-wrap"><img data-src="/img/remote/1460000015858420" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" title="" style="cursor: pointer;"></span></p> <p><strong>接下来我们继续深入学习吧,加油~~</strong></p>

总结

以上是脚本宝典为你收集整理的

Vue 进阶 (一)

全部内容,希望文章能够帮你解决

Vue 进阶 (一)

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过