Vue組件之間的通信你知道多少

Vue組件間通信

vue組件間通信分為以下幾種:

  • 父向子傳遞數據,用自定義屬性
  • 子向父傳遞數據,用自定義事件
  • 兄弟(任意)組件間傳遞數據,用全局事件總線或者消息訂閱與發佈

背吧,面試題要是說讓你簡述一下,就上面這段話拿過來回答唄。下面就介紹一下這幾種通信方式的簡單用法

1.父向子傳遞數據

前面已經說瞭,父向子傳遞數據用的是自定義屬性,接下來就讓我們看下代碼是怎麼寫的

//這是父組件,Father.vue
<template>
  <div class="father">
    <!-- 父組件向子組件傳遞person對象 -->
    <Son :person="person"/>
  </div>
</template>
<script>
export default {
    data (){
        return {
            person:{name:'張三',age:18,sex:'男'}
        }
    }
}
</script>
//這是子組件,Son.vue
<template>
  <div class="son">
      <h2>我是子組件</h2>
      <div>
        <h4>個人信息展示</h4>
		<ul>
            <li><label>姓名:</label><span>{{person.name}}</span></li>
            <li><label>年齡:</label><span>{{person.age}}</span></li>
            <li><label>性別:</label><span>{{person.sex}}</span></li>
        </ul>
      </div>
  </div>
</template>
<script>
export default {
  //子組件通過props接收父組件傳遞過來的數據
  props:['person']
}
</script>

這裡題外話,簡單的介紹下props

1.props的大小寫

當我們使用自定義屬性傳遞數據的時候,自定屬性的名稱可能不會簡單的是一個單詞,那這個時候我們該如何書寫呢?請看如下代碼

//父組件 父組件傳遞瞭 company-name
<Son company-name = "Microsoft"></Son>
//子組件 子組件接收時的寫法
<script>
export default {
    props:['companyName']
}
</script>

2.props的兩種寫法

第一種是簡單的寫法

props:['name','age','sex']

第二種是對象形式的寫法

props:{
    name:{
        type:String,
        required:true,
        default:''
    },
    age:{
        type:Number,
        required:true,
        default:0
    },
    sex:String
}

這兩種寫法根據實際情況來決定,一般的使用第一種就可以滿足需求

3.傳遞動態props

通過v-bind為組件傳遞動態數據類型

<Son :categoryList="categoryList"></Son>
<script>
export default {
	data (){
        return {
            //購物車列表數據
            categoryList:[]
        }
    }        
}
</script>

2.子向父傳遞數據

前面講到,子向父傳遞數據需要用到自定義事件,但是這裡通過自定義屬性也可以實現,我們一起來看一下

//子組件 Son.vue
<template>
  <div class="son">
    <button @click="sendMsgForFather">發送信息</button>
  </div>
</template>
<script>
export default {
  props:['getSonMessage'],
  methods:{
    sendMsgForFather(){
      this.getSonMessage(`我是子組件,你好啊`)
    }
  }
}
</script>
//父組件 Father.vue
<template>
  <div class="father">
    <h1>我是父組件</h1>
    <Son :getSonMessage="getSonMessage"/>
  </div>
</template>
<script>
import Son from '@/components/Son.vue'
export default {
  components : {
    Son
  },
  methods:{
    getSonMessage(msg){
      console.log(`我收到瞭子組件傳遞過來的信息:${msg}`);
    }
  }
}
</script>

下面這段代碼是通過自定義事件實現的

//子組件 Son.vue
<template>
  <div class="son">
    <button @click="sendMsgForFather">發送信息</button>
  </div>
</template>
<script>
export default {
  props:['getSonMessage'],
  methods:{
    //發送信息給父組件
    sendMsgForFather(){
      this.$emit('eventN',`我是子組件,hello`)
    }
  }
}
</script>
//父組件 Father.vue
<template>
  <div class="father">
    <h1>我是父組件</h1>
    <Son @eventN="demo"/>
  </div>
</template>
<script>
import Son from '@/components/Son.vue'
export default {
  components : {
    Son
  },
  methods:{
    demo(msg){
      console.log(`觸發瞭demo函數,${msg}`);
    }
  }
}
</script>

其實理解起來還是很簡單的,給子組件上綁定一個自定義事件,子組件上的自定義事件通過$emit觸發,而$emit通過子組件上的按鈕點擊事件來觸發,最終將數據發送給父組件,父組件通過demo函數拿到並展示數據,估計聽完我說的,肯定蒙瞭。研究一下代碼,自己敲一下就明白瞭

3.兄弟(任意)組件間的傳值

兄弟組件間的傳值方法比較多,包括我們甚至可以通過逐層使用自定義屬性自定義事件來實現,但代碼看起來可能不是那麼舒服,甚至把自己都給繞暈瞭,我自己也試過,想想這種方法知道就行,效率太低瞭。接下來就講講目前主流的幾種兄弟組件間傳值的方法

3.1全局事件總線

//main.js中安裝全局事件總線
new Vue({
  render: h => h(App),
  beforeCreate(){
    Vue.prototype.$bus = this //安裝全局事件總線
  }
}).$mount('#app')
//消息發送方 SendCom.vue
<template>
  <div class="send-container">
    <!-- SendCom 向組件 GetMsg 發送信息,通過$emit觸發自定義事件-->
    <button @click="sendMsg">發送消息</button>
  </div>
</template>
<script>
export default {
  methods:{
    sendMsg(){
      this.$bus.$emit('eventB','hello')
    }
  }
}
</script>
//消息接收方 GetMsg.vue
<template>
  <div class="get-msg-container">
  </div>
</template>
<script>
export default {
  mounted() {
    console.log(this);
    this.$bus.$on('eventB', (data) => {
      console.log(`我是事件接受方Demo2,我收到瞭數據${data}`);
    });
  },
  beforeDestroy() {
    this.$bus.$off('eventB') //在使用完後將事件解綁
  }
};
</script>

3.2消息訂閱與發佈

消息訂閱與發佈在原生js下實現比較復雜,這裡使用第三方庫pubsub-js,通過npm i pubsub-js安裝。

//消息訂閱者(接收方) Subscribe.vue
<template>
  <div class="subscribe">
  </div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
    mounted(){
        this.pubId = pubsub.subscribe('message',(msgName,data)=>{
            console.log(`我收到瞭消息${msgName},內容是${data}`);
        })
    },
    beforeDestroy(){
        pubsub.unsubscribe(this.pubId)
    }
}
</script
//消息發佈者(發送方) Publish.vue
<template>
  <div class="publish">
      <button @click="sendMsg">點擊發送</button>
  </div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
    methods:{
        sendMsg(){
            pubsub.publish('message','這是訂閱的消息')
        }
    }
}
</script>

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: