2. vue 原理

1. 組件化基礎(chǔ)

1.1 如何理解 VUE 的 MVVM 模型?
知識點: 數(shù)據(jù)驅(qū)動試圖

  • 傳統(tǒng)組件快耿,只是靜態(tài)渲染,更新還要依賴于操作 DOM
  • 數(shù)據(jù)驅(qū)動試圖-Vue MVVM
  • 數(shù)據(jù)驅(qū)動試圖-React setState


    image.png
2. 響應(yīng)式
  • 組件 data 的數(shù)據(jù)一旦變化,立刻觸發(fā)試圖的更新
  • 實現(xiàn)數(shù)據(jù)驅(qū)動試圖的第一步
  • 考察 vue 原理的第一題
    vue2 中實現(xiàn)數(shù)據(jù)驅(qū)動視圖的主要 api ES5: Object.defineProperty蛔外?
// 觸發(fā)更新視圖
function updateView() {
    console.log('視圖更新')
}

// 重新定義數(shù)組原型
const oldArrayProperty = Array.prototype
// 創(chuàng)建新對象,原型指向 oldArrayProperty 溯乒,再擴展新的方法不會影響原型
const arrProto = Object.create(oldArrayProperty);
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => {
    arrProto[methodName] = function () {
        updateView() // 觸發(fā)視圖更新
        oldArrayProperty[methodName].call(this, ...arguments)
        // Array.prototype.push.call(this, ...arguments)
    }
})

// 重新定義屬性,監(jiān)聽起來
function defineReactive(target, key, value) {
    // 深度監(jiān)聽
    observer(value)

    // 核心 API
    Object.defineProperty(target, key, {
        get() {
            return value
        },
        set(newValue) {
            if (newValue !== value) {
                // 深度監(jiān)聽
                observer(newValue)

                // 設(shè)置新值
                // 注意矛纹,value 一直在閉包中,此處設(shè)置完之后光稼,再 get 時也是會獲取最新的值
                value = newValue

                // 觸發(fā)更新視圖
                updateView()
            }
        }
    })
}

// 監(jiān)聽對象屬性
function observer(target) {
    if (typeof target !== 'object' || target === null) {
        // 不是對象或數(shù)組
        return target
    }

    // 污染全局的 Array 原型
    // Array.prototype.push = function () {
    //     updateView()
    //     ...
    // }

    if (Array.isArray(target)) {
        target.__proto__ = arrProto
    }

    // 重新定義各個屬性(for in 也可以遍歷數(shù)組)
    for (let key in target) {
        defineReactive(target, key, target[key])
    }
}

// 準(zhǔn)備數(shù)據(jù)
const data = {
    name: 'zhangsan',
    age: 20,
    info: {
        address: '北京' // 需要深度監(jiān)聽
    },
    nums: [10, 20, 30]
}

// 監(jiān)聽數(shù)據(jù)
observer(data)

// 測試
// data.name = 'lisi'
// data.age = 21
// // console.log('age', data.age)
// data.x = '100' // 新增屬性或南,監(jiān)聽不到 —— 所以有 Vue.set
// delete data.name // 刪除屬性,監(jiān)聽不到 —— 所有已 Vue.delete
// data.info.address = '上海' // 深度監(jiān)聽
data.nums.push(4) // 監(jiān)聽數(shù)組

Tips:

  1. 可以看出來 vue2 在對象監(jiān)聽的時候采够,
    問題一:復(fù)雜數(shù)據(jù)監(jiān)聽需要遞歸到底冰垄,一次性的計算量很大;
    問題二:對象的新增和刪除都無法監(jiān)聽到逝薪,所以vue2 推出了 Vue.set 和 Vue.delete 來實現(xiàn)對象的新增和刪除的監(jiān)聽蝴罪;
    問題三:數(shù)組的監(jiān)聽需要通過 原型鏈來實現(xiàn);

vue3 中實現(xiàn)數(shù)據(jù)驅(qū)動視圖的主要 api ES6:Proxy要门?

