「从源码中学习」面试官都不知道的Vue题目答案

论坛 期权论坛     
选择匿名的用户   2021-5-22 15:16   18   0
<div class="article-content">
<h2 class="heading">前言</h2>
<p>当回答面试官问及的Vue问题,我们除了照本宣科的回答外,其实还可以根据少量的源码来秀一把,来体现出你对Vue的深度了解。</p>
<p>本文会陆续更新,此次涉及以下问题:</p>
<ol><li><a href="https://blog.csdn.net/weixin_34138139/article/details/91418559#heading-1">“new Vue()做了什么?”</a></li><li><a href="https://blog.csdn.net/weixin_34138139/article/details/91418559#heading-3">“什么阶段才能访问DOM?”</a></li><li><a href="https://blog.csdn.net/weixin_34138139/article/details/91418559#heading-4">“谈谈你对Vue生命周期的理解。”</a></li><li><a href="https://blog.csdn.net/weixin_34138139/article/details/91418559#heading-5">扩展:新生命周期钩子serverPrefetch是什么?</a></li><li><a href="https://blog.csdn.net/weixin_34138139/article/details/91418559#heading-7">“vue-router路由模式有几种?”</a></li><li><a href="https://blog.csdn.net/weixin_34138139/article/details/91418559#heading-9">“谈谈你对keep-alive的了解?”</a></li><li><a href="https://blog.csdn.net/weixin_34138139/article/details/91418559#heading-10">“了解Vue2.6&#43;新全局API:Vue.observable()吗?”</a></li></ol>
<h2 class="heading">1. “<code>new Vue()</code>做了什么?”</h2>
<p><code>new</code>关键字代表实例化一个对象, 而<code>Vue</code>实际上是一个类, 源码位置是<code>/src/core/instance/index.js</code>。</p>
<pre class="blockcode"><code class="hljs bash copyable"><span class="hljs-keyword">function</span> Vue (options) {
  <span class="hljs-keyword">if</span> (process.env.NODE_ENV !&#61;&#61; <span class="hljs-string">&#39;production&#39;</span> &amp;&amp;
    !(this instanceof Vue)
  ) {
    warn(<span class="hljs-string">&#39;Vue is a constructor and should be called with the &#96;new&#96; keyword&#39;</span>)
  }
  this._init(options)
}
<span class="copy-code-btn">复制代码</span></code></pre>
<p>接着我们跳转追踪至<code>this._init()</code>,即<code>Vue.prototype._init</code>,位于<code>src\core\instance\init.js</code> 在<code>_init()</code>方法的内部有一系列 <code>init*</code> 的方法</p>
<pre class="blockcode"><code class="hljs bash copyable">Vue.prototype._init &#61; <span class="hljs-keyword">function</span> (options?: Object) {
    const vm: Component &#61; this
    // ...忽略,从第45行看起
    <span class="hljs-keyword">if</span> (process.env.NODE_ENV !&#61;&#61; <span class="hljs-string">&#39;production&#39;</span>) {
      initProxy(vm)
    } <span class="hljs-keyword">else</span> {
      vm._renderProxy &#61; vm
    }
    // expose real self
    vm._self &#61; vm
    initLifecycle(vm)
    initEvents(vm)
    initRender(vm)
    callHook(vm, <span class="hljs-string">&#39;beforeCreate&#39;</span>)
    initInjections(vm) // resolve injections before data/props
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, <span class="hljs-string">&#39;created&#39;</span>)
    // ...忽略
    <span class="hljs-keyword">if</span> (vm.<span class="hljs-variable">$options</span>.el) {
      vm.<span class="hljs-variable">$mount</span>(vm.<span class="hljs-variable">$options</span>.el)
    }
  }
}
<span class="copy-code-btn">复制代码</span></code></pre>
<h3 class="heading">1.1 这里我们概述一遍:</h3>
<ol><li><code>initProxy</code>,作用域代理,拦截组件内访问其它组件的数据。</li><li><code>initLifecycle</code>, 建立父子组件关系,在当前实例上添加一些属性和生命周期标识。如:<code>$children</code>、<code>$refs</code>、<code>_isMounted</code>等。</li><li><code>initEvents</code>,用来存放除<code>&#64;hook:生命周期钩子名称&#61;&#34;绑定的函数&#34;</code>事件的对象。如:<code>$on</code>、<code>$emit</code>等。</li><li><code>initRender</code>,用于初始化<code>$slots</code>、<code>$attrs</code>、<code>$listeners</code></li><li><code>initInjections</code>,初始化<code>inject</code>,一般用于更深层次的组件通信,相当于加强版的<code>props</code>。用于组件库开发较多。</li></ol>
<blockquote>
  <p>只要在上一层级的声明的provide,那么下一层级无论多深都能够通过inject来访问到provide的数据。这么做也是有明显的缺点:在任意层级都能访问,导致数据追踪比较困难,不知道是哪一个层级声明了这个或者不知道哪一层级或若干个层级使用。</p>
</blockquote>
<ul><li><code>initState</code>,是很多选项初始化的汇总,包括:<code>props、methods、data、computed 和 watch</code> 等。</li><li><code>initProvide</code>,初始化<code>provide</code>。</li><li><code>vm.$mount</code>,挂载实例。</li></ul>
<h2 class="heading">2. “什么阶段才能访问DOM?”</h2>
<p>这个回答可以从<code>beforeCreate</code>以及 <code>created</code> 的调用时机谈起,我们根据上面的概述,来简化下代码:</p>
<pre class="blockcode"><code class="hljs bash copyable">callHook(vm, <span class="hljs-string">&#39;beforeCreate&#39;</
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP