1. 父組件向子組件傳值
父組件通過 prop 給子組件下發(fā)數(shù)據(jù),子組件通過$emit觸發(fā)事件給父組件發(fā)送消息,即 prop 向下傳遞,事件向上傳遞。
- 新建父組件文件
<template>
<div>
父組件:
<input type="text" v-model="name">
<!--引入子組件-->
//這里傳的是一個變量值(可修改的,所以要使用v-bind屬性)
<son :inputName="name"></son>
</div>
</template>
<script>
// 引入子組件
import son from './son'
export default {
name: 'father',
data () {
return {
name: '',
}
},
components: { //接收組件
son
}
}
</script>
- 新建子組件文件
<template>
<div>
子組件:
<span>{{inputName}}</span> //接收父組件傳過來的值
</div>
</template>
<script>
export default {
name: 'son',
data () {
return {}
},
// 接受父組件的值
props: {
inputName: String, //聲明的類型
required: true
}
}
</script>

另一種(在封裝組件里傳值)父組件向子組件傳值
局部封裝


‘a’是字符串數(shù)組
2. 子組件向父組件傳值
vue是禁止子組件直接向父組件傳值的,所以只能通過$emit觸發(fā)事件來達到目的。
- 新建子組件文件
<template>
<div>
子組件:
<span>{{sonValue}}</span>
<!-- 定義一個子組件傳值的方法 -->
<button @click="sonClick">點擊觸發(fā)</button> //綁定一個點擊事件
</div>
</template>
<script>
export default {
name: 'son',
data () {
return {
sonValue: '我是子組件的數(shù)據(jù)'
}
},
methods: {
sonClick () {
// sonByValue是在父組件on監(jiān)聽的方法
// 第二個參數(shù)this.sonValue是需要傳給父組件的值,就是return中的值
this.$emit('sonByValue', this.sonValue)
}
}
}
</script>
- 新建父組件文件
<template>
<div>
父組件:
<span>{{name}}</span>
<!-- 引入子組件 定義一個on的方法監(jiān)聽子組件的狀態(tài)-->
//@sonByValue是接收子組件的事件名稱,需要和子組件保持一致
<son @sonByValue="outSon"></son> //outSon自定義名稱方法
</div>
</template>
<script>
import son from './son'
export default {
name: 'father',
data () {
return {
name: ''
}
},
methods: {
// sonValue就是子組件傳過來的值
outSon(sonValue) {
// 把子組件里傳過來的值賦值給this.name,當點擊觸發(fā)方法時,就把值傳過來了并顯示在頁面上了
this.name = sonValue
}
},
components: {
son
}
}
</script>

3.非父子組件傳值(兄弟組件傳值)
需要新建一個公共的公共實例文件bus.js,作為中間倉庫來傳值
- 1.在src目錄下新建一個bus.js文件
import Vue from 'vue'
export default new Vue()
- 2.新建組件A
<template>
<div id="emit">
A組件:
<span>{{elementValue}}</span>
<button @click="elementByValue">點擊觸發(fā)</button>
</div>
</template>
<script>
// 引入公共的bug,來做為中間傳達的工具
import Bus from './bus.js'
export default {
name: 'componentA',
data () {
return {
elementValue: '我要給兄弟組件傳值啦'
}
},
methods: {
elementByValue () {
// 用$emit來觸發(fā)
Bus.$emit('val', this.elementValue)
// console.log(this.elementValue)
}
}
}
</script>
- 新建組件B
<template>
<div>
B組件:
<!--<button @click="getBata">點擊觸發(fā)</button>-->
<span>{{name}}</span>
</div>
</template>
<script>
// 引入公共的bug,來做為中間傳達的工具
import Bus from './bus.js'
export default {
name: 'componentB',
data () {
return {
name: ''
}
},
mounted () {
var vm = this
// 用$on來接收
Bus.$on('val', (data) => {
console.log(data)
vm.name = data
})
}
// methods: {
// getBata () {
// this.name++
// }
// }
}
</script>
4. 袓孫隔代傳值
當一個模板里嵌套了很多層時,如:組先、兒子、孫子、曾孫等,你要從最里層曾孫組件里去訪問最外層袓先的數(shù)據(jù),如果你要一層一層的去傳值的話,那這會非常麻煩,并且數(shù)據(jù)容易出錯。這時就需要用到provide 和inject方法,它們倆需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在起上下游關系成立的時間里始終生效。
不推薦直接用于應用程序代碼中。一般使用的場景是自定義組件庫的時候,底層組件之間需要通信的時候使用。
provide: 一個對象或返回一個對象的函數(shù)
inject:一個字符串數(shù)組,或 一個對象,對象的 key 是本地的綁定名
- 新建袓先級組件
<template>
<div>
<span>祖先級組件:parent</span>
<input type="text" v-model="toGdata.name">
<div>
<dadC></dadC> // 定義父組件
</div>
</div>
</template>
<script>
// 引入父組件
import dadC from './dadC'
export default {
name: 'parent',
data () {
return {
toGdata: {name: '李三'} // 存放數(shù)據(jù)
}
},
// import引入的組件需要注入到對象中才能使用
components: {
dadC
},
// 注入數(shù)據(jù)
provide () {
return {
toGdata: this.toGdata
}
}
}
</script>
- 新建兒子級組件
<template>
<div>
<span>兒子級組件C:dadC</span>
<div>
<grandSon></grandSon> // 定義孫子組件
</div>
</div>
</template>
<script>
// 引入孫子組件
import grandSon from './grandSon'
export default {
name: 'dadC',
data () {
return {}
},
// import引入的組件需要注入到對象中才能使用
components: {
grandSon
}
}
</script>
- 新建孫子級組件
<template>
<div>
<span>孫子級組件G:grandSon</span>
<div>
接受來自袓父級組件parent的數(shù)據(jù)【toGdata】:{{toGdata}}
<input type="text" v-model="fromParentData.name">
</div>
</div>
</template>
<script>
export default {
name: 'grandSon',
data () {
return {
fromParentData: this.toGdata
}
},
// 接受袓先級傳過來的數(shù)據(jù)
inject: ['toGdata'],
components: {}
}
</script>
注意:這里不論子組件嵌套有多深, 只要調用了 inject 那么就可以注入 provide 中的數(shù)據(jù),而不局限于只能從當前父組件的props屬性中回去數(shù)據(jù)

總結:
在簡單的功能模塊,可以通過傳遞對象實現(xiàn)跨級組件通信,復雜的功能模塊不建議使用,因為傳遞的數(shù)據(jù),如果其他的兒子級組件,其他兒子級組件的孫子級組件也在使用的話,會造成數(shù)據(jù)的混亂,甚至無法理解數(shù)據(jù)是在哪里變化的,排查故障艱難。
跨級組件通信可以定義一個中央事件總線(eventBus),但是更復雜的系統(tǒng),還是建議使用vuex。
參考以下資料:
https://blog.csdn.net/weihaifeng163/article/details/88338822
https://www.cnblogs.com/pangchunlei/p/12112318.html