// 創(chuàng)建響應(yīng)式
function reactive(target = {}) {
    if (typeof target !== 'object' || target == null) {
        // 不是對象或數(shù)組,則返回
        return target
    }

    // 代理配置
    const proxyConf = {
        get(target, key, receiver) {
            // 只處理本身(非原型的)屬性
            const ownKeys = Reflect.ownKeys(target)
            if (ownKeys.includes(key)) {
                console.log('get', key) // 監(jiān)聽
            }
    
            const result = Reflect.get(target, key, receiver)
        
            // 深度監(jiān)聽
            // 性能如何提升的询微?
            return reactive(result)
        },
        set(target, key, val, receiver) {
            // 重復(fù)的數(shù)據(jù)狂巢,不處理
            if (val === target[key]) {
                return true
            }
    
            const ownKeys = Reflect.ownKeys(target)
            if (ownKeys.includes(key)) {
                console.log('已有的 key', key)
            } else {
                console.log('新增的 key', key)
            }

            const result = Reflect.set(target, key, val, receiver)
            console.log('set', key, val)
            // console.log('result', result) // true
            return result // 是否設(shè)置成功
        },
        deleteProperty(target, key) {
            const result = Reflect.deleteProperty(target, key)
            console.log('delete property', key)
            // console.log('result', result) // true
            return result // 是否刪除成功
        }
    }

    // 生成代理對象
    const observed = new Proxy(target, proxyConf)
    return observed
}

// 測試數(shù)據(jù)
const data = {
    name: 'zhangsan',
    age: 20,
    info: {
        city: 'beijing',
        a: {
            b: {
                c: {
                    d: {
                        e: 100
                    }
                }
            }
        }
    }
}

const proxyData = reactive(data)
3. vdom 和 diff 算法
  • vdom 是實現(xiàn) vue 和 react 的重要基石
  • vdom 是一個熱門話題,也是面試中的熱門問題
    背景: Dom 操作是非常耗時的藻雌,但是 js 的操作是很快的胯杭,jquery 自己控制dom操作,vue 和 react 是數(shù)據(jù)驅(qū)動試圖做个,如何有效控制 Dom 操作?
    解決思路:
  1. 有了一定的復(fù)雜度顽频,想減少計算次數(shù)比較難太闺;
  2. 能不能把計算,更多的轉(zhuǎn)移為js計算省骂;
  3. vdom- 用 js 模擬Dom 結(jié)構(gòu),計算出最小的變更怠惶,操作Dom;(最大程度的避免無意義的變更)
image.png

diff 算法


image.png

image.png

image.png

image.png
4. 模版編譯(熱門技術(shù)的深度)

前置知識,with 語法


image.png

image.png

image.png

image.png

vue模版被編譯成什么?

5. 渲染過程
6. 前端路由
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末讽膏,一起剝皮案震驚了整個濱河市拄丰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌奄侠,老刑警劉巖载矿,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異弯洗,居然都是意外死亡,警方通過查閱死者的電腦和手機牡整,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門逃贝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沐扳,你說我怎么就攤上這事∏溉颍” “怎么了卓起?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵凹炸,是天一觀的道長。 經(jīng)常有香客問我奕筐,道長变骡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任渊胸,我火速辦了婚禮,結(jié)果婚禮上翎猛,老公的妹妹穿的比我還像新娘接剩。我一直安慰自己,他們只是感情好懊缺,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著而克,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腾降。 梳的紋絲不亂的頭發(fā)上碎绎,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機與錄音奸晴,去河邊找鬼日麸。 笑死,一個胖子當(dāng)著我的面吹牛代箭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播乙帮,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼极景,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了氢卡?” 一聲冷哼從身側(cè)響起晨缴,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎喜庞,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雷猪,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡晰房,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了与境。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡挥转,死狀恐怖共屈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拗引,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布壤玫,位于F島的核電站哼凯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏括改。R本人自食惡果不足惜家坎,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一吝梅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧苏携,春花似錦、人聲如沸装蓬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乳蛾。三九已至鄙币,卻和暖如春蹂随,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绩衷。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工激率, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人柱搜。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓聪蘸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親健爬。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容