一仙粱、組件間通信傳值的各種方式與場(chǎng)景
1碳默、父組件向子組件(跨級(jí))傳值
1.1 父組件通過(guò)props給子組件傳值
props也可以傳函數(shù)
// 父組件vue文件
<template>
<div class="home">
<!--父組件傳msg屬性給子組件傳值-->
<child :msg="msg"></child>
</div>
</template>
<script>
import Child from '@/components/Child'
export default {
name: 'Father',
components: {
Child
},
data () {
return {
msg: '父組件傳給子組件的值'
}
},
methods: {}
}
</script>
// 子組件
<template>
<div>{{ msg }}</div>
</template>
<script>
export default {
name: 'Child',
// 子組件通過(guò)props接收父組件的傳值
props: ['msg']
}
</script>
<style scoped>
</style>
1.2 父組件通過(guò)$ref給子組件傳值
ref 用于給元素或子組件注冊(cè)引用信息柳弄,引用信息將會(huì)注冊(cè)在父組件的 refs 對(duì)象上疯潭,父組件通過(guò)refs對(duì)象上,父組件通過(guò)ref 獲取到在子組件里定義的屬性和方法祝旷,通過(guò)調(diào)用方法給子組件傳遞數(shù)據(jù)
// 父組件
<template>
<div class="home">
<!--父組件傳msg屬性給子組件傳值-->
<child ref="child"></child>
</div>
</template>
<script>
import Child from '@/components/Child'
export default {
name: 'Father',
components: {
Child
},
data () {
return {
msg: '父組件傳給子組件的值'
}
},
mounted () {
// 父組件通過(guò)ref屬性調(diào)用子組件的方法
this.$refs.child.getMsg(this.msg)
},
methods: {}
}
</script>
// 子組件
<template>
<div>{{ msg }}</div>
</template>
<script>
export default {
name: 'Child',
data () {
return {
msg: ''
}
},
methods: {
// 子組件獲取父組件值的方法
getMsg (val) {
this.msg = val
}
}
}
</script>
<style scoped>
</style>
1.3 父組件通過(guò)$children給子組件傳值
children為當(dāng)前組件的直接子組件履澳,是一個(gè)無(wú)序的數(shù)組,父組件通過(guò) children 訪問(wèn)子組件并傳遞數(shù)據(jù)怀跛,$ children
并不保證順序距贷,也不是響應(yīng)式的,如果能清楚的知道子組件的順序吻谋,可以使用下標(biāo)來(lái)操作對(duì)應(yīng)的子組件
// 父組件
<template>
<div class="home">
<!--父組件傳msg屬性給子組件傳值-->
<child ref="child"></child>
</div>
</template>
<script>
import Child from '@/components/Child'
export default {
name: 'Father',
components: {
Child
},
data () {
return {
msg: '父組件傳給子組件的值'
}
},
mounted () {
// 父組件通過(guò)$children[0]訪問(wèn)對(duì)應(yīng)子組件
this.$children[0].msg = this.msg
},
methods: {}
}
</script>
// 子組件
<template>
<div>{{ msg }}</div>
</template>
<script>
export default {
name: 'Child',
data () {
return {
msg: ''
}
}
}
</script>
<style scoped>
</style>
1.4 父組件通過(guò)provide/inject給子孫組件傳值
provide/inject 組合以允許一個(gè)祖先組件向其所有子孫后代組件注入一個(gè)依賴(屬性和方法)忠蝗,不論組件層次有多深,并在其上下游關(guān)系成立的時(shí)間里始終生效漓拾,從而實(shí)現(xiàn)跨級(jí)父子組件通信阁最,主要在開(kāi)發(fā)高階插件/組件庫(kù)時(shí)使用
// 父組件
<template>
<div class="home">
<child></child>
</div>
</template>
<script>
import Child from '@/components/Child'
export default {
name: 'Father',
components: {
Child
},
data () {
return {}
},
// 父組件通過(guò)provide方法向子孫組件提供值
provide () {
return {
msg: '父組件傳給子組件的值'
}
}
}
</script>
// 子組件
<template>
<div>{{ msg }}</div>
</template>
<script>
export default {
name: 'Child',
// 子孫組件通過(guò)inject注入父組件提供的值
inject: ['msg'],
data () {
return {
}
}
}
</script>
<style scoped>
</style>
總結(jié):props
和$ref
和 $children
和provide/inject
的主要區(qū)別:
- props 側(cè)重于數(shù)據(jù)的傳遞,并不能獲取子組件里的屬性和方法骇两,適用于自定義內(nèi)容的使用場(chǎng)景
-
$ref
側(cè)重于獲取子組件里的屬性和方法速种,并不是太適合傳遞數(shù)據(jù),并且 ref 常用于獲取dom元素低千,起到選擇器的作用 -
$children
側(cè)重于獲取所有的直接子組件配阵,得到的是一個(gè)無(wú)序的數(shù)組,并不太適合向多個(gè)子組件傳遞數(shù)據(jù) - provide/inject 側(cè)重于在開(kāi)發(fā)高階插件/組件庫(kù)時(shí)使用,并不推薦用于普通應(yīng)用程序代碼中棋傍。
1.5 非prop的$attrs?inheritAttrs? 提供封裝組件的可擴(kuò)展性
要求第1個(gè)input輸入文字救拉,第2個(gè)input輸入密碼
-
設(shè)置 inheritAttrs: false
-
v-bind="$attrs"
-
總結(jié)
// 子組件
<template>
<div class="input-con">
<input v-bind="$attrs" :value="value" @input="$emit('input')">
$attrs接收非props傳遞過(guò)來(lái)的屬性:{{$attrs}},所有不包含屬性 ’value‘
</div>
</template>
<script>
export default {
name: 'Child',
props: ['value'],
inheritAttrs: false // 關(guān)閉父組件傳過(guò)來(lái)的屬性添加到子組件的根元素
}
</script>
<style scoped>
</style>
// 父組件
<template>
<div class="home">
<!--要求第1個(gè)input輸入文字-->
<!-- 第2個(gè)input輸入密碼-->
<child v-model="msg" type="text"></child>
<child v-model="msg" type="password"></child>
</div>
</template>
<script>
import Child from '@/components/Child'
export default {
name: 'Father',
components: {
Child
},
data () {
return {
msg: '你好瘫拣,孩子'
}
}
}
</script>
1.6 $listeners
包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽(tīng)器近上。它可以通過(guò) v-on="$listeners" 傳入內(nèi)部組件——在創(chuàng)建更高層次的組件時(shí)非常有用。
2拂铡、子組件向父組件(跨級(jí))傳值 $emit(自定義事件名[,...param])
2.1 子組件通過(guò)觸發(fā)$emit事件給父組件傳值
$emit
的第一個(gè)參數(shù)為自定義的事件壹无,第二個(gè)參數(shù)為要傳遞給父組件的值,父組件在子組件標(biāo)簽上綁定自定義事件來(lái)接收子組件傳遞的數(shù)據(jù)
// 子組件
<template>
<div>
<button @click="sendMsg"></button>
</div>
</template>
<script>
export default {
name: 'Child',
data () {
return {
msg: '子組件傳給父組件的值'
}
},
methods: {
sendMsg () {
this.$emit('getMsg', this.msg)
}
}
}
</script>
<style scoped>
</style>
// 父組件
<template>
<div class="home">
<child @getMsg="getData"></child>
<p>{{msg}}</p>
</div>
</template>
<script>
import Child from '@/components/Child'
export default {
name: 'Father',
components: {
Child
},
data () {
return {
msg: ''
}
},
methods: {
getData (data) {
this.msg = data
}
}
}
</script>
2.2 子組件通過(guò)$parent給父組件傳值
$parent
可以用來(lái)從一個(gè)子組件訪問(wèn)父組件并傳遞數(shù)據(jù)
// 子組件
<template>
<div>
<button @click="sendMsg"></button>
</div>
</template>
<script>
export default {
name: 'Child',
data () {
return {
msg: '子組件傳給父組件的值'
}
},
methods: {
// 子組件通過(guò)$parent訪問(wèn)父組件
sendMsg () {
this.$parent.msg = this.msg
}
}
}
</script>
// 父組件
<template>
<div class="home">
<child></child>
<p>{{msg}}</p>
</div>
</template>
<script>
import Child from '@/components/Child'
export default {
name: 'Father',
components: {
Child
},
data () {
return {
msg: ''
}
}
}
</script>
3感帅、兄弟組件間通信傳值 vm.$emit
和vm.$on
兄弟之間傳值通過(guò)eventBus斗锭。
eventBus 就是一個(gè)vue實(shí)例來(lái)作為全局的事件總線,兄弟組件之間通過(guò) eventBus. on 和 eventBus.on和eventBus.emit 注冊(cè)觸發(fā)事件來(lái)傳遞數(shù)據(jù)
// 新建一個(gè)vue實(shí)例 eventBus.js
import Vue from 'vue'
export default new Vue()
// 父組件
<template>
<div class="home">
<child></child>
<child-two></child-two>
</div>
</template>
<script>
import Child from '@/components/Child'
import ChildTwo from '@/components/ChildTwo'
export default {
name: 'Father',
components: {
Child,
ChildTwo
},
data () {
return {
msg: ''
}
}
}
</script>
// 子組件A
<template>
<div>
<button @click="sendMsg">子組件A傳值給子組件B</button>
</div>
</template>
<script>
import eventBut from '@/utils/eventBut'
export default {
name: 'Child',
data () {
return {
msg: '子組件A傳給子組件B的值'
}
},
methods: {
sendMsg () {
// 子組件A通過(guò)eventBus.$emit觸發(fā)自定義事件給子組件B傳值
eventBut.$emit('getMsg', this.msg)
}
}
}
</script>
<style scoped>
</style>
// 子組件B
<template>
<div>
{{ msg }}
</div>
</template>
<script>
import eventBut from '@/utils/eventBut'
export default {
name: 'ChildTwo',
data () {
return {
msg: ''
}
},
created () {
this.getData()
},
methods: {
getData () {
eventBut.$on('getMsg', (data) => {
this.msg = data
})
}
}
}
</script>
<style scoped>
</style>