關(guān)于 vue原理和生命周期 1

最近由于各種原因又開始面試了噪服,然后想把這方面關(guān)于vue做一個整理,以便于自己后續(xù)鞏固復習~

若有不足拼弃,歡迎大佬補充并指證~

1略号、vue的生命周期鉤子函數(shù)

   1)berforeCreate    new vue()觸發(fā)的第一個鉤子,現(xiàn)階段data纵菌、methods斥赋、computed以及watch上的數(shù)據(jù)和方法都不能被訪問。

    2)created   實力創(chuàng)建完成后觸發(fā)产艾,此階段完成了數(shù)據(jù)觀測疤剑,可是使用數(shù)據(jù),更改數(shù)據(jù)闷堡。需要注意的是隘膘,在這個階段更改數(shù)據(jù)的話,不會觸發(fā)updated函數(shù)哦~杠览,能獲取初始數(shù)據(jù)弯菊,不能和dom進行交互,如果實在忍不住想訪問dom踱阿,你用vm.$nextTick試試管钳!

    3) beforeMount  掛在之前觸發(fā),此階段templete已經(jīng)導入渲染函數(shù)進行編譯软舌,而且此時虛擬dom已經(jīng)創(chuàng)建完成才漆,馬上就開始渲染了.注意哈,此階段更改數(shù)據(jù)的話和上一個一樣佛点,不會觸發(fā)updated的哦

    4) mount  掛在完成后觸發(fā)醇滥,此階段真實dom掛載完成了,數(shù)據(jù)也雙向綁定了超营,可以訪問dom節(jié)點了鸳玩,操作dom的話用$refs試試,結(jié)果會讓你滿意的演闭。

    5)beforeUpdate  數(shù)據(jù)更新之前(響應式數(shù)據(jù)發(fā)生更新不跟,虛擬dom重新渲染之前)觸發(fā),這個階段可以進行數(shù)據(jù)更改米碰,那會造成重渲染嗎窝革?答案當然是不會啦,放手干吧见间!

    6)updated 更新完成聊闯,dom完成更新觸發(fā)。注意注意:避免在這個期間更改數(shù)據(jù)米诉,不然就導致無線循環(huán)的更新啦菱蔬。

    7)beforeDestroyed   實例銷毀之前觸發(fā),當前階段可以進行善后收尾工作,比如說清楚計時器之類的拴泌。

    8)destroyed  實例銷毀之后觸發(fā)剩一個dom空殼魏身,組件被拆解了,數(shù)據(jù)綁定被卸除蚪腐,監(jiān)聽被移出箭昵,子實例也統(tǒng)統(tǒng)被銷毀。

2 理解一下MVVM回季,和MVC有什么區(qū)別

##哎呀家制,先說說MVC吧,MVC 模式代表 Model-View-Controller(模型-視圖-控制器) 模式泡一,這種模式一般用于應用程序的分層開發(fā)颤殴。

Model(模型) - 模型代表一個存取數(shù)據(jù)的對象或 JAVA POJO。它也可以帶有邏輯鼻忠,在數(shù)據(jù)變化時更新控制器涵但。

View(視圖) - 視圖代表模型包含的數(shù)據(jù)的可視化。Controller(控制器) - 控制器作用于模型和視圖上帖蔓。它控制數(shù)據(jù)流向模型對象矮瘟,并在數(shù)據(jù)變化時更新視圖。它使視圖與模型分離開塑娇。

1622125558(1).jpg
##再來說說MVVM吧澈侠,

MVVM是Model-View-ViewModel的簡寫,本質(zhì)上就是MVC 的改進版钝吮。

即 MODEL 模型- VIEW 視圖- VIEWMODEL 視圖模型埋涧。

MODEL 指的是后端傳遞的數(shù)據(jù)。

VIEW 指的是所看到的頁面奇瘦。

VIEWMODEL mvvm模式的核心,它是連接view和model的橋梁劲弦。那么你得知道它做了什么耳标,它做了兩件事情,或者說它走了兩個方向邑跪。

1)將 MODEL 轉(zhuǎn)化成 VIEW次坡,即將后端傳遞的數(shù)據(jù)轉(zhuǎn)化成所看到的頁面。實現(xiàn)的方式是:數(shù)據(jù)綁定画畅。俗稱聯(lián)調(diào)接口砸琅,把后端返回的數(shù)據(jù)展示在前端頁面。

