Vue造輪子-tab組件(中)

1. 若是給一個標籤一個class,標籤自己又有class,vue是默認會合並的。只有兩個屬性是這樣一個是class,一個是style。這樣就比較好改樣式。

<g-tabs-head class="red"></g-tabs>

2. 組件的結構以及selected的傳遞過程,見下圖。

  • 沒有點擊的圖

沒點擊.png

  • 發生了點擊操做的圖,兩個item兄弟之間是沒有關係的,發生了點擊操做以後要作下圖中的五件事情。html

    1. 亮本身
    2. 熄兄弟
    3. 亮pane
    4. 熄pane
    5. 觸發事件 update:selected -> item2

點擊.png

3. 接下去考慮代碼的實現,有兩種方案

  1. 第一種爺爺爸爸兒子以前互相通訊
  2. 用事件中心EventHub或者叫EventBus發佈訂閱模式實現,這種簡單

發佈訂閱.png

4. 下劃線開頭的屬性不要用是私有屬性給vue用的,$開頭的屬性是專門能夠用的

5. 在爺爺tabs組件上面加了privide後代均可以用,其餘的屬性只提供給兒子不提供給孫子,只有provide是任何後代均可以訪問的。

// tabs.vue這樣就有了eventBus   
   data(){
      return {
        eventBus: new Vue()
      }
    },
    provide(){
      return {
        eventBus:this.eventBus
      }
    },
    created(){
      console.log('爺爺的eventBus')
      console.log(this.eventBus)
      // this.$emit('update:selected','xxx')
    }

    // tabs-head.vie兒子就有了eventBus,其餘組件同理
    inject: ['eventBus'],
    created(){
      console.log('爺爺給爸爸的eventBus')
      console.log(this.eventBus)
    }
下圖橙色字的地方就是provide

provide.png

6.取函數名字的時候先取一個必需要改的名字,以後再改

created(){
      this.eventBus.$on('update:selected',(name)=>{
        console.log(name)
      })
      // 這句話的意思是監聽selected被更新了,而且執行一個回調,這裏監聽的多是其它的組件
    },
    methods: {
      xxx(){
        this.eventBus.$emit('update:selected',this.name)
        // 這句話的意思是大聲喊出來selected更新了
      }
    }

7.index.html中,在g-tabs中監聽update:selected事件,不會觸發yyy,vue的事件是不會冒泡的,在哪裏觸發就在哪裏,可是這個問題不是冒泡問題

// 咱們的eventBus是g-tabs生成的new Vue(),而app.js監聽的g-tabs,是一個vue組件,
  // 也就是vue組件的事件,而不是new Vue()
  <g-tabs :selected.sync="selectedTab" @update:selected="yyy"></g-tabs>
    methods: {
        yyy(data){
            console.log('yyy')
            console.log(data)
        }
    }

    // 那麼組件怎麼觸發呢
    // tabs.vue
    created(){
        this.$emit('update:selected', '這是 this $emit 出來的數據') // 這樣寫能夠觸發外面,這裏的this
        就是當前組件
        this.eventBus.$emit('update:selected', '這是 this event $emit 出來的數據') // 這樣寫不能夠觸發外面
    }
    // app.js
    <g-tabs :selected.sync="selectedTab" @update:selected="yyy"></g-tabs>
    methods: {
        yyy(data){
            console.log('yyy')
            console.log(data)
        }
    }
  • 總結:事件要看在哪一個對象上觸發的,你須要知道你觸發的事件是在哪一個對象上觸發的,一個是在this上面,一個是在this的eventBus上面,每一個對象均可以觸發不一樣事件。

8. 若是在tabs-header上不會觸發

// tabs-head
    created(){
      this.$emit('update:selected', '這是 tabs-head 拋出來的數據') 
      // 這樣寫不能夠觸發外面是由於vue的事件系統是不會冒泡的,
      //若是g-tabs-head標籤是一個div那麼是能夠觸發到g-tabs的由於div是能夠冒泡的
    }
    // index.html
     <g-tabs :selected.sync="selectedTab" @update:selected="yyy">
        <g-tabs-head class="red">
            <template slot="actions">
                <button>設置</button>
            </template>
        </g-tabs-head>
    </g-tabs>

9.關於Vue的事件要注意點

  • 事件是在哪一個對象上調用的,在哪一個對象上調用就只能在那個對象上監聽
  • 事件不會冒泡,子標籤觸發的事件不會自動傳到父標籤

我的微信,歡迎交流!

IMG_0146.jpg

相關文章
相關標籤/搜索