Vue組件通信方式(父傳子、子傳父、兄弟通信)
父組件傳到子組件
父組件是通過props屬性給子組件通信的
數據是單向流動 父—>子 (子組件中修改props數據,是無效的,會有一個紅色警告)
1. 父組件parent.vue代碼如下:
<template> <div class="parent"> <h2>{{ msg }}</h2> <son :fa-msg="msg"></son> <!-- 子組件綁定faMsg變量,註意駝峰--> </div> </template>
<script> import son from './Son' //引入子組件 export default { name: 'HelloWorld', data () { return { msg: '父組件', } }, components:{son}, } </script>
2. 子組件son代碼如下:
<template> <div class="son"> <p>{{ sonMsg }}</p> <p>子組件接收到內容:{{ faMsg }}</p> </div> </template>
<script> export default { name: "son", data(){ return { sonMsg:'子組件', } }, props:['faMsg'],//接收psMsg值 } </script>
子組件通過props來接受數據
- 第一種方法
props: ['childCom']
- 第二種方法
props: { childCom: String //這裡指定瞭字符串類型,如果類型不一致會警告的哦 }
- 第三種方法
props: { childCom: { type: String, default: 'sichaoyun' } }
子組件向父組件傳值
通過綁定事件然後及$emit傳值
vue2.0隻允許單向數據傳遞,我們通過出發事件來改變組件的數據
1.父組件parent代碼如下:
父組件通過綁定自定義事件,接受子組件傳遞過來的參數
<template> <div class="parent"> <h2>{{ msg }}</h2> <p>父組件接手到的內容:{{ username }}</p> <son psMsg="我是你爸爸" @transfer="getUser"></son> <!-- 監聽子組件觸發的transfer事件,然後調用getUser方法 --> </div> </template>
<script> import son from './Son' export default { name: 'HelloWorld', data () { return { msg: '父組件', username:'', } }, components:{son}, methods:{ getUser(msg){ this.username= msg } } } </script>
2.子組件son代碼如下:
子組件通過$emit觸發父組件上的自定義事件,發送參數
<template> <div class="son"> <p>{{ sonMsg }}</p> <p>子組件接收到內容:{{ psMsg }}</p> <!--<input type="text" v-model="user" @change="setUser">--> <button @click="setUser">傳值</button> </div> </template>
<script> export default { name: "son", data(){ return { sonMsg:'子組件', user:'子傳父的內容' } }, props:['psMsg'], methods:{ setUser:function(){ this.$emit('transfer',this.user)//觸發transfer方法,this.user 為向父組件傳遞的數據 } } } </script>
非父子傳參 (事件總線)
假設你有兩個Vue組件需要通信: A 和 B ,A組件按鈕上面綁定瞭點擊事件,發送一則消息,B組件接收。
1. 初始化,全局創建$bus
直接在項目中的 main.js 初始化 $bus :
// main.js window.$bus=new Vue();
註意,這種方式初始化一個 全局的事件總線 。
2. 發送事件
$bus.$emit("aMsg", '來自A頁面的消息');
<!-- A.vue --> <template> <button @click="sendMsg()">-</button> </template>
<script> //import $bus from "../bus.js"; export default { methods: { sendMsg() { $bus.$emit("aMsg", '來自A頁面的消息'); } } }; </script>
接下來,我們需要在 B頁面 中接收這則消息。
4. 接收事件
$bus.$on("事件名",callback)
<!-- IncrementCount.vue --> <template> <p>{{msg}}</p> </template>
<script> //import $bus from "../bus.js"; export default { data(){ return { msg: '' } }, mounted() { $bus.$on("aMsg", (msg) => { // A發送來的消息 this.msg = msg; }); } }; </script>
<<<<<<<<<<<<<<下方是拓展,面試不必說>>>>>>>>>>>
事件總線推薦下面寫法:
集中式的事件中間件就是 Bus。我習慣將bus定義到全局:
app.js
var eventBus = { install(Vue,options) { Vue.prototype.$bus = vue } }; Vue.use(eventBus);
然後在組件中,可以使用$emit, $on, $off 分別來分發、監聽、取消監聽事件:
分發事件的組件
// ... methods: { todo: function () { this.$bus.$emit('todoSth', params); //params是傳遞的參數 //... } }
監聽的組件
// ... created() { this.$bus.$on('todoSth', (params) => { //獲取傳遞的參數並進行操作 //todo something }) }, // 最好在組件銷毀前 // 清除事件監聽 beforeDestroy () { this.$bus.$off('todoSth'); }
如果需要監聽多個組件,隻需要更改 bus 的 eventName:
// ... created() { this.$bus.$on('firstTodo', this.firstTodo); this.$bus.$on('secondTodo', this.secondTodo); }, // 清除事件監聽 beforeDestroy () { this.$bus.$off('firstTodo', this.firstTodo); this.$bus.$off('secondTodo', this.secondTodo); }
vue 跨頁面雙向通信
同源通信
1. localStorage
添加時間監聽
window.addEventListener('storage', function (e) {});
改變 localStorage 值,觸發 storage 事件
window.localStorage.setItem('params', JSON.stringify(object));
2. 通過跳轉 url 傳參
// 跳轉路徑帶參數
3. 通過 BroadCast channel 廣播實現通信
// 創建一個廣播頻道 const bc = new BroadcastChannel('kaixin');
// 其他頁面可以通過onmessage來監聽被廣播的消息 bc.onmessage = function (res) { const data = res.data; };
// 發送消息時直接調用實例上的postMessage方法 bc.postMessage(data);
4. shareWorker
非同源通訊
1. iframe 嵌套
1、發送消息 window.postMessage(message, targetOrigin, [transfer]) // message 需要傳的數據[object] // 目標窗口(URI), *代表沒有限制任何窗口都能接收 // transfer 是一串和message 同時傳遞的 Transferable 對象. 這些對象的所有權將被轉移給消息的接收方,而發送一方將不再保有所有權。 2、監聽發來的消息 window.addEventListener("message", receiveMessage, false); // receiveMessage 處理函數[$event] function receiveMessage(event){ // 參數 event // event.data 就是你傳的參數 // event.origin 發送者的目標url,做安全驗證 // event.source 發送者的window對象 }
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。