2)將 VIEW 轉(zhuǎn)化成 MODEL 轴踱,即將所看到的頁面轉(zhuǎn)化成后端的數(shù)據(jù)症脂。實現(xiàn)的方式是:DOM 事件監(jiān)聽。

上述兩項都完成了,就是我們常說的诱篷,數(shù)據(jù)的雙向綁定壶唤。

image.png

2、vue 2.0 如何實現(xiàn)的雙向數(shù)據(jù)綁定(說白了就是考原理棕所,有興趣就去看看源碼吧闸盔。)

先網(wǎng)上扒一張圖過來


image.png

看圖,首先就是data琳省,在vue里迎吵,要實現(xiàn)對data的數(shù)據(jù)相應,利用Observer進行數(shù)據(jù)劫持针贬。初始化數(shù)據(jù)之后击费,使用Object.definedProperty重新定義data中的所有屬性,然后進行依賴收集坚踩,也就是圖中的watcher(當前組件的watcher)

注釋:Object.definedProperty(obj, prop, descriptor)
obj:必需荡灾。目標對象
prop:必需。需定義或修改的屬性的名字
descriptor:必需瞬铸。目標屬性所擁有的特性

存取器了解一下批幌,getter、setter

getter:當訪問該屬性時嗓节,該方法會被執(zhí)行荧缘。函數(shù)的返回值會作為該屬性的值返回
setter:當屬性值修改時,該方法會被執(zhí)行拦宣。該方法將接受唯一參數(shù)截粗,即該屬性新的參數(shù)值。

動動爪子試試

image.png

附一下代碼:
var obj = {}; //定義一個新對象
var initVal = 'nihao'; //設(shè)置一個初始值
Object.defineProperty(obj,"newVal",{ //重定義數(shù)據(jù),也就是數(shù)據(jù)劫持鸵隧,數(shù)據(jù)代理
get:function (){//當獲取值的時候觸發(fā)的函數(shù)绸罗,也就是obj.newVal 的默認值是 nihao
return initVal;
},
set:function (value){//當設(shè)置值的時候觸發(fā)的函數(shù),設(shè)置的新值通過參數(shù)value拿到,如果設(shè)置新的值豆瘫,obj.newVal就會發(fā)生改變
initVal = value;
}
});
//獲取值
console.log( obj.newVal ); // 打印出來 hello
//設(shè)置值
obj.newVal = 'hao ge der';
console.log( obj.newVal ); //打印出來 hao ge der

打印結(jié)果 不信你自己試試


image.png

注意:當使用了getter或setter方法珊蟀,不允許使用writable和value這兩個屬性
注意:不要在getter中再次獲取該屬性值,也不要在setter中再次設(shè)置改屬性外驱,否則會棧溢出

簡單寫個vue 數(shù)據(jù)代理和劫持
文件目錄


image.png

簡單示例


image.png

在js文件里面寫個簡單的vue 實例 進行數(shù)據(jù)代理 和數(shù)據(jù)劫持

class Vue {
// 構(gòu)造器
constructor(params){
this.$options = params // vm
this._data = params.data //vm.data
this.initData() //初始化
}
initData(){
let data = this._data;
console.log(data) //結(jié)果如下
// {name: "xuxiansheng", message: "this is vue.js"}
// message: "this is vue.js"
// name: "xuxiansheng"
// proto: Object 原型

    //收集所有集合中的key 結(jié)果是一個數(shù)組 也就是收集watcher
    let keys = Object.keys(data);  //結(jié)果如下
    //  ["name", "message"]

    console.log(keys)
    // 遍歷數(shù)組 使用objectDefine.property()對數(shù)據(jù)進行代理
    for(let i = 0; i < keys.length; i++){       
        // this指向vue實例   
        // 注意這里要用關(guān)鍵字let 而不要用var 否則會出現(xiàn)變量名提升 訪問不到data中的數(shù)據(jù)
        // Object.definedProperty(obj, prop, descriptor)
        // obj:必需育灸。目標對象
        // prop:必需。需定義或修改的屬性的名字
        // descriptor:必需昵宇。目標屬性所擁有的特性
        Object.defineProperty(this, keys[i], {
            // 可枚舉磅崭?true  or false 
            // 至于for...in循環(huán)和Object.keys方法的區(qū)別,在于for...in包括對象繼承自原型對象的屬性瓦哎,而Object.keys只包括對象本身的屬性砸喻。 
            enumerable:true,
            // 是否可以刪除目標屬性或是否可以再次修改屬性的特性
            configurable:true,
            get: function() { //獲取屬性值
                return  this._data[keys[i]]
            },
            set: function(value) { //設(shè)置新的值
                // 設(shè)置值
                data[keys[i]] = value
            }
        })
    } 
    
    // 為了實現(xiàn)data 數(shù)據(jù)的響應柔逼,需要對data中的數(shù)據(jù)進行劫持
    for(let i = 0;i < keys.length; i++){//遍歷數(shù)組
        // 拿到data對象里面  key 為 keys[i]的值
        let value = data[keys[i]] 
        console.log(value) // xuxiansheng  this is vue.js
        Object.defineProperty(data, keys[i], {
            enumerable:true,
            configurable:true,
            get: function reactiveGetter(){
                console.log(`data的屬性${keys[i]}的獲取`);
                return value;
            },
            set: function reactiveSetter(val){
                console.log(`data設(shè)置屬性${keys[i]}`)
                value = val;
            }
        })

    }
}

}
注意一下,get set函數(shù)里面打印不出來具體的屬性值恩够,所以reactiveGetter() reactiveSetter()這兩個需要手動觸發(fā)一下卒落,才能打印里面的內(nèi)容

