摘要:前言本文主要介紹屬性事件和插槽這三個基礎概念使用方法及其容易被忽略的一些重要細節。至于如何改變,我們接下去詳細介紹單向數據流這個概念出現在組件通信。比如上例中在子組件中修改父組件傳遞過來的數組從而改變父組件的狀態。的一個核心思想是數據驅動。
前言
本文主要介紹屬性、事件和插槽這三個vue基礎概念、使用方法及其容易被忽略的一些重要細節。如果你閱讀別人寫的組件,也可以從這三個部分展開,它們可以幫助你快速了解一個組件的所有功能。
本文的代碼請猛戳github博客,紙上得來終覺淺,大家動手多敲敲代碼!
一、屬性 1.自定義屬性propsprop 定義了這個組件有哪些可配置的屬性,組件的核心功能也都是它來確定的。寫通用組件時,props 最好用對象的寫法,這樣可以針對每個屬性設置類型、默認值或自定義校驗屬性的值,這點在組件開發中很重要,然而很多人卻忽視,直接使用 props 的數組用法,這樣的組件往往是不嚴謹的。
// 父組件
// 子組件 props: { name: String, type: { //從父級傳入的 type,它的值必須是指定的 "success", "warning", "danger"中的一個,如果傳入這三個以外的值,都會拋出一條警告 validator: (value) => { return ["success", "warning", "danger"].includes(value) } }, onChange: { //對于接收的數據,可以是各種數據類型,同樣也可以傳遞一個函數 type: Function, default: () => { } }, isVisible: { type: Boolean, default: false }, list: { type: Array, // 對象或數組默認值必須從一個工廠函數獲取 default: () => [] } }
從上面的例中,可以得出props 可以顯示定義一個或一個以上的數據,對于接收的數據,可以是各種數據類型,同樣也可以傳遞一個函數。通過一般屬性實現父向子通信;通過函數屬性實現子向父通信
2.inheritAttrs這是2.4.0 新增的一個API,默認情況下父作用域的不被認作 props 的特性綁定將會“回退”且作為普通的 HTML 特性應用在子組件的根元素上。可通過設置 inheritAttrs 為 false,這些默認行為將會被去掉。注意:這個選項不影響 class 和 style 綁定。
上個例中,title屬性沒有在子組件中props中聲明,就會默認掛在子組件的根元素上,如下圖所示:
相同點
兩者選項里都可以存放各種類型的數據,當行為操作改變時,所有行為操作所用到和模板所渲染的數據同時都會發生同步變化。
不同點
data 被稱之為動態數據,在各自實例中,在任何情況下,我們都可以隨意改變它的數據類型和數據結構,不會被任何環境所影響。
props 被稱之為靜態數據,在各自實例中,一旦在初始化被定義好類型時,基于 Vue 是單向數據流,在數據傳遞時始終不能改變它的數據類型,而且不允許在子組件中直接操作 傳遞過來的props數據,而是需要通過別的手段,改變傳遞源中的數據。至于如何改變,我們接下去詳細介紹:
4.單向數據流這個概念出現在組件通信。props的數據都是通過父組件或者更高層級的組件數據或者字面量的方式進行傳遞的,不允許直接操作改變各自實例中的props數據,而是需要通過別的手段,改變傳遞源中的數據。那如果有時候我們想修改傳遞過來的prop,有哪些辦法呢?
方法1:過渡到 data 選項中
在子組件的 data 中拷貝一份 prop,data 是可以修改的
export default { props: { type: String }, data () { return { currentType: this.type } } }
在 data 選項里通過 currentType接收 props中type數據,相當于對 currentType= type進行一個賦值操作,不僅拿到了 currentType的數據,而且也可以改變 currentType數據。
方法2:利用計算屬性
export default { props: { type: String }, computed: { normalizedType: function () { return this.type.toUpperCase(); } } }
以上兩種方法雖可以在子組件間接修改props的值,但如果子組件想修改數據并且同步更新到父組件,卻無濟于事。在一些情況下,我們可能會需要對一個 prop 進行『雙向綁定』,此時就推薦以下這兩種方法:
方法3:使用.sync
// 父組件父組件msg:{{ msg }}
父組件數組:{{ arr }}
// 子組件三、插槽子組件msg:{{ msg }}子組件數組:{{ arr }}父組件向子組件 props 里傳遞了 msg 和 show 兩個值,都用了.sync 修飾符,進行雙向綁定。
不過.sync 雖好,但也有限制,比如:1)不能和表達式一起使用(如 v-bind:title.sync="doc.title + "!"" 是無效的);
2)不能用在字面量對象上(如 v-bind.sync="{ title: doc.title }" 是無法正常工作的)。方法4:將父組件中的數據包裝成對象傳遞給子組件
這是因為在 JavaScript 中對象和數組是通過引用傳入的,所以對于一個數組或對象類型的 prop 來說,在子組件中改變這個對象或數組本身將會影響到父組件的狀態。比如上例中在子組件中修改父組件傳遞過來的數組arr,從而改變父組件的狀態。
5.向子組件中傳遞數據時加和不加 v-bind?對于字面量語法和動態語法,初學者可能在父組件模板中向子組件中傳遞數據時到底加和不加 v-bind 會感覺迷惑。
v-bind:msg = "msg"這是通過 v-bind 進行傳遞數據并且傳遞的數據并不是一個字面量,雙引號里的解析的是一個表達式,同樣也可以是實例上定義的數據和方法(其實就是引用一個變量)。
msg="浪里行舟"這種在沒有 v-bind 的模式下只能傳遞一個字面量,這個字面量只限于 String 類量,字符串類型。那如果想通過字面量進行數據傳遞時,如果想傳遞非String類型,必須props名前要加上v-bind,內部通過實例尋找,如果實例方沒有此屬性和方法,則默認為對應的數據類型。
:msg="11111" //Number :msg="true" //Bootlean :msg="()=>{console.log(1)}" //Function :msg="{a:1}" //Object二、事件 1.事件驅動與數據驅動用原生JavaScript事件驅動通常是這樣的流程:
先通過特定的選擇器查找到需要操作的節點 -> 給節點添加相應的事件監聽
然后用戶執行某事件(點擊,輸入,后退等等) -> 調用 JavaScript 來修改節點
這種模式對業務來說是沒有什么問題,但是從開發成本和效率來說會比較不理想,特別是在業務系統越來越龐大的時候。另一方面,找節點和修改節點這件事,效率本身就很低,因此出現了數據驅動模式。
Vue的一個核心思想是數據驅動。所謂數據驅動,是指視圖是由數據驅動生成的,我們對視圖的修改,不會直接操作 DOM,而是通過修改數據,其流程如下:
用戶執行某個操作 -> 反饋到 VM 處理(可以導致 Model 變動) -> VM 層改變,通過綁定關系直接更新頁面對應位置的數據
可以簡單地理解:數據驅動不是操作節點的,而是通過虛擬的抽象數據層來直接更新頁面。主要就是因為這一點,數據驅動框架才得以有較快的運行速度(因為不需要去折騰節點),并且可以應用到大型項目。
2.修飾符事件Vue事件分為普通事件和修飾符事件,這里我們主要介紹修飾符事件。
Vue 提供了大量的修飾符封裝了這些過濾和判斷,讓開發者少寫代碼,把時間都投入的業務、邏輯上,只需要通過一個修飾符去調用。我們先來思考這樣問題:怎樣給這個自定義組件 custom-component 綁定一個原生的 click 事件?
組件內容 如果你的回答是
,那就錯了。這里的 @click 是自定義事件 click,并不是原生事件 click。綁定原生的 click 是這樣的: 組件內容 實際開發過程中離不開事件修飾符,常見事件修飾符有以下這些:
表單修飾符
1).lazy
在默認情況下,v-model?在每次?input?事件觸發后將輸入框的值與數據進行同步 。你可以添加?lazy?修飾符,從而轉變為使用?change事件進行同步。適用于輸入完所有內容后,光標離開才更新視圖的場景。
2).trim
如果要自動過濾用戶輸入的首尾空白字符,可以給 v-model 添加 trim 修飾符:
這個修飾符可以過濾掉輸入完密碼不小心多敲了一下空格的場景。需要注意的是,它只能過濾首尾的空格!首尾,中間的是不會過濾的。
3).number
如果想自動將用戶的輸入值轉為數值類型,可以給 v-model 添加 number 修飾符:
從上面例子,可以得到如果你先輸入數字,那它就會限制你輸入的只能是數字。如果你先輸入字符串,那它就相當于沒有加.number
事件修飾符
插槽分為普通插槽和作用域插槽,其實兩者很類似,只不過作用域插槽可以接受子組件傳遞過來的參數。
1.作用域插槽我們不妨通過一個todolist的例子來了解作用域插槽。如果當item選中后,文字變為黃色(如下圖所示),該如何實現呢?
// 父組件
// 這是個具名插槽 // 其中itemProps的值就是子組件傳遞過來的對象 {{ item }}
// 子組件// 將checked的值傳遞給父組件
值得注意:v-bind:style 的對象語法十分直觀——看著非常像 CSS,但其實是一個 JavaScript 對象。CSS 屬性名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case,記得用引號括起來) 來命名。
2.v-slot新語法在 2.6.0 中,我們為具名插槽和作用域插槽引入了一個新的統一的語法 (即?v-slot?指令)。它取代了?slot?和?slot-scope?。我們來思考個問題:相同名稱的插槽是合并還是替換?
Vue2.5版本,普通插槽合并、作用域插槽替換
Vue2.6版本,都是替換(見下面例子)
我們通過一個例子介紹下Vue2.6版本默認插槽、具名插槽和作用域插槽的新語法:
// 父組件2.6 新語法
默認插槽:default slot
具名插槽:title slot1
具名插槽:title slot2
new具名插槽:title slot1
new具名插槽:title slot2
作用域插槽:item slot-scope {{ props }}
// 子組件// propData這個屬性名可以任意取
給大家推薦一個好用的BUG監控工具Fundebug,歡迎免費試用!
歡迎關注公眾號:前端工匠,你的成長我們一起見證!
珠峰架構課(強烈推薦)
Vue開發實戰
Vue.js 組件精講
Vue.js 官方文檔
Vue 組件通信全揭秘
vue修飾符--可能是東半球最詳細的文檔(滑稽)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/104240.html
摘要:五六月份推薦集合查看最新的請點擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...
摘要:五六月份推薦集合查看最新的請點擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...
摘要:依舊采取傳統的開發技術棧進行開發,同時在終端的運行體驗不輸。首先來看下前端開發框架目前與構成了三大最流行的前端開發框架,具有組件化以及三大特性,還學習的,引入了狀態管理模塊。 摘要: WEEX依舊采取傳統的web開發技術棧進行開發,同時app在終端的運行體驗不輸native app。其同時解決了開發效率、發版速度以及用戶體驗三個核心問題。那么WEEX是如何實現的?目前WEEX已經完全開...
摘要:毫無疑問,設計模式于己于他人于系統都是多贏的設計模式使代碼編寫真正工程化設計模小書前端掘金這是一本關于的小書。 JavaScript 常見設計模式解析 - 掘金設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。毫無疑問,設計模式于己于他人于系統都是多贏的;設計...
閱讀 3659·2021-09-22 15:15
閱讀 3564·2021-08-12 13:24
閱讀 1312·2019-08-30 15:53
閱讀 1824·2019-08-30 15:43
閱讀 1184·2019-08-29 17:04
閱讀 2794·2019-08-29 15:08
閱讀 1583·2019-08-29 13:13
閱讀 3088·2019-08-29 11:06