日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

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

發布時間:2025/4/5 vue 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 「从源码中学习」面试官都不知道的Vue题目答案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

當回答面試官問及的Vue問題,我們除了照本宣科的回答外,其實還可以根據少量的源碼來秀一把,來體現出你對Vue的深度了解。

本文會陸續更新,此次涉及以下問題:

  • “new Vue()做了什么?”
  • “什么階段才能訪問DOM?”
  • “談談你對Vue生命周期的理解。”
  • 擴展:新生命周期鉤子serverPrefetch是什么?
  • “vue-router路由模式有幾種?”
  • “談談你對keep-alive的了解?”
  • “了解Vue2.6+新全局API:Vue.observable()嗎?”
  • 1. “new Vue()做了什么?”

    new關鍵字代表實例化一個對象, 而Vue實際上是一個類, 源碼位置是/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) } 復制代碼

    接著我們跳轉追蹤至this._init(),即Vue.prototype._init,位于src\core\instance\init.js 在_init()方法的內部有一系列 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)}} } 復制代碼

    1.1 這里我們概述一遍:

  • initProxy,作用域代理,攔截組件內訪問其它組件的數據。
  • initLifecycle, 建立父子組件關系,在當前實例上添加一些屬性和生命周期標識。如:$children、$refs、_isMounted等。
  • initEvents,用來存放除@hook:生命周期鉤子名稱="綁定的函數"事件的對象。如:$on、$emit等。
  • initRender,用于初始化$slots、$attrs、$listeners
  • initInjections,初始化inject,一般用于更深層次的組件通信,相當于加強版的props。用于組件庫開發較多。
  • 只要在上一層級的聲明的provide,那么下一層級無論多深都能夠通過inject來訪問到provide的數據。這么做也是有明顯的缺點:在任意層級都能訪問,導致數據追蹤比較困難,不知道是哪一個層級聲明了這個或者不知道哪一層級或若干個層級使用。

    • initState,是很多選項初始化的匯總,包括:props、methods、data、computed 和 watch 等。
    • initProvide,初始化provide。
    • vm.$mount,掛載實例。

    2. “什么階段才能訪問DOM?”

    這個回答可以從beforeCreate以及 created 的調用時機談起,我們根據上面的概述,來簡化下代碼:

    callHook(vm, 'beforeCreate') // 初始化 inject // 初始化 props、methods、data、computed 和 watch // 初始化 provide callHook(vm, 'created') // 掛載實例 vm.$mount(vm.$options.el) 復制代碼

    所以當面試官問你:

    • beforeCreate以及 created 調用時,哪些數據能用與否?
    • 什么階段才能訪問DOM?
    • 為什么created之后才掛載實例?

    知道怎么回答了吧。

    3. “談談你對Vue的生命周期的理解”

    常規回答這里就不說了,來稍微深入點的:

  • created/mounted/updated/destroyed,以及對應的before鉤子。分別是創建=>掛載=>更新=>銷毀。
  • Vue源碼中定義了一個mergeHook函數來遍歷一個常量數組LIFECYCLE_HOOKS,該數組實際上是由與生命周期鉤子同名的字符串組成的數組。
  • // v2.6.10 最新版 var LIFECYCLE_HOOKS = ['beforeCreate','created','beforeMount','mounted','beforeUpdate','updated','beforeDestroy','destroyed','activated','deactivated','errorCaptured',// v2.6+ 'serverPrefetch' ]; 復制代碼

    于是,你可以答多activated & deactivated(keep-alive 組件激活/停用)、errorCaptured(v2.5 以上版本有的一個鉤子,用于處理錯誤)這三個。

    3.1 新生命周期鉤子:serverPrefetch是什么?

    可以看到,serverPrefetch前身是ssrPrefetch。顧名思義,這是用來處理ssr的。允許我們在渲染過程中“等待”異步數據。可在任何組件中使用,而不僅僅是路由組件。

    這里我們貼出一段官方例子:

    <!-- 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> 復制代碼
    • 絕大多數的面試官都不會去關注v2.6+ 以后的代碼記錄和變更。這里如果你說出這個v2.6.10的變化,嘖嘖...面試官肯定更加欣賞你。

    3.2 生命周期鉤子的合并策略

    拿callHook(vm, 'created')講,先判斷組件的選項中有無對應名字的生命周期鉤子,再判斷是否有 parentVal(vm)。若存在parentVal(vm)且都有對應的生命周期鉤子,則會將兩者concat為一個數組(parentVal.concat(childVal))。所以,生命周期鉤子其實是可以寫成數組。如:

    created: [ function () {console.log('first') }, function () {console.log('second') }, function () {console.log('third') }] 復制代碼

    鉤子函數將按順序執行。

    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}`)} } 復制代碼

    # mode

    類型: string

    默認值: "hash" (瀏覽器環境) | "abstract" (Node.js 環境)

    可選值: "hash" | "history" | "abstract" 配置路由模式:

    • hash: 使用 URL hash 值來作路由。支持所有瀏覽器,包括不支持 HTML5 History Api 的瀏覽器。
    • history: 依賴 HTML5 History API 和服務器配置。查看 HTML5 History 模式。
    • abstract: 支持所有 JavaScript 運行環境,如 Node.js 服務器端。如果發現沒有瀏覽器的 API,路由會自動強制進入這個模式.

    5. “談談你對keep-alive的了解?”

    先貼一個常規回答:

    keep-alive是 Vue 內置的一個組件,可以使被包含的組件保留狀態,或避免重新渲染。 在vue 2.1.0 版本之后,keep-alive新加入了兩個屬性: include(包含的組件緩存) 與 exclude(排除的組件不緩存,優先級大于include) 。

    然后你可以開始騷了:

  • <keep-alive>是 Vue 源碼中實現的一個全局抽象組件,通過自定義 render 函數并且利用了插槽來實現數據緩存和更新。它的定義在src/core/components/keep-alive.js 中:
  • export default {name: 'keep-alive',abstract: true,... } 復制代碼
  • 所有的抽象組件是通過定義abstract選項來聲明的。抽象組件不渲染真實DOM,且不會出現在父子關系的路徑上(initLifecycle會忽略抽象組件),相關代碼片段:
  • if (parent && !options.abstract) {// abstract 即 `ptions.abstract`// while 循環查找第一個非抽象的父組件while (parent.$options.abstract && parent.$parent) {parent = parent.$parent}parent.$children.push(vm) } 復制代碼

    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>);}, }; 復制代碼

    而它定義在/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 } 復制代碼

    再看看它import的observe,最近一次提交在12/1/2018,唔。。。。

    核心就是暴露出observe(obj)觀測后的數據,代碼啥都沒改。懂了吧?

    求一份深圳的內推

    目前本人在準備跳槽,希望各位大佬和HR小姐姐可以內推一份靠譜的深圳前端崗位!

    • 微信:huab119
    • 郵箱:454274033@qq.com

    作者掘金文章總集

    • 為何你始終理解不了JavaScript作用域鏈?
    • 「Vue實踐」項目升級vue-cli3的正確姿勢
    • 「從源碼中學習」徹底理解Vue選項Props
    • 「從源碼中學習」Vue源碼中的JS騷操作
    • 「從源碼中學習」面試官都不知道的Vue題目答案

    公眾號:

    轉載于:https://juejin.im/post/5c959f74f265da610c068fa8

    總結

    以上是生活随笔為你收集整理的「从源码中学习」面试官都不知道的Vue题目答案的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。