你要想知道打印出來的是什么,蜂桶,那就去瀏覽器的控制臺輸入命令 如下

image.png

有個東西值得好好注意一下儡毕,那就是沒有進行數(shù)據(jù)劫持 只進行數(shù)據(jù)代理的時候,在瀏覽器控制臺執(zhí)行vm 回車 結(jié)果如下

image.png

但是做了數(shù)據(jù)劫持之后 如下圖


image.png

vm明明是一個實例扑媚,可結(jié)果不一樣腰湾。

所以數(shù)據(jù)代理劫持的目的就是為了實現(xiàn)vue里面的data數(shù)據(jù)訪問的時候,如this.name 直接拿到的就是message的值疆股,實際上this.name訪問的應該是this.data.message

結(jié)合實際就是這么理解

image.png

以上是簡單的數(shù)據(jù)劫持费坊,如果遇到復雜的數(shù)據(jù) 那就進行扁平化處理,比如先判斷當前數(shù)據(jù)的類型是復雜還是簡單

image.png

簡單數(shù)據(jù)注釋掉 把它和復雜數(shù)據(jù)一起處理 封裝一個方法
先判斷數(shù)據(jù)類型


image.png

進行數(shù)據(jù)劫持


image.png

這個就暫時這樣吧.....寫太累了 后續(xù)整體更新吧

3 vue 2.x如何監(jiān)測數(shù)據(jù)變化

那就是上面說的函數(shù)劫持了唄旬痹,重寫了數(shù)組的方法(也就是上面提到的object.key()得到的數(shù)組)附井,將data中的數(shù)據(jù)進行原型鏈的重寫,這樣一來調(diào)用api的時候就可以通知依賴更新了两残。
但是數(shù)組中如果包含引用類型的話永毅,也就是復雜數(shù)據(jù)類型,然后進行遞歸遍歷人弓,實現(xiàn)數(shù)據(jù)監(jiān)測沼死,看不明白就自己動動爪子寫寫,好記性不如爛筆頭

4 nextTick 實現(xiàn)原理是什么

在下一次dom更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)崔赌,這個主要使用了微任務和宏任務意蛀,不通執(zhí)行環(huán)境分別嘗試,promise mutationObserver setImmediate 健芭,如果這三個都不行就用setTimeout 通過異步方法清空任務隊列县钥。

5 說說宏任務和微任務 (上個問題答了 這個問題緊隨而來)

第一件事 先盜個圖來


image.png
image.png

請自信告訴我,上面答應出來的是什么慈迈?

1魁蒜、2、3吩翻、4? ×
2锥咸、4狭瞎、1、3搏予?×
2熊锭、4、3、1碗殷? ×
2精绎、4、1 锌妻? √ 想想為啥是這個答案

從一開始寫代碼的時候就知道一句話 js代碼是從上往下一行一行執(zhí)行的代乃,所以很多人先入為主覺得輸出應該是1234,可事實并非如此仿粹。

這就涉及到上面的宏任務 微任務了搁吓,結(jié)合上面宏任務微任務的圖來看,同步和異步任務分別進入不同的執(zhí)行"場所"吭历,同步的進入主線程堕仔,異步的進入Event Table并注冊函數(shù)。

