Vue組件深入

vue組件深入

組件注冊

  1. 全局注冊
  2. 局部注冊

prop

prop的大小寫

camelCase vs Kebab-case

kebab-case

prop類型

props: {
  title: String,
  likes: Number,
  isPublished: Boolean,
  commentIds: Array,
  author: Object,
  callback: Function,
  contactsPromise: Promise // or any other constructor
}

傳靜態(tài)或動態(tài)prop

prop可以通過v-bind動態(tài)賦值

<!-- 動態(tài)賦予一個變量的值 -->
<blog-post v-bind:title="post.title"></blog-post>

<!-- 動態(tài)賦予一個復雜表達式的值 -->
<blog-post
  v-bind:title="post.title + ' by ' + post.author.name"
></blog-post>
  1. 傳入一個數字
  2. 傳入一個布爾值
<!-- 包含該 prop 沒有值的情況在內,都意味著 `true`智玻。-->
<blog-post is-published></blog-post>
  1. 傳入一個數組
  2. 傳入一個對象

v-bind告訴JavaScript表達式是動態(tài)的而不是一個字符串

prop單向數據流

  1. 在組件中使用props來從父親組件接受數據爆惧,在props中定義的屬性,都可以在組件中直接使用
  2. props來自父級俏竞,而組件中的data return的數據就是組件自己的數據至非,兩種情況作用域就是組件本身篷朵,可以直接在template勾怒,computed,methods中直接使用
  3. 使用v-bind動態(tài)綁定來自父組件的值声旺。input

單向下行綁定:父級 prop 的更新會向下流動到子組件中笔链,但是反過來則不行。這樣會防止從子組件意外改變父級組件的狀態(tài)腮猖,從而導致你的應用的數據流向難以理解鉴扫。

應該在一個子組件內部改變 prop。如果你這樣做了澈缺,Vue 會在瀏覽器的控制臺中發(fā)出警告坪创。

注意在 JavaScript 中對象和數組是通過引用傳入的,所以對于一個數組或對象類型的 prop 來說姐赡,在子組件中改變這個對象或數組本身將會影響到父組件的狀態(tài)莱预。

兩種常見的prop情形

一種是父組件傳遞初始值進來,子組件將它作為初始值保存起來项滑,在自己的作用域 下可以隨意使用和修改依沮。這種情況可以在組件 data 內再聲明一個數據,引用父組件 的 prop

步驟一:注冊組件

步驟二:將父組件的數據傳遞進來枪狂,并在子組件中用props接收 步驟三:將傳遞進來的數據通過初始值保存起來

props: ['initialCounter'],
data: function () {
 return {
   counter: this.initialCounter
 }
}

另一種情況就是 prop 作為需要被轉變的原始值傳入危喉。這種情況用計算屬性就可以了

步驟一:注冊組件

步驟二:將父組件的數據傳遞進來,并在子組件中用props接收 步驟三:將傳遞進來的數據通過計算屬性進行重新計算

props: ['size'],
computed: {
 normalizedSize: function () {
   return this.size.trim().toLowerCase()
 }
}

自定義事件

v-model

一個組件上的v-model會利用名為value的prop和名為input的事件州疾,但是像但是像單選框辜限、復選框等類型的輸入形控件可能會將value特性用于不同的目的

model選項可以用來避免這樣的沖突

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

現在在這個組件上使用v-model的時候

<base-checkbox v-model="lovingVue"></base-checkbox>

這里的 lovingVue 的值將會傳入這個名為 checked 的 prop。同時當 `` 觸發(fā)一個 change 事件并附帶一個新的值的時候严蓖,這個 lovingVue 的屬性將會被更新薄嫡。

.sync修飾符

對prop進行雙向綁定氧急,但真正的雙向綁定會帶來維護上的問題,因為子組件可以修改父組件岂座,但在父組件和子組件都沒有明顯的改動來源

推薦updata:myPropName的模式取而代之。

在一個包含title prop的假設組件中杭措,我們可以用以下方法表達對其復新值的意圖

