天天看點

Vue 元件,元件通信(父子,子父,非父子元件通信)

Vue 元件

Vue元件 其實是一個html、css、js等的一個聚合體。

元件定義:

Vue.extend() 得到的是一個構造函數VueComponent( options )

options即我們之前在new Vue( options )

Vue.component('VueHello', Hello )
 const Hello = Vue.extend({ // 元件選項
    template: `
      <div>
        <p> Vue Hello</p>
      </div>
    `,
  })
           

元件注冊

  • 全局注冊
  • 局部注冊
<div id="app">
    <Demo></Demo> 
    <Hello></Hello>
</div>
  
//js代碼
Vue.component('Hello',{
    template: '<div> 全局元件注冊簡寫 </div>',
    data () { //data為啥是一個函數?
    return {
       }
     }
  })
  new Vue({
    el: '#app',
    data: {},
    components: {
      'Demo': {
        template: '<div> 局部注冊簡寫 </div>'
      }
    },
  })
           

data為啥是一個函數?

因為元件是一個獨立的整體,我們希望它的資料也是獨立的,是以使用函數會有獨立作用域,傳回值必須是一個對象,因為要經過資料劫持處理。

父子元件通信

  • 在父元件模闆中,将父元件資料指派給子元件的自定義屬性
  • 在子元件模闆中,通過 props 屬性來接收綁定在自己身上的自定義屬性
<div id="app">
    <Father/>
</div>

<template id="father">
 <div>
    <h3> 父元件 </h3>
    <!-- 在父元件模闆中,使用單項資料綁定,将父元件資料指派給子元件的自定義屬性 -->
    <Son :money = "money"/>
  </div>
</template>

<template id="son">
   <div>
     <h5> 子元件 </h5>
     <p> 我老爸給了我: {{ money }} </p>
   </div>
 </template>

           

js代碼

Vue.component('Father',{
    template: '#father',
    data () {
      return {
        money: 2000
      }
    }
 })

 Vue.component('Son',{
    template: '#son',
    /* 子元件通過props屬性來接收綁定在自己身上的自定義屬性 */
    props: ['money'] // 這個屬性在子元件模闆中相當于全局變量,可以直接使用
 })

new Vue({
    el: '#app',
    data: {},
 })
           

子父元件通信

  • 在父元件模闆中,使用自定義事件綁定(v-on監聽)父元件的方法
  • 在子元件模闆中,通過 $emit 調用(觸發)自定義事件
<div id="app">
    <Father/>v-on
</div>

  <template id="father">
    <div>
      <h3> father - 元件 </h3>
      <p> 我的小金庫有: {{ gk }} </p>
      <hr>
      <!-- 在父元件模闆中,使用自定義事件綁定父元件的方法 - get是自定義事件,名稱随意 -->
      <Son @get = "changeGk"/>
    </div>
  </template>

  <template id="son">
    <div>
      <h5> son - 元件 </h5>
      <button @click = "give"> 給老爸紅包 </button>
    </div>
  </template>

           

js代碼

Vue.component('Father',{
    template: '#father',
    data () {
      return {
        gk: 0
      }
    },
    methods: {
      changeGk ( val ) {
        this.gk = val
      }
    }
  })


  Vue.component('Son',{
    template: '#son',
    data () {
      return {
        hongbao: 888
      }
    },
    methods: {
      give () {
        // 在這裡調用自定義事件 get 
        // this.$emit('get',參數1,參數2,參數3 )
        this.$emit('get', this.hongbao )
      }
    }
  })

  new Vue({
    el: '#app',
    data: {},
  })
           

非父子元件通信

第一種:ref鍊實作

  • 在父元件模闆中,通過ref 獲得son元件的資訊,并執行son元件的事件
  • 在girl元件模闆中,通過 $emit 觸發父元件的事件(實際上是son的事件)
<div id="app">
    <Father/>
</div>
  
  <template id="father">
    <div>
      <h3> 父元件 </h3>
      <hr>
      <Son ref = "son"></Son>  
      <hr>
      <Girl @kick = "kick"/>
    </div>
  </template>

  <template id="son">
    <div>
      <h4> Son元件 </h4>
      <p v-if='f'>我被姐姐打了</p>
    </div>
  </template>

  <template id="girl">
    <div>
      <h4> Girl元件 </h4>
      <button @click = "hit"> 打 </button>
    </div>
  </template>
           
Vue.component('Father',{
    template: '#father',
    methods: {
      kick () {
        // 通過ref 獲得son 元件,并執行son元件的changeF
        // console.log( this )
        this.$refs.son.changeF()
      }
    }
  })

  Vue.component('Son',{
    template: '#son',
    data () {
      return {
        f: false 
      }
    },
    methods: {
      changeF () {
        this.f = !this.f
      }
    }
  })

  Vue.component('Girl',{
    template: '#girl',
    methods: {
      hit () {
        this.$emit('kick')  //觸發父元件的kick事件
      }
    }
  })

  new Vue({
    el: '#app',
    data: {},
    methods: {
      
    },
  })
           

第二種:bus事件總線實作

  • 在son元件模闆中,通過bus.$on監聽一個自定義事件
  • 在girl元件模闆中,通過 bus.$emit 觸發son元件的自定義事件
<div id="app">
    <Father/>
</div>
  
  <template id="father">
    <div>
      <h3> 父元件 </h3>
      <hr>
      <Son></Son>  
      <hr>
      <Girl/></Girl>
    </div>
  </template>

  <template id="son">
    <div>
      <h4> Son元件 </h4>
      <p v-if='f'>我被姐姐打了</p>
    </div>
  </template>

  <template id="girl">
    <div>
      <h4> Girl元件 </h4>
      <button @click = "hit"> 打 </button>
    </div>
  </template>
           

js代碼

const bus = new Vue() // 事件總線
  //console.log(bus)
  
  Vue.component('Father',{
    template: '#father',
  })

  Vue.component('Son',{
    template: '#son',
    data () {
      return {
        f: false 
      }
    },
    mounted () { // 表示元件已經挂載結束,也就是表示這個元件已經渲染到了頁面
      // console.log('mounted')
      bus.$on('cry',() => {  //監聽事件
        this.f = !this.f
      })
    }
  })

  Vue.component('Girl',{
    template: '#girl',
    methods: {
      hit () {
        bus.$emit('cry')  //觸發son元件的事件
      }
    }
  })
  new Vue({
    el: '#app',
    data: {},
    methods: {
      
    },
  })
           

繼續閱讀