源碼地址
Vue2父子傳參:props
首先在父組件中引入子組件,然后以屬性的方式將數據傳遞給子組件
父組件:
<template>
<div class="home">
<!-- 在子組件中使用 :變量名=value 的方式向子組件傳遞數據,子組件通過 props 接收-->
<HelloWorld :msg="fatchData" ref="childEl"/>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
data () {
return {
fatchData: '我是父組件通過props傳遞給子組件的文字'
}
}
}
</script>
然后在子組件中使用props接收,props里定義的名字要和父組件定義的一致
子組件:
<template>
<div>
<span>{{ msg }}</span>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
// 子組件通過使用 props 接收父組件傳遞過來的數據
props: {
msg: String
}
}
</script>
Vue2父子傳參之父傳子:$refs
在父組件中給子組件的標簽上添加 ref 等於一個變量,然后通過使用 $refs 可以獲取子組件的實例,以及調用子組件的方法和傳遞參數
父組件:
<template>
<div class="home">
<!-- 在子組件中使用 :變量名=value 的方式向子組件傳遞數據,子組件通過 props 接收-->
<HelloWorld :msg="fatchData" ref="childEl"/>
<div>
父組件
</div>
<div>
<button @click="changeChildMsg">父組件按鈕</button>
</div>
</div>
</template>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
data () {
return {
fatchData: '我是父組件通過props傳遞給子組件的文字'
}
},
methods: {
// 點擊父組件的按鈕修改子組件中顯示的文字
changeChildMsg () {
this.fatchData = '通過按鈕修改了子組件中顯示的問題'
// 父組件調用子組件的方法並傳遞參數
this.$refs.childEl.showText('我來自父組件')
}
}
}
</script>
然后在子組件中定義相同的方法名,在父組件使用 $refs
調用后觸發在子組件中定義的同名方法
子組件:
<template>
<div class="hello">
<b>子組件</b>
<div>
<span>{{ msg }}</span>
</div>
<div>
<button>子組件按鈕</button>
</div>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
// 子組件通過使用 props 接收父組件傳遞過來的數據
props: {
msg: String
},
methods: {
// 這個方法由父組件通過 this.$refs.childEl.showText('我來自父組件') 調用觸發
showText (text) {
alert(text)
}
}
}
</script>
Vue2父子傳參之子傳父:$emit
在子組件中我們也可以調用父組件的方法向父組件傳遞參數,通過$emit
來實現
子組件:
<button @click="childClick">子組件按鈕</button>
<script>
export default {
name: 'HelloWorld',
methods: {
// 子組件通過 $emit 調用父組件中的方法
childClick () {
this.$emit('setValueName', '我是通過子組件傳遞過來的')
}
}
}
</script>
然后在父組件中定義並綁定子組件傳遞的 setValueName
事件,事件名稱要和子組件定義的名稱一樣
父組件:
<HelloWorld @setValueName="setValueName" />
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
methods: {
// 該方法是由子組件觸發的
setValueName (data) {
alert(data) //= > 我是通過子組件傳遞過來的
}
}
}
</script>
Vue2父子傳參:parent/children
- 父組件通過
$children
獲取子組件的實例數組 - 子組件通過
$parent
獲取的父組件實例
父組件中可以存在多個子組件,所以this.$children
獲取到的是子組件的數組
父組件:
<HelloWorld />
<button @click="getSon">children/parent</button>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
data () {
return {
parentTitle: '我是父組件'
}
},
methods: {
// 子組件調用這個方法
parentHandle () {
console.log('我是父組件的方法')
},
// 通過 this.$children 獲取子組件實例
getSon () {
console.log(this.$children)
console.log(this.$children[0].sonTitle) //= > 我是子組件
this.$children[0].sonHandle() //= > 我是子組件的方法
}
}
}
</script>
子組件:
<button @click="getParent">獲取父組件的方法和值</button>
<script>
export default {
name: 'HelloWorld',
data () {
return {
sonTitle: '我是子組件'
}
},
methods: {
// 父組件通過 this.$children 來調用
sonHandle () {
console.log('我是子組件的方法')
},
// 調用父組件的方法和獲取父組件的值
getParent () {
console.log(this.$parent)
console.log(this.$parent.parentTitle) //= > 我是父組件
this.$parent.parentHandle() //= > 我是父組件的方法
}
}
}
</script>
Vue2兄弟傳參:bus.js
首先新建 bus.js
文件,初始化如下代碼:
import Vue from 'vue'
export default new Vue()
然后在需要通信的組件中都引入該 bus
文件,其中一個文件用來發送,一個文件監聽接收。派發事件使用 bus.$emit
。
下面組件派發了一個叫setYoungerBrotherData
的事件
<template>
<div>
哥哥組件:<button @click="setYoungerBrotherData">給弟弟傳參</button>
</div>
</template>
<script>
import bus from '../assets/bus'
export default {
methods: {
setYoungerBrotherData () {
// 通過 bus.$emit 派發一個事件
bus.$emit('setYoungerBrotherData', '給弟弟傳參')
}
}
}
</script>
在另一個頁面中使用 bus.$on('setYoungerBrotherData',()=>{})
監聽
<template>
<div>弟弟組件:{{ msg }}</div>
</template>
<script>
import bus from '../assets/bus'
export default {
data () {
return {
msg: ''
}
},
mounted () {
// 通過 bus.$on 監聽兄弟組件派發的方法
bus.$on('setYoungerBrotherData', (res) => {
this.msg = res
})
}
}
</script>
Vue2跨級傳參:provide/inject
provide
和inject
是vue
生命周期上的兩個函數,這對選項需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,並在其上下游關系成立的時間里始終生效。
提示:provide
和 inject
綁定並不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監聽的對象,那么其對象的 property 還是可響應的。
祖先組件:
<script>
export default {
name: 'Home',
// 通過 provide 提供的數據可以在該組件層次之下的任何組件使用
provide () {
return {
// 可以傳遞普通字符串
provideName: '祖先',
// 也可以傳遞一個異步方法
getOrderInfo: () => {
return this.getOrderList()
}
}
},
methods: {
// 傳遞一個異步方法獲取數據,用來模擬接口請求
getOrderList () {
return new Promise((resolve, reject) => {
// 倒計時兩秒模擬請求延遲
setTimeout(() => {
resolve({
code: 'WX15485613548',
name: '農夫安裝工單'
})
}, 2000)
})
}
}
}
</script>
孫子組件:
<template>
<div>
{{ bar }}
<button @click="getOrder">異步獲取數據</button>
</div>
</template>
<script>
export default {
// 使用 inject 接收祖先生成的數據
inject: ['provideName', 'getOrderInfo'],
data () {
return {
// inject 接收的數據可以作為數據的入口
bar: this.provideName
}
},
mounted () {
console.log(this.provideName) //= >祖先
},
methods: {
getOrder () {
// 調用的是父組件的方法,延遲兩秒獲取數據
this.getOrderInfo().then(res => {
console.log(res) //= > {code: "WX15485613548", name: "農夫安裝工單"}
})
}
}
}
</script>
使用 provide/inject
的好處是父組件不需要知道是哪個自組件使用了我的數據,子組件也不需要關心數據從何而來
總結
- 父子通信:父向子傳遞數據通過
props
,子向父傳遞數據通過$emit
事件,父鏈子鏈使用$parent/$children
,直接訪問子組件實例使用$refs
- 兄弟通信:
bus,Vuex
- 跨級通信:
bus,Vuex,provide/inject