this.$emit('updata:title',newTitle)

然后父組件可以監(jiān)聽那個事件并根據需要更新一個本地的數據屬性费什。

<text-document
  v-bind:title="doc.title"
  v-on:update:title="doc.title = $event"
></text-document>
//doc.title = newTitle 
1.當updata:title事件被觸發(fā)時,將newTitle通過自定義的updata:title事件拋出
2. 在父組件上監(jiān)聽并綁定本地數據手素,實現雙向綁定

為了方便起見鸳址,給這種模式提供一個縮寫.sync修飾符

<text-document v-bind:title.sync="doc.title"></text-document>
//子組件
this.$emit('updata:title',newTitle)

關于prop的雙向綁定

舉個例子就以title改變?yōu)槔?/p>

父 ->子

父的本地數據 data下的doc.title ->

父組件v-bind:title="doc.title"->

子組件的props title:{type:String}

子組件使用props可寫在子組件data中

子 -> 父

子組件 this.$emit('updata:title',newTitle) ->

父組件 v-on:update:title="doc.title = $event" ->

父組件 v-bind:title="doc.title" ->

父組件 data doc.title 改變

prop雙向綁定相比v-model更靈活,總結父子組件上的v-bind時雙向綁定的數據接口泉懦,父到子通過props 稿黍,子到父通過自定義事件。

關于在組件上使用v-model的雙向綁定

因為原生的JavaScript的<input>有value屬性 所以為了父到子通信

舉個例子

父->子

父自定義組件的data->

父的this.msg ->

父組件v-bind:value= 'msg' ->

子組件的props value:{type:String}改變 ->

子組件v-bind:value = value(來自子props)>

子的JavaScript<input>

因為原生的JavaScript的<input>有value屬性 所以為了父到子通信 父和子都要動態(tài)綁定value屬性崩哩。

子->父

子組件的JavaScript<input> ->

子組件輸入改變v-bind:value->

子組件v-on:input:$emit('input' , $event.target.value) ->

父組件v-on:input(msg = $event) ->

父的this.msg ->

父的data ->

父的{{msg}}

因為原生的JavaScript的<input>有input事件巡球,所以為了子到父通信,子組件觸發(fā)input事件時采用自定義input事件邓嘹,在父組件上監(jiān)聽input事件

插槽slot

一條規(guī)則

父級模板里的所有內容都是在父級作用域中編譯的酣栈;子模板里的所有內容都是在子作用域中編譯的。

編譯作用域

<navigation-link url="/profile">
  Clicking here will send you to: {{ url }}
  <!--
  這里的 `url` 會是 undefined汹押,因為 "/profile" 是
  _傳遞給_ <navigation-link> 的而不是
  在 <navigation-link> 組件*內部*定義的矿筝。
  -->
</navigation-link>

后備內容

<button type="submit">
  <slot>Submit</slot>
</button>

如果提供內容Submit就會被取而代之

具名插槽slot

新語法v-slot或#

v-slot:default

v-slot:name

作用域插槽slot

V-slot:name = "slotProps"

動態(tài)組件&異步組件

用is在多標簽的界面來切換不同組件的時候,有時需要保持這些組件的狀態(tài)棚贾,避免反復沖渲染導致的性能問題

讓重新創(chuàng)建的動態(tài)組件能夠在它們被第一次創(chuàng)建的時候緩存下來窖维。為了解決這個問題,可以用個<keep-alive>元素將其動態(tài)組件包裹起來妙痹。

<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

里面的組件一定要有自己的名字

處理邊界情況

訪問元素&組件

  1. 訪問根實例$root: 對于小型的有少量的組件應用來說是很方便铸史,大型項目使用vuex來管理應用的狀態(tài)
  2. 訪問父組件實例$parent:用與簡單直接的父子組件,當需要向任意更深層的組件提供上下文信息使怯伊,使用依賴注入
  3. 訪問子組件實例或子元素$refs:在組件渲染完成后生效沛贪。

