关于vue-cli $emit $on 中mounted调用的时候发现无法更改data中的值,或不主动执行$on
我的问题:
使用Vue脚手架的过程中,希望两个兄弟组件之间进行值的传递,于是经过查询可以使用vue-bus的方法来进行通信
Bus通信
在组件之外定义一个bus.js作为组件间通信的桥梁,适用于比较小型不需要vuex又需要兄弟组件通信的
1).bus.js中添加如下
import Vue from 'vue'
export default new Vue
2.)组件中调用bus.js通过自定义事件传递数据
import Bus from './bus.js'
export default {
methods: {
bus () {
Bus.$emit('msg', '我要传给兄弟组件们')
}
}
}
3).兄弟组件中监听事件接受数据
import Bus from './bus.js'
export default {
mounted() {
Bus.$on('msg', (e) => {
console.log(e)
})
}
}
使用过程中出现的问题
1.数据虽然传输过来了,在控制台可以进行输出。但是我发现却没法给data中的数据进行值的传递
data(){
return {
a:''
}
}
...
mounted(){
Bus.$on('message',data=>{
this.a = data
}
}
此时对于data中的数据的更改是无效的
那么是什么原因呢
我们简单的理解一下vue中的传值操作
对于vue bus的解释
- 首先我们知道vue中所有的传值操作都必须经过父子传值这一道过程,两个兄弟之间是没法传值的
- 我们现在使用的传值方法:我们需要新建一个vue组件,通过这个vue组件来进行传值
- 在这个过程中,一个组件充当emit的角色(也就是消息的发送方的角色),另一个组件充当on的角色(消息的订阅方)
- 但是on不仅仅充当订阅方,我们看到的
<template>
<div id="app">
<brother1 @data-msg="msg2($event)"></brother1>
<brother2 :msgbro2="msgbro2"></brother2>
</div>
</template>
<script>
import Brother1 from "./components/Brother1";
import Brother2 from "./components/Brother2";
- 这种为什么能执行呢
原因很简单:
我们需要首先注册这个‘bus’,然后才能使用
注册就是用$on来进行注册 - 我的测试过程:我想既然on是开启一个bus,那我先去on页面,然后回到emit页面,现在应该数据就能发送了,bus也创建了。于是我在emit操作页面之后又跳回on操作页面,但是数据还是无法操作更改与刷新。
- 那我们分开他们写的时候,为什么就收不到呢,我通过console发现,当我们从一个vue组件on操作之后,其vue的id与之后emit的vue的id相同,但是,当我返回on操做的页面的时候,发现vue被更新了(id被更新)。
我们找到了问题,on必须在emit之前执行,但是我们程序的逻辑又是先执行emit。
那么如何解决这个问题?
解决问题
<script>
import Bus from '../assets/js/bus'
export default {
props:{
withHeader:{
type:Boolean,
default:false
}
},
methods: {
haveSelect(){
this.drawer=true
this.middleSelections = this.selections
console.log('this is the before after close',this.middleSelections)
console.log('this is the before after close',this.selections)
},
handleClose(done) {
this.selections = this.middleSelections
console.log('this is after close',this.middleSelections)
done()
},
selectionLineChangeHandle(val){
console.log('this is val.id:',val)
this.selections = val
console.log('this is selections:',this.selections)
},
handleSizeChange(val) {
console.log(`每页 3 条`);
},
handleCurrentChange(val) {
console.log(`当前页: 3`);
},
handleClicks(indexs,row) {
console.log(row.id);
console.log(this.tableData[indexs].url);
const urlTwo1 = this.tableData[indexs].urlTwo;
const urlThree1 = this.tableData[indexs].urlThree;
const ID_CEEDI = this.tableData[indexs].ID_CEEDI;
this.$confirm('点击查看设备号为:<h3>'+ID_CEEDI+'</h3>的详细信息', '提示', {
dangerouslyUseHTMLString: true,
confirmButtonText: '查看详情',
cancelButtonText:'关闭',
}).then(()=>{
Bus.$emit('url1',urlTwo1)
console.log('urlTwo1:',urlTwo1)
Bus.$emit('url2',urlThree1)
Bus.$emit('title',ID_CEEDI)
console.log('urlThree1:',urlThree1)
this.$router.push('/look')
})
},
searchTable(){
const message = this.form1
const message2 =this.form2
const messageForm = new FormData();
messageForm.append('app', message);
messageForm.append('moudle', message2);
console.log(messageForm)
this.$axios.post('/api/search/',messageForm).then(message=>{
console.log('message send successful')
this.tableData=message.data
})
},
handleSelect(selection, row) {
if(selection.indexOf(row) !== -1) {
row.state = 1
} else {
row.state = 0
}
console.log('@',selection)
console.log('@',row.state)
}
},
data() {
return {
middleSelections:[],
drawer : false,
direction:'rtl',
selections:[],
internet:'http://baidu.com',
data1:12,
data2:13,
tableData:[],
form2:'',
form1:'',
currentPage: 1,
pageSize:10,
total:1,
pageCount:2
}
},
mounted() {
Bus.$on('url1',args=>{
Bus.sendUrl1 = args
})
Bus.$on('url2',args=>{
Bus.sendUrl2 = args
})
Bus.$on('title',args=>{
Bus.title = args
})
console.log(444)
this.$axios.get("/api/table",).then(response=>{
this.tableData = response.data
console.log(this.tableData)
this.data1 = response.data.length
const total = this.data1/this.pageSize
this.pageCount= Math.ceil(total)
console.log('this is total:',this.pageCount)
})
}
}
</script>
注意这里::
Bus.$on('url1',args=>{
Bus.sendUrl1 = args
})
Bus.$on('url2',args=>{
Bus.sendUrl2 = args
})
Bus.$on('title',args=>{
Bus.title = args
})
我将其要发送的内容作为一个属性,同时在emit之前就on操作了
那我只需要在需要的地方拿出这个属性就可以了
this.msg1 = Bus.title
this.u1 = Bus.sendUrl1
注意使用Bus的地方都需要引入Bus.js****