參考文章:
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傳遞過來的值:

之前在項目中沒這樣用過同級組件之間的傳值,這次是個教訓,以后得注意一下每一個細節的地方。這里我看了參考文章,自己寫個示例來驗證的,最好是能自己驗證一下,記憶才比較深刻。