依賴注入

provide inject

  • provide選項,允許我們指定我們想要提供給后代組件的數據方法震贵。
  • inject選項利赋,在后代組件里,使用inject選項來接受指定的想要添加在這個實例上的屬性

可以猩系;把依賴注入看作一部分"大范圍有效的prop"一樣

  • 祖先組件不需要知道哪些后代組件使用它提供的屬性
  • 后代組件不需要知道被注入的屬性來自哪里

程序化的事件偵聽器

組件之間的循環(huán)應用

兩個相互依賴的組件A媚送、B ,需要給系統(tǒng)一個點寇甸,告訴系統(tǒng)A是需要B的塘偎,但我們不需要向解析B

  1. 在生命周期鉤子beforeCreate時注冊
  2. 在本地注冊組件的時候疗涉,使用webpack的一步import
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吟秩,隨后出現的幾起案子咱扣,更是在濱河造成了極大的恐慌,老刑警劉巖涵防,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闹伪,死亡現場離奇詭異,居然都是意外死亡壮池,警方通過查閱死者的電腦和手機偏瓤,發(fā)現死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椰憋,“玉大人厅克,你說我怎么就攤上這事〕纫溃” “怎么了证舟?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長窗骑。 經常有香客問我褪储,道長,這世上最難降的妖魔是什么慧域? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任鲤竹,我火速辦了婚禮,結果婚禮上昔榴,老公的妹妹穿的比我還像新娘辛藻。我一直安慰自己,他們只是感情好互订,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布吱肌。 她就那樣靜靜地躺著,像睡著了一般仰禽。 火紅的嫁衣襯著肌膚如雪氮墨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天吐葵,我揣著相機與錄音规揪,去河邊找鬼。 笑死温峭,一個胖子當著我的面吹牛猛铅,可吹牛的內容都是我干的。 我是一名探鬼主播凤藏,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼奸忽,長吁一口氣:“原來是場噩夢啊……” “哼堕伪!你這毒婦竟也來了?” 一聲冷哼從身側響起栗菜,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤欠雌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后疙筹,有當地人在樹林里發(fā)現了一具尸體富俄,經...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年腌歉,在試婚紗的時候發(fā)現自己被綠了蛙酪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片齐苛。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡翘盖,死狀恐怖,靈堂內的尸體忽然破棺而出凹蜂,到底是詐尸還是另有隱情馍驯,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布玛痊,位于F島的核電站汰瘫,受9級特大地震影響,放射性物質發(fā)生泄漏擂煞。R本人自食惡果不足惜混弥,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望对省。 院中可真熱鬧蝗拿,春花似錦、人聲如沸蒿涎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劳秋。三九已至仓手,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間玻淑,已是汗流浹背嗽冒。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留补履,地道東北人辛慰。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像干像,于是被迫代替她去往敵國和親帅腌。 傳聞我的和親對象是個殘疾皇子驰弄,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容

  • 組件注冊 組件名 在注冊一個組件的時候,我們始終需要給它一個名字速客。 該組件名就是Vue.component的第一個...
    oWSQo閱讀 399評論 0 1
  • 傳遞靜態(tài)或動態(tài)Prop 傳入靜態(tài)的值: 這時候值是一個字符串你也可以通過v-bind動態(tài)賦值: 這時候值是一個js...
    A鄭家慶閱讀 381評論 0 0
  • 什么是組件戚篙? 組件 (Component) 是 Vue.js 最強大的功能之一。組件可以擴展 HTML 元素溺职,封裝...
    youins閱讀 9,480評論 0 13
  • Vue 實例 屬性和方法 每個 Vue 實例都會代理其 data 對象里所有的屬性:var data = { a:...
    云之外閱讀 2,214評論 0 6
  • 此文基于官方文檔岔擂,里面部分例子有改動,加上了一些自己的理解 什么是組件浪耘? 組件(Component)是 Vue.j...
    陸志均閱讀 3,828評論 5 14