參考文章:
Vue2.0子同級組件之間數據交互
1、父組件可以使用 props 把數據傳給子組件。
2、子組件可以使用 $emit 觸發父組件的自定義事件。
(一)父組件給子組件傳值,關鍵字:props
父組件:
<template> <div> <h1>父組件</h1>
<!-- 引入子組件 --> <child :sendMsg="fatherMsg"></child> </div> </template> <script> import child from '@/components/child' export default { name: 'father', components: { child }, data() { return { fatherMsg: '嗨,兒子' // 傳遞給子組件的值 } } } </script>
子組件:通過props拿到父組件傳遞過來的值
<template> <div> <h1>子組件</h1> <span>獲取父組件傳值:{{sendMsg}}</span> </div> </template> <script> export default { name: 'child', data() { return { } }, props: ['sendMsg'] // 拿到父組件綁定到sendMsg的值,然后在子組件下顯示出來 } </script>
(二)子組件給父組件傳值:通過觸發事件傳遞值
以上面的示例代碼作為基礎修改,子組件:
<template> <div> <h1>子組件</h1> <span>獲取父組件傳值:{{sendMsg}}</span><hr> <button @click="sendToFather">子組件給父組件傳值</button> </div> </template> <script> export default { name: 'child', data() { return { childMsg: '這是來自子組件的數據' } }, props: ['sendMsg'], methods: { sendToFather: function() { this.$emit('getChildValue', this.childMsg); // 參數1 getChildValue作為中間狀態,參數2 this.childMsg即為傳遞給父組件的數據 } } } </script>
父組件:
<template> <div> <h1>父組件</h1> <!-- 引入子組件 定義一個on的方法監聽子組件的狀態,然后通過getChild方法獲取子組件傳遞的數據--> <child :sendMsg="fatherMsg" v-on:getChildValue="getChild"></child> <span>這是來自子組件的數據:{{childValue}}</span> </div> </template> <script> import child from '@/components/child' export default { name: 'father', components: { child }, data() { return { fatherMsg: '嗨,兒子', childValue: '' } }, methods: { getChild: function(data) { // 此時的參數data為子組件傳遞的值,即this.$emit()的第二個參數 this.childValue = data; } } } </script>
(三)同級組件傳遞數據
對於同級組件傳值用的較多的情況,推薦直接使用vuex進行狀態管理會比較方便。
補充:面試被問到同級組件傳遞參數,平時很少去用這個,沒答上來(尷尬),回來百度了下,原來就是通過一個中間橋接的方式進行傳遞(遭不住,之前看到過,沒引起重視)
其原理是先建立一個中間事件總線center.js,放在tools文件夾下,如下:
import Vue from 'vue' export default new Vue()
center.js中我們只創建了一個新的Vue實例,以后它就承擔起了組件之間通信的橋梁了,也就是中央事件總線
然后創建第一個子組件first.vue:
<template> <div class="first-vue-box"> <p>this is firstChild vue</p> <button @click="sendMsg">發送</button> </div> </template> <script> import bridge from '../tools/center' export default { data () { return {} }, methods: { sendMsg () { bridge.$emit('firstChildMsg', 'this is firstChild Msg') } } } </script> <style lang="scss" scoped> .first-vue-box { border: 1px solid blue; } </style>
這里先引入事件總線,通過事件總線點擊按鈕后將first.vue的信息通過事件firstChildMsg的形式發布出去了(我個人的理解是相當於通過事件總線,將first.vue的firstChildMsg這個事件暴露出去),用法跟子組件向父組件傳參的模式一樣
然后再創建第二個組件second.vue:
<template> <div class="second-child"> <h4>this is second child vue</h4> <p>從first.vue獲取同級組件傳遞過來的信息:{{message}}</p> </div> </template> <script> import bridge from '../tools/center' export default { data () { return { message: '默認值' } }, mounted () { let _this = this bridge.$on('firstChildMsg', function (msg) { _this.message = msg }) } } </script>
在second.vue中再引入事件總線,然后通過$on(functionName, callback)監聽first.vue暴露出來的firstChildMsg事件,通過回調函數獲取first.vue傳遞出來的值(我個人是這么理解的)
引入兩個子組件:
<template> <div class="detail-div"> <h3>首頁詳情</h3> <first-child></first-child> <second-child></second-child> </div> </template> <script> import firstChild from './first' import secondChild from './second' export default { data () { return {} }, components: { firstChild, secondChild }, mounted () { // console.log('詳情頁面...') } } </script>
第二個子組件通過中央事件總線bridge,監聽事件first.vue發布的事件firstChildMsg,獲取到子組件first.vue發送過來的信息,如下圖所示:
點擊發送按鈕后second.vue獲取到first.vue傳遞過來的值:
之前在項目中沒這樣用過同級組件之間的傳值,這次是個教訓,以后得注意一下每一個細節的地方。這里我看了參考文章,自己寫個示例來驗證的,最好是能自己驗證一下,記憶才比較深刻。