1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        當(dāng)面試官問:為什么 Vue3.0 要重寫響應(yīng)式系統(tǒng)?

        共 4034字,需瀏覽 9分鐘

         ·

        2021-01-24 10:39

        嗨,我是你穩(wěn)定更新、精通面試的勾勾。



        以前面試的時候經(jīng)常被問到響應(yīng)式相關(guān)的內(nèi)容,而 Vue3.0 更新后,面試官又有了新的武器來考核面試者。


        面試官:為什么 Vue3.0 要重寫響應(yīng)式系統(tǒng)?



        對于面試者來說,懵逼樹上懵逼果,懵逼樹下你和我,面試官在問什么,我該怎么回答,完全不知道怎么回事。


        有些經(jīng)驗的小伙伴可能會從解釋 Proxy 的好處開始簡單聊一下,比如,Proxy 是直接代理對象,而不是劫持對象的屬性,更好的數(shù)組監(jiān)控等。


        這樣的回答,勉強算是合格吧。


        那到底應(yīng)該怎么答呢,才能順利通過面試,贏得 offer?


        面試官背后的出題邏輯


        別急,咱們先整理一下思路,孫子兵法有云:“知己知彼,百戰(zhàn)不殆”。


        面試就像打仗,你來我往,所以我們需要換位思考,想一想。


        為什么面試官會問這樣一個問題?

        面試官想從這個問題里得到什么回答?

        這個問題可以考察那些技術(shù)點?


        想清楚這些問題,再回到自己身上,去思考這些技術(shù)點自己是否都已經(jīng)掌握。


        說的直白一點,面試就像考試,你需要先讀題、審題才能答好這道題。


        為什么很多人認(rèn)為“面試造火箭,工作擰螺絲”?


        因為沒有換位思考,沒有想清楚面試題背后的邏輯。


        那我們想清楚這個邏輯之后,需要我們做的就是提取技術(shù)點——整理思路——做出對應(yīng)解答。


        當(dāng)然,前提是你需要具備這些技術(shù)能力。


        那么接下來,我就嘗試拆解一下這個面試題了,提取其中的知識點。對于你來說,就是要看看這些知識點,你都掌握了多少?


        為什么 Vue3.0 要重寫響應(yīng)式系統(tǒng)?


        為什么要重寫?


        如果之前好好的,重寫就沒有意義。那之前存在什么問題,現(xiàn)在是怎么解決的,這就是關(guān)鍵點了。


        不知道你對 Vue2.x 的響應(yīng)式掌握多少,是不是欠下了技術(shù)的債呢?


        沒關(guān)系,我來幫你還債,先梳理 Vue2.x 的響應(yīng)式


        其實基于這個面試題,背后還有很多技術(shù)點。上面這些,是與當(dāng)前題目有直接關(guān)系的。在實際面試中,很有可能基于這些技術(shù)點,再進(jìn)行深入交流,這里就不擴展了,你能把現(xiàn)在這些問題理清楚,就算賺到了!



        Vue2.x 響應(yīng)式


        關(guān)于這一點,在 Vue 的官方文檔中,早已經(jīng)有過說明了,而且說的非常詳細(xì)。


        官方文檔:

        https://cn.vuejs.org/v2/guide/reactivity.html



        當(dāng)你把一個普通的 JavaScript 對象傳入 Vue 實例作為 data 選項,Vue 將遍歷此對象所有的 property,并使用 Object.defineProperty 把這些 property 全部轉(zhuǎn)為 getter/setter。


        Object.defineProperty 是 ES5 中一個無法 shim 的特性,這也就是 Vue 不支持 IE8 以及更低版本瀏覽器的原因。


        這些 getter/setter 對用戶來說是不可見的,但是在內(nèi)部它們讓 Vue 能夠追蹤依賴,在 property 被訪問和修改時通知變更。


        這里需要注意的是,不同瀏覽器在控制臺打印數(shù)據(jù)對象時對 getter/setter 的格式化并不同,所以建議安裝 vue-devtools 來獲取對檢查數(shù)據(jù)更加友好的用戶界面。


        每個組件實例都對應(yīng)一個 watcher 實例,它會在組件渲染的過程中把“接觸”過的數(shù)據(jù) property 記錄為依賴。之后當(dāng)依賴項的 setter 觸發(fā)時,會通知 watcher,從而使它關(guān)聯(lián)的組件重新渲染。


        我們使用官方給的一張圖示,來梳理整個流程。



        先來看一段代碼:



        響應(yīng)式原理


        data 中的 obj 就是一個普通的 JavaScript 對象,通過點擊 Click 按鈕,將獲取到的隨機數(shù)賦值給 this.message ,而 this.message 指向的就是 data 中 obj 對象的 message 屬性。


        當(dāng) message 發(fā)生數(shù)據(jù)改變時,頁面中 H1 標(biāo)簽的內(nèi)容會隨之改變,這個過程就是就是響應(yīng)式的。


        那么 Vue 是如何實現(xiàn)的呢?


        首先,Vue 內(nèi)部使用 Object.defineProperty() 將 Data 中的每一個成員都轉(zhuǎn)換為 getter / setter 的形式。


        getter 用來依賴收集,setter 用來派發(fā)更新。而模板內(nèi)容,最終會被編譯為 render 函數(shù)。


        在 render 函數(shù)中,我們能發(fā)現(xiàn)?_v(_s(message)) message 被訪問了,就會觸發(fā) getter 來進(jìn)行依賴收集。


        而在代碼中的點擊事件中,一旦事件處理程序被觸發(fā)執(zhí)行,那么 message 則會被修改,就會觸發(fā) setter 來進(jìn)行派發(fā)更新。


        雖然流程理清楚了,但是總感覺少點什么,怎么才能更通透呢?


        我們用代碼來模擬整個的實現(xiàn)過程。


        defineProperty 模擬代碼


        defineProperty 的基本用法,直接看手冊就行了:


        https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty


        我們來看看代碼:

        <div id="app">     hello div> <script>     // 模擬 Vue 中的 data 選項     let data = {       msg: 'hello'     }     // 模擬 Vue 的實例     let vm = {}     // 數(shù)據(jù)劫持:當(dāng)訪問或者設(shè)置 vm 中的成員的時候,做一些干預(yù)操作     Object.defineProperty(vm, 'msg', {       // 可枚舉(可遍歷)       enumerable: true,       // 可配置(可以使用 delete 刪除,可以通過 defineProperty 重新定義)       configurable: true,       // 當(dāng)獲取值的時候執(zhí)行       get () {         console.log('get: ', data.msg)         return data.msg       },       // 當(dāng)設(shè)置值的時候執(zhí)行       set (newValue) {         console.log('set: ', newValue)         if (newValue === data.msg) {           return         }         data.msg = newValue         // 數(shù)據(jù)更改,更新 DOM 的值         document.querySelector('#app').textContent = data.msg       }     })     // 測試     vm.msg = 'Hello World'     console.log(vm.msg) script>


        你沒有看錯,加上注釋,一共 36行代碼,這就是 Vue2.x 對響應(yīng)式實現(xiàn)的整個流程。


        ?繼續(xù)實現(xiàn)多個數(shù)據(jù)的響應(yīng)。

        <body>  <div id="app">    hello  div>  <script>    // 模擬 Vue 中的 data 選項    let data = {      msg: 'hello',      count: 10    }    // 模擬 Vue 的實例    let vm = {}    proxyData(data)    function proxyData(data) {      // 遍歷 data 對象的所有屬性      Object.keys(data).forEach(key => {        // 把 data 中的屬性,轉(zhuǎn)換成 vm 的 setter/setter        Object.defineProperty(vm, key, {          enumerable: true,          configurable: true,          get () {            console.log('get: ', key, data[key])            return data[key]          },          set (newValue) {            console.log('set: ', key, newValue)            if (newValue === data[key]) {              return            }            data[key] = newValue            // 數(shù)據(jù)更改,更新 DOM 的值            document.querySelector('#app').textContent = data[key]          }        })      })    }    // 測試    vm.msg = 'Hello World'    console.log(vm.msg)script>body>


        上面的代碼只是模擬了響應(yīng)式的原理,但 Vue 在實現(xiàn)中,肯定不會那么簡單。


        下周一,我們來康康源碼(●'?'●)。


        推薦閱讀:

        喜大普奔!Element UI for Vue 3.0 來了!

        Proxy 代理對象

        不小心將 Webpack 升級后我搞定了微前端。

        別覺得搞前端就不需要懂后臺知識。

        騰訊QQ偷我瀏覽記錄到底想干嘛。

        是我 Web 端配不上阿里了。


        點點“”和“在看”,保護頭發(fā),減少bug。

        瀏覽 81
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            高请无码一区AAA片毛片 | 波多野结衣无码一区二区 | 天天干夜夜夜夜 | 黄片成人免费 | 男女激情上床 | 新加坡毛片 | 狠狠色情婷婷 | 91精品国自产欧美在线观看 | 国产精品美女久久久久AV爽 | 国产传媒自拍 |