前言
Vue組件之間的通信 其實是一種非常常見的場景 不管是業務邏輯還是前段面試中都是非常頻繁出現的 這篇文章將會逐一講解各個傳值的方式 不過在此之前 先來總結一下各個傳值方式吧
- 1.父組件向子組件傳值 =>
props
- 2.子組件向父組件傳值 =>
$emit
- 3.平級組件傳值 => 總線機制
event-bus
- 4.Vuex
父組件向子組件傳值
舉個? 你在項目中定義了一個公共組件Header 這個Header里需要根據具體的業務場景去展示不同的title 那這個時候就是一個非常常見的父組件向子組件傳值的業務場景了
下面 一起來看一下代碼 首先 定義一個公用的Header組件 這個組件里也沒有什么復雜的邏輯 就是用props接受一個父組件傳遞過來的title 并且渲染到頁面上
<template><!-- 通用導航欄 --><div class="head-title">{{title}}</div>
</template><script>
export default {name: 'Header',props: {title: String}
}
</script>
復制代碼
父組件其實也是啥都沒有 也就是引入Header組件 并且向子組件傳遞一個title的值 子組件利用props接收到這個值 并且渲染在頁面上
<template><div class="container"><Header :title="title" /></div>
</template><script>
import Header from "components/header/header";
export default {name: "Home",data() {return {title: "首頁"}},components: {Header}
}
</script>
復制代碼
這樣就完成了一個最簡單最基礎的父組件向子組件傳值的過程 不過呢 這個props
Vue其實也是支持許多拓展的了 *
- 例如開發者可以通過
defalut
去定義一個默認值 當沒有接受到父組件傳遞過來的值的時候 可以展示這個默認值 type
給props指定一個類型 當類型不符合預期的時候 會在控制臺上報錯- 當默認的校驗規則都無法滿足要求的時候 props也支持自定義一個validator 只需要在props里傳遞一個validator函數即可
props: {title: {validator: function () {// do somethings}}
}
復制代碼
子組件向父組件傳值
說到子組件向父組件傳值之前 需要解釋一個名詞 單項數據流
也就是 子組件不能隨意更改父組件傳遞過來的值 以免造成一些數據污染之類的情況 推薦的做法是 如果子組件想要更改一個值 應該是通知父組件 讓父組件進行更改
話不多說 還是繼續縷一縷思路 然后寫代碼 首先 需要在子組件里定義一個事件 例如點擊事件 通過點擊向父組件派發一個事件同時可以在事件里攜帶需要向外傳遞的值 同時父組件監聽到了這個事件 并且在事件里處理對應的邏輯
<template><!-- 通用導航欄 --><div class="head-title" @click="toParent">{{title}}</div>
</template><script>
export default {name: 'Header',props: {title: String},methods: {toParent () {// 第一個參數 需要父組件監聽的時間 第二個參數 向外傳遞的值this.$emit('getMsg','這是傳遞給父組件的值')}}
}
</script>
復制代碼
這個時候 子組件已經通過$emit
向外傳遞了一個事件 那么接下去就是在父組件里去監聽這個事件 并且處理對應邏輯
<template><div class="container"><Header :title="title" @getMsg="getMsg" /></div>
</template><script>
import Header from "components/header/header";
export default {name: "Home",data() {return {title: "首頁",msg: ''}},components: {Header},methods: {getMsg(msg) {console.log(this.msg)this.msg = msgconsole.log(this.msg)}}
}
</script>
復制代碼
這樣通過$emit
就可以成功獲取從子組件傳遞過來的值 并且父組件可以更改這個值 從而實現一些對應的業務邏輯
平級組件之間傳值
兩個沒什么關系的組件之間有時候也是會需要傳遞一些值 例如頁面A要傳遞值給頁面B B接受這個值并且渲染在頁面上
下面來說一下實現思路
- 1.創建一個js文件 在文件中新建一個vue的實例 并且在實例上新建一個EventBus 或者在vue的屬性上掛載一個envent-bus 這樣通過屬性的方式創建的event-bus是一個全局的屬性
- 2.在需要使用event-bus的組件里引入 bus并且利用
$emit
向外觸發事件 - 3.在需要接受值的組件里利用
$on
來接受值
新建一個.js文件 并且創建event-bus
import Vue from 'vue'
export const EventBus = new Vue()
復制代碼
利用enent-bus向外觸發事件
<template><button @click="handleClick">-</button>
</template><script> import { EventBus } from "../event-bus.js";export default {name: "Count",data () {return {num: 1,}},methods: {decrease() {EventBus.$emit("getNum", {num:this.num,})}}}
</script>
復制代碼
監聽事件
EventBus.$on("getNum", (num) => {console.log(num)})復制代碼
這樣就通過event-bus成功將頁面A的值傳遞給了頁面B的值 寫起來的感覺 其實還是和子組件向父組件傳值的過程非常相似
下面還會提到Vuex傳值 不過感覺可以新開一個文章..所以..下次再見啦 ??