11月份的面試越來越覺得自己學的不夠踏實和深入。現在實習了有空總結下
京東前端實習一道面試題:vue中元件通訊介面有哪些,除了props和$emit?
注意是介面,我說了vuex和localstorage,立馬就被否決了
props最常見的父子通訊介面,但是props是單向資料流的形式:父級 prop 的更新會向下流動到子元件中,但是反過來則不行
此時需要借助vue提供的事件監聽機制來完成子元件向父元件資料流動更新的功能。 在子元件使用$emit定義監聽事件名稱,在父元件使用v-on監聽該事件,在事件中改變父元件的狀態。
// father.vue
// children.vue
$parent用來訪問父元件例項,通常父元件都是唯一確定的
// children.vue
$children用來訪問子元件例項,要知道乙個元件的子元件可能是不唯一的,所以它的返回值是陣列.
// father.vue
$children的缺點是無法確定子元件的順序,也不是響應式的。所以如果你確切的知道要訪問的子元件建議使用$refs。
$refs需要使用ref屬性在子元件上設定標識,然後通過this.$refs.refname訪問。
// father.vue
// children.vue
注意:ref屬性作為元件屬性時,訪問的是根元件的例項;作為dom屬性時,訪問的是dom資訊
// father.vue
這是@2.4新增的屬性和介面。inheritattrs屬性控制子元件html屬性上是否顯示父元件的提供的屬性
// father.vue
瀏覽器渲染的時候,缺省會把父元件寫在子元件的屬性一起渲染出來,它是這樣的
...
從@2.4開始,在子元件預設新增inheritattrs選項,並且預設為false,來隱藏這些屬性,如果你期望這些屬性是顯示在根html元素上,你只需要將inheritattrs的值指定為true
// children.vue
此時渲染之後式這樣的
...
$attrs包含所有未在props中宣告的父元件傳遞的屬性
$attrs簡單的說就是props的加強版,因為當父元件提供props的屬性十分多時,逐個在子元件顯式的宣告出來有時也是比較費事的。但是使用$attrs就可以達到事半功倍的效果,看下面的例子
// father.vue
// children.vue
$attrs還有個妙用就是將父元件所有未在props宣告的屬性通過v-bind傳給自己的內部子元件(將父親的屬性通過自己傳給自己的兒子),也就是說它可以作為隔代元件通訊的橋梁,例子如下
// father.vue
// children.vue
// child.vue
下面的所有方法的分類不是唯一的,只是我比較推薦的分類方式,比如$root和依賴注入他們既適合兄弟元件,也適合隔代元件
$root用來方位根例項屬性
個人認為$root的適用性是最好的,比如前面父子元件通訊你使用了$parent或者$children,但是由於需求的改變等等不得已原因,它們的關係已經不是父子元件了,此時,通訊機制就不能不重新建立了。但是如果你一開始就使用了$root作為通訊機制,那麼就不存在這樣的麻煩了。
// children1.vue// children2.vue
確切的說$root方法使用於任何情況的元件通訊,包括父子元件、兄弟元件、隔代元件通訊,可以形象的把它理解成為它們共同的祖先
$root也有它的缺點,官網中也提到了,它只適合通用化(就是不用動態更新的意思)的場景,如果想建立隨著改變動態更新的資料,建議使用vuex
// father.vue// child1.vue
} // 一直顯示mmdjj
不過你嘗試著給$root傳遞乙個響應式的物件,當物件中的資料改變時,其餘使用這個屬性的地方也會跟著改變,也就是說它就是響應式的了
// father.vue// child1.vue
} // 剛開始顯示mmdjj,三秒之後顯示為welcome
eventbus並不是vue官方的名稱,它是使用vue例項的$emit介面建立全域性的事件監聽機制,很多人巧妙的使用它來元件通訊,這種思想**於android事件發布/訂閱輕量級框架eventbus。但是這並不是vue最優的通訊機制。
本質就是例項化乙個空vue例項
// src/eventbus.js
import vue from "vue"
const eventbus = new vue()
export default eventbus
或者直接掛載到全域性,連引入都可以省略
// main.js
import vue from "vue"
vue.prototype.$eventbus = new vue()
一般這種方式每個都會經歷三個階段,發起事件——>監聽事件——>銷毀事件
發起
// children1.vue
// 這是掛載到全域性的版本
監聽
// children2.vue
銷毀
// children2.vue
看了前面的例子,你會發現,通訊最關鍵的地方其實就在上面的updatemsg函式裡,而這之外的所有的東西,都只是一種繁瑣的鋪墊,所以缺點也是顯而易見的。另外對於多個監聽的地方,你還需要手動關閉,還有乙個被大家詬病的就是每個事件都必需起乙個獨一無二的名字,這對起名廢的同學來說是災難啊
有人已經提供了乙個方案使用eventbus替代vuex,這個方案為我們解決了前面提到的缺點,具體可以看這裡
依賴注入是在provide選項中提供要共享的資料,在inject選項中使用共享的資料。它也是官方首推在不使用vuex時隔代元件通訊方式
// 父級元件提供 'foo'
var provider = ,
// ...
}// 任何後代元件注入 'foo'
var child =
// ...
}
const child =
}}// 或者
const child =
}}
出於設計的考慮,依賴注入和$root一樣,都是非響應式的資料模式
但是官方又說了,可以通過提供乙個響應式的物件,來使注入的資料是響應式的。
// 父級元件提供 'foo'
var provider = }},
provide: ,
}// 任何後代元件注入 'foo'
var inject = }
", // => 三秒後由mmdjj變成welcome
inject: ['foo'],
created () , 3000);
} // ...
}
close事件 vue vue 觸發父子元件事件
專案接觸多了,用vue開發專案比較喜歡元件化,乙個彈框,乙個模組都可能寫成子元件 父元件觸發子元件事件 這時需要觸發子元件的事件,例如顯示左側彈框時需要觸發事件調介面查資料,子元件的方法是gettimechannel this.refs.drawercount.gettimechannel 這樣子元...
close事件 vue vue 監聽瀏覽器關閉事件
用vue做的專案,有個需求就是關閉瀏覽器的時候,需要往後臺提交有個介面,來監聽這個賬號有沒有下線。網上找了很多種方法,一直沒有實現。主要困惑點 1 瀏覽器關閉是事件,是什麼 window.addeventlistener beforeunload e 執行 mounted window.addeve...
Vue Vue元件簡單使用
現在的有些web應用都非常龐大,web開發也越來越元件化 模組化,我們需要在使用vue的時候去寫一些元件,避免重複造輪子,提高元件的復用和開發效率。乙個元件就好像一塊積木,多個元件的層層堆疊 擺放最終形成乙個完整的系統。元件的好處在於降低了各個模組之間的耦合性,以至於我們在維護專案時不會太心累。高度...