「从源码中学习」面试官都不知道的Vue题目答案
前言
當(dāng)回答面試官問(wèn)及的Vue問(wèn)題,我們除了照本宣科的回答外,其實(shí)還可以根據(jù)少量的源碼來(lái)秀一把,來(lái)體現(xiàn)出你對(duì)Vue的深度了解。
本文會(huì)陸續(xù)更新,此次涉及以下問(wèn)題:
1. “new Vue()做了什么?”
new關(guān)鍵字代表實(shí)例化一個(gè)對(duì)象, 而Vue實(shí)際上是一個(gè)類(lèi), 源碼位置是/src/core/instance/index.js。
function Vue (options) {if (process.env.NODE_ENV !== 'production' &&!(this instanceof Vue)) {warn('Vue is a constructor and should be called with the `new` keyword')}this._init(options) } 復(fù)制代碼接著我們跳轉(zhuǎn)追蹤至this._init(),即Vue.prototype._init,位于src\core\instance\init.js 在_init()方法的內(nèi)部有一系列 init* 的方法
Vue.prototype._init = function (options?: Object) {const vm: Component = this// ...忽略,從第45行看起if (process.env.NODE_ENV !== 'production') {initProxy(vm)} else {vm._renderProxy = vm}// expose real selfvm._self = vminitLifecycle(vm)initEvents(vm)initRender(vm)callHook(vm, 'beforeCreate')initInjections(vm) // resolve injections before data/propsinitState(vm)initProvide(vm) // resolve provide after data/propscallHook(vm, 'created')// ...忽略if (vm.$options.el) {vm.$mount(vm.$options.el)}} } 復(fù)制代碼1.1 這里我們概述一遍:
只要在上一層級(jí)的聲明的provide,那么下一層級(jí)無(wú)論多深都能夠通過(guò)inject來(lái)訪問(wèn)到provide的數(shù)據(jù)。這么做也是有明顯的缺點(diǎn):在任意層級(jí)都能訪問(wèn),導(dǎo)致數(shù)據(jù)追蹤比較困難,不知道是哪一個(gè)層級(jí)聲明了這個(gè)或者不知道哪一層級(jí)或若干個(gè)層級(jí)使用。
- initState,是很多選項(xiàng)初始化的匯總,包括:props、methods、data、computed 和 watch 等。
- initProvide,初始化provide。
- vm.$mount,掛載實(shí)例。
2. “什么階段才能訪問(wèn)DOM?”
這個(gè)回答可以從beforeCreate以及 created 的調(diào)用時(shí)機(jī)談起,我們根據(jù)上面的概述,來(lái)簡(jiǎn)化下代碼:
callHook(vm, 'beforeCreate') // 初始化 inject // 初始化 props、methods、data、computed 和 watch // 初始化 provide callHook(vm, 'created') // 掛載實(shí)例 vm.$mount(vm.$options.el) 復(fù)制代碼所以當(dāng)面試官問(wèn)你:
- beforeCreate以及 created 調(diào)用時(shí),哪些數(shù)據(jù)能用與否?
- 什么階段才能訪問(wèn)DOM?
- 為什么created之后才掛載實(shí)例?
知道怎么回答了吧。
3. “談?wù)勀銓?duì)Vue的生命周期的理解”
常規(guī)回答這里就不說(shuō)了,來(lái)稍微深入點(diǎn)的:
于是,你可以答多activated & deactivated(keep-alive 組件激活/停用)、errorCaptured(v2.5 以上版本有的一個(gè)鉤子,用于處理錯(cuò)誤)這三個(gè)。
3.1 新生命周期鉤子:serverPrefetch是什么?
可以看到,serverPrefetch前身是ssrPrefetch。顧名思義,這是用來(lái)處理ssr的。允許我們?cè)阡秩具^(guò)程中“等待”異步數(shù)據(jù)。可在任何組件中使用,而不僅僅是路由組件。
這里我們貼出一段官方例子: <!-- Item.vue --> <template><div v-if="item">{{ item.title }}</div><div v-else>...</div> </template><script> export default {computed: {item () {return this.$store.state.items[this.$route.params.id]}},serverPrefetch () {return this.fetchItem()},mounted () {if (!this.item) {this.fetchItem()}},methods: {fetchItem () {// return the Promise from the actionreturn this.$store.dispatch('fetchItem', this.$route.params.id)}} } </script> 復(fù)制代碼- 絕大多數(shù)的面試官都不會(huì)去關(guān)注v2.6+ 以后的代碼記錄和變更。這里如果你說(shuō)出這個(gè)v2.6.10的變化,嘖嘖...面試官肯定更加欣賞你。
3.2 生命周期鉤子的合并策略
拿callHook(vm, 'created')講,先判斷組件的選項(xiàng)中有無(wú)對(duì)應(yīng)名字的生命周期鉤子,再判斷是否有 parentVal(vm)。若存在parentVal(vm)且都有對(duì)應(yīng)的生命周期鉤子,則會(huì)將兩者concat為一個(gè)數(shù)組(parentVal.concat(childVal))。所以,生命周期鉤子其實(shí)是可以寫(xiě)成數(shù)組。如:
created: [ function () {console.log('first') }, function () {console.log('second') }, function () {console.log('third') }] 復(fù)制代碼鉤子函數(shù)將按順序執(zhí)行。
4. “Vue-router 路由模式有幾種?”
三種 "hash" | "history" | "abstract",一般人只知道兩種"hash" | "history"。
這里貼出源碼:
switch (mode) {case 'history':this.history = new HTML5History(this, options.base)breakcase 'hash':this.history = new HashHistory(this, options.base, this.fallback)breakcase 'abstract':this.history = new AbstractHistory(this, options.base)breakdefault:if (process.env.NODE_ENV !== 'production') {assert(false, `invalid mode: ${mode}`)} } 復(fù)制代碼# mode
類(lèi)型: string
默認(rèn)值: "hash" (瀏覽器環(huán)境) | "abstract" (Node.js 環(huán)境)
可選值: "hash" | "history" | "abstract" 配置路由模式:
- hash: 使用 URL hash 值來(lái)作路由。支持所有瀏覽器,包括不支持 HTML5 History Api 的瀏覽器。
- history: 依賴(lài) HTML5 History API 和服務(wù)器配置。查看 HTML5 History 模式。
- abstract: 支持所有 JavaScript 運(yùn)行環(huán)境,如 Node.js 服務(wù)器端。如果發(fā)現(xiàn)沒(méi)有瀏覽器的 API,路由會(huì)自動(dòng)強(qiáng)制進(jìn)入這個(gè)模式.
5. “談?wù)勀銓?duì)keep-alive的了解?”
先貼一個(gè)常規(guī)回答:
keep-alive是 Vue 內(nèi)置的一個(gè)組件,可以使被包含的組件保留狀態(tài),或避免重新渲染。 在vue 2.1.0 版本之后,keep-alive新加入了兩個(gè)屬性: include(包含的組件緩存) 與 exclude(排除的組件不緩存,優(yōu)先級(jí)大于include) 。
然后你可以開(kāi)始騷了:
6. “了解Vue2.6+新全局API:Vue.observable()嗎?”
Vue2.6+新的全局API是Vue.observable(),它的使用方式:
import vue from vue; const state = Vue.observable ({counter: 0, }); export default {render () {return (<div>{state.counter}<button v-on:click={() => {state.counter ++; }}>Increment counter</ button></ div>);}, }; 復(fù)制代碼而它定義在/src/core/global-api/index.js第48行:
import { observe } from 'core/observer/index' // ... // 2.6 explicit observable API Vue.observable = <T>(obj: T): T => { observe(obj) return obj } 復(fù)制代碼再看看它import的observe,最近一次提交在12/1/2018,唔。。。。
核心就是暴露出observe(obj)觀測(cè)后的數(shù)據(jù),代碼啥都沒(méi)改。懂了吧?求一份深圳的內(nèi)推
目前本人在準(zhǔn)備跳槽,希望各位大佬和HR小姐姐可以?xún)?nèi)推一份靠譜的深圳前端崗位!
- 微信:huab119
- 郵箱:454274033@qq.com
作者掘金文章總集
- 為何你始終理解不了JavaScript作用域鏈?
- 「Vue實(shí)踐」項(xiàng)目升級(jí)vue-cli3的正確姿勢(shì)
- 「從源碼中學(xué)習(xí)」徹底理解Vue選項(xiàng)Props
- 「從源碼中學(xué)習(xí)」Vue源碼中的JS騷操作
- 「從源碼中學(xué)習(xí)」面試官都不知道的Vue題目答案
公眾號(hào):
轉(zhuǎn)載于:https://juejin.im/post/5c959f74f265da610c068fa8
總結(jié)
以上是生活随笔為你收集整理的「从源码中学习」面试官都不知道的Vue题目答案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 大三下学期第四周总结
- 下一篇: vue2.x 综合教程 一