當指定的事情完成時晌区,Event Table會將這個函數(shù)移入Event Queue摩骨。主線程內(nèi)的任務執(zhí)行完畢為空,會去Event Queue讀取對應的函數(shù)朗若,進入主線程執(zhí)行恼五。上述過程會不斷重復,也就是面試官經(jīng)常會問你的捡偏,什么是循環(huán)機制唤冈,這個就是Event Loop(事件循環(huán))機制。

再偷個圖

image.png

js異步有一個機制银伟,就是遇到宏任務你虹,先執(zhí)行宏任務,將宏任務放入eventqueue彤避,然后在執(zhí)行微任務傅物,將微任務放入eventqueue。

記住這倆規(guī)則:

宏任務一般是:包括整體代碼script琉预,setTimeout董饰,setInterval。

微任務:Promise圆米,process.nextTick卒暂。

所以上述代碼就是,setTimeout是宏任務先執(zhí)行但是特么它是異步的娄帖,所以要往下檢查是不是有微任務也祠,遇到了new Promise立即執(zhí)行之后,打印console.log('2')近速,Promise.then()又被放入了微任務的隊列里诈嘿,所以先去執(zhí)行了宏任務console.log('4')堪旧,執(zhí)行完成之后才執(zhí)行了setTimeout,所有主線程的任務棧執(zhí)行完了才去執(zhí)行了Promise.then()
這塊有點復雜 暫時就理解這么多 后續(xù)補上吧

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奖亚,一起剝皮案震驚了整個濱河市淳梦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌昔字,老刑警劉巖爆袍,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異李滴,居然都是意外死亡螃宙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門所坯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谆扎,“玉大人,你說我怎么就攤上這事芹助√煤” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵状土,是天一觀的道長无蜂。 經(jīng)常有香客問我,道長蒙谓,這世上最難降的妖魔是什么斥季? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮累驮,結(jié)果婚禮上酣倾,老公的妹妹穿的比我還像新娘。我一直安慰自己谤专,他們只是感情好躁锡,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著置侍,像睡著了一般映之。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜡坊,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天杠输,我揣著相機與錄音,去河邊找鬼秕衙。 笑死抬伺,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的灾梦。 我是一名探鬼主播峡钓,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼若河!你這毒婦竟也來了能岩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤萧福,失蹤者是張志新(化名)和其女友劉穎拉鹃,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲫忍,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡膏燕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了悟民。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坝辫。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖射亏,靈堂內(nèi)的尸體忽然破棺而出近忙,到底是詐尸還是另有隱情,我是刑警寧澤智润,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布及舍,位于F島的核電站,受9級特大地震影響窟绷,放射性物質(zhì)發(fā)生泄漏锯玛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一兼蜈、第九天 我趴在偏房一處隱蔽的房頂上張望攘残。 院中可真熱鬧,春花似錦饭尝、人聲如沸肯腕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽实撒。三九已至,卻和暖如春涉瘾,著一層夾襖步出監(jiān)牢的瞬間知态,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工立叛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留负敏,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓秘蛇,卻偏偏與公主長得像其做,于是被迫代替她去往敵國和親顶考。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359

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

  • vue生命周期共分為八個階段:創(chuàng)建前/后妖泄,載入前/后驹沿,更新前/后,銷毀前/后蹈胡。 beforeCreate(創(chuàng)建前)...
    Kepler_明閱讀 1,743評論 0 13
  • 這方面的文章很多渊季,但是我感覺很多寫的比較抽象,本文會通過舉例更詳細的解釋罚渐。(此文面向的Vue新手們却汉,如果你是個大牛...
    Ivy_2016閱讀 15,398評論 8 64
  • vue框架 中最核心的就是 vue的響應式 ,通過對vue中data數(shù)據(jù)的變更實現(xiàn)頁面效果的重新渲染荷并。但在實際開發(fā)...
    郝小淞閱讀 4,345評論 1 1
  • 這方面的文章很多合砂,但是我感覺很多寫的比較抽象,本文會通過舉例更詳細的解釋璧坟。(此文面向的Vue新手們既穆,如果你是個大牛...
    抽瘋的稻草繩閱讀 3,123評論 0 8
  • 什么是Vue的生命周期? 從Vue實例創(chuàng)建雀鹃、運行幻工、到銷毀期間,總是伴隨著各種各樣的事件黎茎,這些事件囊颅,統(tǒng)稱為生命周期。...
    小q閱讀 1,264評論 1 12