原始碼地址
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