Vue.js-資料-組件化思想 —下

1、組件間的通訊vue

 

       組件實例的做用域是孤立的;這意味着不能而且不該該在子組件的模板內直接引用父組件的數據。可是父子組件之間須要通訊:父組件要給子組件傳遞數據,子組件須要將它內部發生的事情告知給父組件。數組

 

       在 Vue.js 中,父子組件的關係能夠總結爲 props down, events up 。父組件經過 props 向下傳遞數據給子組件,子組件經過 events 給父組件發送消息。以下圖所示:this

 

 

2、 Prop — 父組件傳遞數據給子組件spa

 

       prop 是父組件用來傳遞數據的一個自定義屬性。子組件須要顯式地用 props 選項聲明 「prop」:3d

 

 Vue.component('child', {component

  // 聲明 props對象

  props: ['message'],索引

  // 就像 data 同樣,prop 能夠用在模板內接口

  // 一樣也能夠在 vm 實例中像 「this.message」 這樣使用事件

  template: '<span>{{ message }}</span>'

  })

 

2.1 簡單的傳值

 

 

注意:HTML 特性不區分大小寫。當使用非字符串模版時,prop的名字形式會從 camelCase 轉爲 kebab-case(短橫線隔開)。

 

2.2  父組件傳值給子組件,動態綁定

 

 

 

運行結果:

 

 

 

父組件傳遞數據給子組件圖解:

 

 

 

2.3 prop默認是單向綁定

 

       當父組件的屬性變化時,將傳導給子組件,可是反過來不會。這是爲了防止子組件無心修改了父組件的狀態。

 

案例驗證:

 

 

運行結果:

 

 

結論:在vuejs2.0中,任何試圖在組件內修改經過props傳入的父組件數據都被認爲是anti-pattern的。

 

3、自定義事件

 

      咱們知道,父組件是使用 props 傳遞數據給子組件,但若是子組件要把數據傳遞回去,應該怎樣作?那就是自定義事件!

 

       每一個 Vue 實例都實現了事件接口(Events interface),即:

 

使用 $on(eventName) 監聽事件

使用 $emit(eventName) 觸發事件

  

       另外,父組件能夠在使用子組件的地方直接用 v-on 來監聽子組件觸發的事件。

 

一個簡單的官方案例幫助咱們來理解:

 

 

運行結果:子組件已經和它外部徹底解耦了。它所作的只是觸發一個父組件關心的內部事件。

 

 

 

4、Slot插槽 — 實現內容分發

 

父組件模板的內容在父組件做用域內編譯;子組件模板的內容在子組件做用域內編譯

 

       上面話的意思在於:在子組件中定義的數據,只能用在子組件的模板;在父組件中定義的數據,只能用在父組件的模板。若是父組件的數據要在子組件中使用,則須要子組件定義props。

 

4.1  什麼是slot?

 

 

       slot的意思是插槽,其目的在於讓組件的可擴展性更強。打個比方說:假如父組件須要在子組件內放一些DOM,那麼這些DOM是顯示、不顯示、在哪一個地方顯示、如何顯示,就是slot分發負責的。

 

(1) 匿名solt

 

下面這個示例是一個匿名slot,它只能表示一個插槽:

    

 

        結合上述案例,咱們再進一步來了解:好比咱們定製了一個button組件,在根組件裏註冊爲vButton,從而複用。那麼各個button上的文字確定是不一樣的,可是這些文字大部分狀況下也是不須要動態更新的,那麼就沒必要用props之類的方法從根組件向子組件傳遞文字,直接用slot便可。

 

(2) 實名solt

 

       假設你的電腦主板上的各類插槽,有插CPU的,有插顯卡的,有插內存的,有插硬盤的,因此假設有個組件是computer,其模板是:

 

<template id="computer">

<div>

  <slot name="CPU">這兒插你的CPU</slot>

  <slot name="GPU">這兒插你的顯卡</slot>

  <slot name="Memory">這兒插你的內存</slot>

  <slot name="Hard-drive">這兒插你的硬盤</slot>

</div>

</template>

 

那麼,你想要配置一臺電腦,就能夠這麼寫:

 

<computer>

  <div slot="CPU">Intel Core i7</div>

  <div slot="GPU">GTX980Ti</div>

  <div slot="Memory">Kingston 32G</div>

  <div slot="Hard-drive">Samsung SSD 1T</divt>

</computer>

 

具體代碼以下:

 

 

 

5、父子組件之間相互訪問

 

       

       在開發中,組件之間須要相互訪問。好比:父組件訪問子組件,子組件訪問父組件,或者是子組件訪問根組件。

 

針對這種狀況,Vue.js提供瞭如下API:

 

父組件訪問子組件:使用$children或$refs  (一個對象,其中包含了全部擁有 ref 註冊的子組件)

  

子組件訪問父組件:使用$parent

  

子組件訪問根組件:使用$root 

 

5.1 $children

 

 

運行結果:

 

 

       在父組件中,經過this.$children能夠訪問子組件;this.$children是一個數組,它包含全部子組件的實例。

 

5.2  $refs

 

       在子組件上使用v-ref指令,能夠給子組件指定一個索引ID;經過這個ID咱們能夠拿到這個組件。

 

<template id="parent-component">

       <div>

           <first-component  ref="fc1"></first-component>

           <second-component ref="fc2"></second-component>

           <button @click="printAllChildComponent">輸出子組件</button>

       </div>

 </template>

 

在父組件中,則經過```$refs.索引ID```訪問子組件的實例。

 

5.3 $parent

 

<template id="first-component">

       <div>

           <h2>{{ content }}</h2>

           <button @click="printParentComponent">獲取父組件</button>

       </div>

    </template>

 

'first-component': {

                template: '#first-component',

                data:function () {

                    return {

                        content: '我是子組件1'

                    }

                },

                methods: {

                    printParentComponent: function () {

                        console.log(this.$parent.$el);

                    }

                }

            }

 

 

運行結果:

 

 

注意事項:

 

 儘管子組件能夠訪問父鏈上任意的實例,不過子組件應當避免直接依賴父組件的數據,儘可能顯式地使用 props 傳遞數據。

 

另外,在子組件中修改父組件的狀態是很是不提倡的作法,由於:這讓父組件與子組件緊密地耦合;只看父組件,很難理解父組件的狀態。由於它可能被任意子組件修改!理想狀況下,只有組件本身能修改它的狀態。

相關文章
相關標籤/搜索