方法一:通過(guò)bus中轉(zhuǎn)
//1.新建bus.js
import Vue from 'vue'
export default new Vue
//2.在需要傳值和接受值的vue文件中,各自引入bus.js
import bus from '../util/bus'
//3.定義傳值的方法,使用bus.$emit('methodName',data), methodName是自定義的方法名
<button @click="trans()">傳值</button>
methods: {
trans(){
bus.$emit('test',this.helloData)
}
},
//4.在要接收值的組件里,使用bus.on('methodName',val =>{ }) ,val 就是傳過(guò)來(lái)的值
mounted(){
bus.$on('test',val=>{
console.log(val);
this.cdata = val
})
}
如果要傳多個(gè)值:
bus.$emit('test',data1,data2,data3……)
//同樣接收時(shí)候,需要接收多個(gè)值
bus.$on(test,(val,val2,val3……)=>{
console.log(val,val2,val3)
})
如果需要不觸發(fā)事件,就把值傳遞給兄弟組件,那么必須通過(guò)異步的方法傳遞,例如axios或者setTimeout
// 不通過(guò)點(diǎn)擊事件,把數(shù)據(jù)傳遞給兄弟組件,一定要setTimeout,或者axios請(qǐng)求
setTimeout(() => {
bus.$emit('test',data)
}, 2000);
@完整例子:
import Vue from 'vue'
export default new Vue
<template>
<div id="app">
<HelloWorld />
<child></child>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld";
import Child from "./components/Child";
export default {
name: "App",
components: {
HelloWorld,
Child,
},
};
</script>
import Vue from 'vue'
export default new Vue
<template>
<div>
<button @click="trans()">傳值</button>
</div>
</template>
<script>
import bus from "../util/bus";
export default {
name: "HelloWorld",
data() {
return {
helloData: "hello",
};
},
methods: {
trans() {
bus.$emit("test", this.helloData);
},
},
};
</script>
<template>
<div>{{cdata}}</div>
</template>
<script>
import bus from "../util/bus";
export default {
name: "Child",
data() {
return {
cdata: "子數(shù)據(jù)",
};
},
mounted() {
bus.$on("test", (val) => {
console.log(val);
this.cdata = val;
});
},
};
</script>
方法二:通過(guò)vue的原型上定義一個(gè)bus,其實(shí)和 方法一類似,實(shí)現(xiàn)起來(lái)有些區(qū)別
還有一種比較好的方式,也是我比較推薦的
App.vue或者main.js中定義
Vue.prototype.eventBus = new Vue();
組件A
this.eventBus.$emit('eventName', params)
組件B
this.eventBus.$on('eventName', params)
方法三:直接通過(guò)$root傳值
組件A
this.$root.$emit('eventName', params)
組件B
this.$root.$on('eventName', params)
注意:事件名必須保持統(tǒng)一
寫在最后:bus通信的原理分析
class Bus {
constructor() {
this.callbacks = {}
}
$on(name, fn) {
this.callbacks[name] = this.callbacks[name] || []
this.callbacks[name].push(fn)
}
$emit(name, args) {
if (this.callbacks[name]) {
this.callbacks[name].forEach(cb => cb(args))
}
}
}
// main.js
Vue.prototype.$bus = new Bus()
// child1
this.$bus.$on('foo', handle)
// child2
this.$bus.$emit('foo')