主要是整理給自己用的一些面試常用題,這裏記錄一下vue組件間通信幾種方式。
父組件傳值到子組件(父傳子)
先定義一個子組件,這裏我在component文件夾裏定義一個child.vue
子組件
<template>
<div class="about">
<h1>這裏是子組件的變量接受的變量{{msg}}</h1>
</div>
</template>
<script>
export default {
props: {
msg: Number
}
}
</script>
父組件
<template>
<div class="home">
<div>我是父組件的變量{{num}}</div>
<button @click="add">父組件變量+1</button>
<Child :msg="num" @getData="getData"></Child>
</template>
<script>
import Child from '@/components/child.vue'
export default {
data() {
return {
num: 18
}
},
components: {
Child
},
methods: {
add() {
this.num++
}
}
}
</script>
實現效果
父組件傳子組件還是比較容易理解的,實現方式就是通過props屬性,子組件通過props屬性接收從父組件傳過來的數據,而父組件傳值給子組件的時候使用 v-bind 將子組件中props
預留的變量名綁定到父組件data裏面的數據就好了,記得你在子組件定義的數據類型
子組件傳值到父組件(子傳父)
子組件代碼
<template>
<div class="about">
<div>
<input type="text" v-model="inputMsg">
</div>
<button @click="setData">把輸入的文字傳遞給父組件</button>
</div>
</template>
<script>
export default {
data() {
return {
inputMsg: ''
}
},
methods: {
setData() {
this.$emit("setData", this.inputMsg);
}
}
}
</script>
父組件代碼
<template>
<div class="home">
<div class="red">父組件默認:{{msg}}</div>
<Child @setData="getData"></Child>
</template>
<script>
import Child from '@/components/child.vue'
export default {
data() {
return {
msg: '父組件默認數據'
}
},
components: {
Child
},
methods: {
getData(data) {
this.msg = data;
}
}
}
</script>
子組件傳遞數據到父組件,子組件通過this.$emit
自定義事件向父組件傳遞信息,父組件監聽子組件的事件來接收
非父子組件傳值
方法一:
新建一個bus.js文件, 在這個文件裏實例化一下vue;然後在組件A和組件B中分別引入這個bus.js文件,將事件監聽和事件觸發都掛到bus.js這個實例上,這樣就可以實現全局的監聽與觸發了。
bus.js文件
//bus.js
import Vue from 'vue'
export default new Vue()
組件A
<template>
<div>
A組件:
<button @click="AValueChange">傳值給B組件</button>
<span>{{AValue}}</span>
</div>
</template>
<script>
// 引入公共的bug,來做爲中間傳達的工具
import Bus from './bus.js'
export default {
data () {
return {
AValue: 4
}
},
mounted () {
var that = this
// 用$on事件來接收參數
// Bus.$on("事件名稱",事件處理函數)寫在mounted鉤子函數裏面,事件處理函數裏面就寫當這個觸發事件的回調函數裏面,應該乾的事。
Bus.$on('val', (data) => {
that.AValue = data
})
},
methods: {
// 觸發事件
AValueChange() {
Bus.$emit('val', this.AValue)
}
}
}
</script>
組件B
<template>
<div>
B組件:
<button @click="getData">自身+1</button>
<button @click="BValueChange">傳值給A組件</button>
<span>{{BNum}}</span>
</div>
</template>
<script>
import Bus from './bus.js'
export default {
data () {
return {
BNum: 0
}
},
mounted () {
var that = this
// 用$on事件來接收參數
Bus.$on('val', (data) => {
that.BNum = data
})
},
methods: {
getData() {
this.BNum++
},
BValueChange() {
Bus.$emit('val', this.BNum)
}
}
}
</script>
方法二:
在main.js,也就是入口文件中,在vue的原型上添加一個bus對象,原理跟方法一類似,只不過更加簡單
//在main.js中
Vue.prototype.bus = new Vue()
// 傳遞組件裏的觸發事件
this.bus.$emit('updata', this.AValue)
// 接收組件裏面的監聽事件
this.bus.$on('updata', (data) => {
console.log(data) //data就是觸發updata事件帶過來的數據
})
這裏就不上詳細代碼了,因爲在方法一里面改下即可。
A組件裏面的觸發事件
methods: {
// 傳遞組件裏的觸發事件
AValueChange() {
this.bus.$emit('updata', this.AValue)
},
}
B組件裏面的mounted函數裏面的監聽事件
mounted() {
var that = this
// 接收組件裏面的監聽事件
this.bus.$on('updata', (data) => {
console.log(data) //data就是觸發updata事件帶過來的數據
that.BNum = data
})
}
實現效果:
這裏就是改了下,原理還是類似
其實這些可以直接Vuex狀態管理工具來實現,看實際應用場景。
本來是這些都在一個demo裏面的,便於理解寫的時候把這些拆分出來了。複製代碼的時候可能會出現些問題,如果各位發現問題了,可以指出,我加以更正,感謝。
個人水平有限,有問題歡迎大家留言指導,僅供學習和參考。
學海無涯!努力二字,共勉!