01 發布者訂閱者模式vue(vuejs源碼用了什么設計模式,具體點的)

时间:2024-05-06 15:28:36 编辑: 来源:

vuejs源碼用了什么設計模式,具體點的

最簡單的訂閱者模式

// Observer

class Observer {

買粉絲nstructor (data) {

this.walk(data)

}

walk (data) {

// 遍歷

let keys = Object.keys(data)

for(let i = 0; i < keys.length; i++){

defineReactive(data, keys[i], data[keys[i]])

}

}

}

function defineReactive (data, key, val) {

observer(val)

// dep 為什么要在這里實例化, 就是為了實現, 對象每一層的 每一個key都有自己的一個訂閱實例, 比如 a.b 對應 dep1, a.c 對應dep2, 這里雖然都是let dep = new Dep()

// 但每次來到這個方法, dep都是獨立的, 會一直保留在內存. 這樣在每次調用set方法都能找到這個a.b對應的dep

// dep 這里會一直保存, 是因為閉包的關系, Object這個全局的函數, 引用了上層的作用域, 這個作用域包含了 dep, 除非Object = null, 或者退出瀏覽器, dep才會消失

//實例化之后, dep就有了被訂閱, 和發布消息的功能, dep不寫在這里也是可以的, 多定義一個全局函數, 每次obser的時候增加一個dep

let dep = new Dep()

Object.defineProperty(data, key, {

enumerable: true,

買粉絲nfigurable: true,

get: function () {

//每次new Watch('a.b'), 都會先執行get方法, 進而來到這里, 觸發 dep.depend(), 這個dep就是 a.b 對應的 訂閱,

dep.depend()

return val

},

set: function (newVal) {

if(val === newVal){

return

Vue 面試中常問知識點整理

生命周期:Vue實例從開始創建、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,我們稱這是Vue的生命周期,各個階段有相對應的事件鉤子。

beforeCreate(創建前),在數據觀測和初始化事件還未開始

created(創建后),完成數據觀測,屬性和方法的運算,初始化事件, $el 屬性還沒有顯示出來

beforeMount(載入前),在掛載開始之前被調用,相關的render函數首次被調用。實例已完成以下的配置:編譯模板,把data里面的數據和模板生成買粉絲。注意此時還沒有掛載買粉絲到頁面上。

mounted(載入后),在 el 被新創建的 vm.$el 替換,并掛載到實例上去之后調用。實例已完成以下的配置:用上面編譯好的買粉絲內容替換 el 屬性指向的DOM對象。完成模板中的買粉絲渲染到買粉絲頁面中。此過程中進行ajax交互。

beforeUpdate(更新前),在數據更新之前調用,發生在虛擬DOM重新渲染和打補丁之前。可以在該鉤子中進一步地更改狀態,不會觸發附加的重渲染過程。

updated(更新后),在由于數據更改導致的虛擬DOM重新渲染和打補丁之后調用。調用時,組件DOM已經更新,所以可以執行依賴于DOM的操作。然而在大多數情況下,應該避免在此期間更改狀態,因為這可能會導致更新無限循環。該鉤子在服務器端渲染期間不被調用。

beforeDestroy(銷毀前),在實例銷毀之前調用。實例仍然完全可用。

destroyed(銷毀后),在實例銷毀之后調用。調用后,所有的事件監聽器會被移除,所有的子實例也會被銷毀。該鉤子在服務器端渲染期間不被調用。

注意:

created 階段的ajax請求與 mounted 請求的區別:前者頁面視圖未出現,如果請求信息過多,頁面會長時間處于白屏狀態。

mounted 不會承諾所有的子組件也都一起被掛載。如果你希望等到整個視圖都渲染完畢,可以用 vm.$nextTick 。

初始化組件時,僅執行了 beforeCreate/Created/beforeMount/mounted 四個鉤子函數

當改變 data 中定義的變量(響應式變量)時,會執行 beforeUpdate/updated 鉤子函數

當切換組件(當前組件未緩存)時,會執行 beforeDestory/destroyed 鉤子函數

初始化和銷毀時的生命鉤子函數均只會執行一次, beforeUpdate/updated 可多次執行

僅當子組件完成掛載后,父組件才會掛載

當子組件完成掛載后,父組件會主動執行一次beforeUpdate/updated鉤子函數(僅首次)

父子組件在data變化中是分別監控的,但是在更新props中的數據是關聯的

銷毀父組件時,先將子組件銷毀后才會銷毀父組件

組件的初始化(mounted之前)分開進行,掛載是從上到下依次進行

當沒有數據關聯時,兄弟組件之間的更新和銷毀是互不關聯的

mixin中的生命周期與引入該組件的生命周期是僅僅關聯的,且mixin的生命周期優先執行

1、什么是vue生命周期?

答: Vue 實例從創建到銷毀的過程,就是生命周期。從開始創建、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、銷毀等一系列過程,稱之為 Vue 的生命周期。

2、vue生命周期的作用是什么?

答:它的生命周期中有多個事件鉤子,讓我們在控制整個Vue實例的過程時更容易形成好的邏輯。

3、vue生命周期總共有幾個階段?

答:它可以總共分為8個階段:創建前/后、載入前/后、更新前/后、銷毀前/銷毀后。

5、DOM 渲染在哪個周期中就已經完成?

答:DOM 渲染在 mounted 中就已經完成了。

vue實現數據雙向綁定主要是:采用數據劫持結合發布者-訂閱者模式的方式,通過 Object.defineProperty() 來劫持各個屬性的 setter,getter ,在數據變動時發布消息給訂閱者,觸發相應監聽回調。當把一個普通 Javascript 對象傳給 Vue 實例來作為它的 data 選項時,Vue 將遍歷它的屬性,用 Object.defineProperty() 將它們轉為 getter/setter 。用戶看不到 getter/setter,但是在內部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。

vue的數據雙向綁定 將MVVM作為數據綁定的入口,整合 Observer ,Compile和 Watcher 三者,通過 Observer 來監聽自己的 model 的數據變化,通過 Compile 來解析編譯模板指令(vue中是用來解析 { { }}),最終利用 watcher 搭起observer和 Compile 之間的通信橋梁,達到數據變化 —>視圖更新;視圖交互變化( input )—>數據 model 變更雙向綁定效果。

js實現簡單的雙向綁定:

1、父組件與子組件傳值

父組件傳給子組件:子組件通過 props 方法接受數據;

子組件傳給父組件: $emit 方法傳遞參數

2、非父子組件間的數據傳遞,兄弟組件傳值 eventBus ,就是創建一個事件中心,相當于中轉站,可以用它來傳遞事件和接收事件。項目比較小時,用這個比較合適。

hash模式:在瀏覽器中符號“#”,#以及#后面的字符稱之為hash,用 window.location.hash 讀取。特點:hash雖然在URL中,但不被包括在HTTP請求中;用來指導瀏覽器動作,對服務端安全無用,hash不會重加載頁面。

history模式:history采用HTML5的新特性;且提供了兩個新方法: pushState(), replaceState()可以對瀏覽器歷史記錄棧進行修改,以及popState事件的監聽到狀態變更。

需求一:

在一個列表頁中,第一次進入的時候,請求獲取數據。

點擊某個列表項,跳到詳情頁,再從詳情頁后退回到列表頁時,不刷新。

也就是說從其他頁面進到列表頁,需要刷新獲取數據,從詳情頁返回到列表頁時不要刷新。

解決方案

在 App.vue設置:

假設列表頁為 list.vue ,詳情頁為 detail.vue ,這兩個都是子組件。

我們在 keep-alive 添加列表頁的名字,緩存列表頁。

然后在列表頁的 created 函數里添加ajax請求,這樣只有第一次進入到列表頁的時候才會請求數據,當從列表頁跳到詳情頁,再從詳情頁回來的時候,列表頁就不會刷新。

這樣就可以解決問題了。

需求二:

在需求一的基礎上,再加一個要求:可以在詳情頁中刪除對應的列表項,這時返回到列表頁時需要刷新重新獲取數據。

我們可以在路由配置文件上對 detail.vue 增加一個 meta 屬性。

這個 meta 屬性,可以在詳情頁中通過 this.$route.meta.isRefresh 來讀取和設置。

設置完這個屬性,還要在 App.vue 文件里設置 watch 一下 $route 屬性。

這樣就不需要在列表頁的 created 函數里用 ajax 來請求數據了,統一放在 App.vue 里來處理。

觸發請求數據有兩個條件:

從其他頁面(除了詳情頁)進來列表時,需要請求數據。

從詳情頁返回到列表頁時,如果詳情頁 meta 屬性中的 isRefresh 為 true ,也需求

搜索关键词: