1. props和$emit
最簡單常用的方式
目錄結(jié)構(gòu)
// index.vue
<template>
<div>
<h2>父組件中</h2>
輸入向子組件傳值<input type="text" v-model="foo">
<child-com :foo="foo" @out="getMsg"></child-com>
<h2>子組件信息</h2>{{childMsg}}
</div>
</template>
<script>
const childCom = () => import('./components/child')
export default {
components: {
childCom
},
data() {
return {
foo: '',
childMsg: ''
}
},
methods: {
getMsg(v) {
this.childMsg = v
}
}
}
</script>
// child.vue
<template>
<div>
<h2>子組件中</h2> {{foo}}
<br/>
<button @click="sendMsg">點(diǎn)擊向父組件傳值</button>
</div>
</template>
<script>
export default {
props: ['foo'],
methods: {
sendMsg() {
this.$emit('out', 'msg')
}
}
}
</script>
效果圖
2. vuex
3. 依賴注入
使用場景
當(dāng)組件嵌套過多页屠,而且所有組件都需要使用根組件(包括但不限于)的某一些內(nèi)容時(shí)(數(shù)據(jù)或方法)消约,使用依賴注入會(huì)比普通的傳值更加方便
使用
// 依賴注入一個(gè)getMap方法
provide: function () {
return {
getMap: this.getMap
}
}
然后在任何子組件里婶肩,我們都可以使用 inject 選項(xiàng)來接收指定的我們想要添加在這個(gè)實(shí)例上的屬性:
inject: ['getMap']
相比于$parent叉谜,選擇依賴注入的好處
使用依賴注入可以讓我們免于暴露整個(gè)根組件信息孕豹,具體有兩點(diǎn)
- 祖先組件不需要知道哪些后代組件使用它提供的屬性
- 后代組件不需要知道被注入的屬性來自哪里
4. 使用$emit/$on捧挺,模擬發(fā)布訂閱模式
這里需要利用一個(gè)空的vue對(duì)象當(dāng)做事件中心倚搬,可以實(shí)現(xiàn)組件間的通訊
目錄結(jié)構(gòu)
// event.js創(chuàng)建一個(gè)新的vue實(shí)例
import Vue from 'vue'
const Event = new Vue()
export default Event
// index.vue
<template>
<div>
父組件 {{msg}}
<child-com01></child-com01>
<child-com02></child-com02>
</div>
</template>
<script>
import Event from './components/event'
const childCom01 = () => import('./components/child01')
const childCom02 = () => import('./components/child02')
export default {
components: {
childCom01,
childCom02
},
data() {
return {
msg: ''
}
},
mounted() { // 因?yàn)椴恢朗裁磿r(shí)候會(huì)觸發(fā)方法,所以一般會(huì)選擇在created或者是mounted的時(shí)候綁定
Event.$on('getMsg', v => this.msg = v) //箭頭函數(shù)內(nèi)部不會(huì)產(chǎn)生新的this随夸,這邊如果不用=>,this指代Event
}
}
</script>
// child01.vue
<template>
<div>
子組件01 {{msg}}
</div>
</template>
<script>
import Event from './event'
export default {
mounted() {
Event.$on('getMsg', v => this.msg = v)
},
data() {
return {
msg: ''
}
}
}
</script>
// child02.vue
<template>
<div>
<h2>子組件02</h2>
<button @click="sendMsg">to 父組件和兄弟組件</button>
</div>
</template>
<script>
import Event from './event'
export default {
methods: {
sendMsg() {
Event.$emit('getMsg', 'child02的數(shù)據(jù)')
}
}
}
</script>
注意: 在使用$on綁定事件之后九默,需要主動(dòng)銷毀事件
例如
beforeDestroy () {
Event.$off('getMsg')
}
5. 使用$attrs/$listeners
在父組件通過v-bind綁定,但是在子組件中未被props聲明的屬性可以通過$attrs獲取到宾毒。
$listeners包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器
// index.vue
<template>
<div>
父組件
<child-com01 :msg1="msg1" :msg2="msg2" :msg3="msg3" :msg4="msg4" @indexfuc="indexfuc" @indexfuc2="indexfuc2" @indexfuc3="indexfuc3"></child-com01>
</div>
</template>
<script>
const childCom01 = () => import('./components/child01')
export default {
components: {
childCom01
},
data() {
return {
msg1: 'm1',
msg2: 'm2',
msg3: 'm3',
msg4: 'm4'
}
},
methods: {
indexfuc() {
console.log('根組件方法1')
},
indexfuc2() {
console.log('根組件方法2')
},
indexfuc3() {
console.log('根組件方法3')
}
}
}
</script>
// child01.vue
<template>
<div>
子組件01收到的數(shù)據(jù) {{$attrs}}
props接收的數(shù)據(jù){{msg1 + ' ' + msg2}}
<child-com02 v-bind="$attrs" v-on="$listeners"></child-com02>
</div>
</template>
<script>
const childCom02 = () => import('./child02')
export default {
components: {
childCom02
},
props: ['msg1', 'msg2'],
mounted() {
console.log(this.$attrs, '---child1中')
console.log(this.$listeners, '---child1中')
this.$listeners.indexfuc2()
}
}
</script>
// child02.vue
<template>
<div>
子組件02收到的數(shù)據(jù) {{$attrs}}
</div>
</template>
<script>
export default {
mounted() {
console.log(this.$listeners, '---child02中')
this.$listeners.indexfuc3()
}
}
</script>
這里的child02是child01的子組件驼修,三個(gè)組件是嵌套關(guān)系,child02可以拿到全部的屬性和方法
6. $refs和$parent诈铛、$children
使用ref給組件賦值一個(gè)ID
<base-input ref="usernameInput"></base-input>
之后使用this.$refs.usernameInput來訪問這個(gè)組件
this.$refs.usernameInput
或者在組件中使用來獲取數(shù)據(jù)
this.$parent
this.$children
但是這幾種無法實(shí)現(xiàn)跨級(jí)或兄弟組件之間傳遞消息乙各,在使用過程中,應(yīng)該酌情使用以上幾種方法