vue中,监听路由的变化 & 兄弟组件传值过程(创建bus中间件)——vue中 e m i t 触 发 的 事 件 , emit触发的事件, emit触发的事件,on 第一次监听不到数据,利用eventBus解决,并进行页面动态响应
1、watch监听路由不生效,没反应
解决方案:
watch: {
'$route': {
immediate: true, // 一旦监听到路由的变化立即执行
handler(to, from) {
console.log("监听路由:" + JSON.stringify(to.name));
},
},
}
2、利用eventBus接收数据
场景——组件与页面之间想通过$ emit,来触发一个事件,传递数据,可是当在目标页面利用$on监听事件,获取数据时,发现第一次并不能监听到事件,而返回再次点击就可以监听到数据。
原因——$ emit 先于$ on 执行了,Vue并没有储存监听事件,所以无法监听到数据。
解决方案——如果不想用vuex来解决,利用eventBus来解决,而且组件不直接通过$on来存储数据,而是利用bus实例来存储数据,然后组件只负责来获取数据。
2.1、兄弟传值过程
1、在utils目录下(bus.js放置位置自己决定),新建bus.js 文件,内容如下:
// 创建vue实例,作为中间件进行数据传递
import Vue from 'vue'
export const bus = new Vue({
data () {
return {
// 定义数据
data: {}
}
},
created () {
// 绑定监听
this.$on('toDetailPage', (value)=>{
this.data = value.data
})
}
})
2.1、在发送数据的A组件里先引用
import {bus} from "../../utils/bus.js" // A组件
2.2、在跳转方法中,触发$ emit事件
// A组件
skip_to_detail: function (e) {
//跳转到详情页面
var that = this;
bus.$emit('toDetailPage', {
data: {
userName: that.userName,
commodityId: that.commodityId,
...
...
commodityDescription: that.commodityDescription,
},
})
uni.navigateTo({
url: "../../detailPage",
})
}
3.1、在目标B组件页面中也是先引用bus.js文件
import {bus} from "../../../utils/bus.js" // B组件
3.2、通过computed计算属性,来接受数据,动态响应刷新页面
// B组件
computed:{
userName(){
return bus.data.userName
},
commodityId(){
return bus.data.commodityId
},
...
...
commodityDescription(){
return bus.data.commodityDescription
}
},
2.2、兄弟组件传值应用实例
效果
1、在传值A组件同层级目录下,创建中间件js文件
src\views\sourceManage\multi\multi.js
import Vue from 'vue'
export const bus = new Vue({
data () {
return {
data: {}
}
},
created () {
this.$on('routePath', (value) => {
this.data = value.data
})
}
})
2、在A组件引用bus,进行传递数据
src\views\sourceManage\multi\multiList.vue
<template>
<el-button size="small" type="primary" @click="upload">上传</el-button>
</template>
<script>
import {bus} from './multi.js';
export default{
data(){
return{}
},
methods:{
// 上传
upload () {
let that = this;
bus.$emit('routePath', {data: {path: that.$route.path}}) // 给bus传参
this.$router.push({path: '/console/sourceManageFileUpload'}) //跳转到上传界面
}
}
}
</script>
3、在B组件引入bus,进行接收数据
src\views\sourceManage\file\FileUpload.vue
<template>
<div class="container">
<el-breadcrumb class="indexNav" separator-class="el-icon-arrow-right">
<el-breadcrumb-item>资源管理</el-breadcrumb-item>
<el-breadcrumb-item v-if="!show" :to="{name: 'sourceManageFileList'}">文件</el-breadcrumb-item>
<el-breadcrumb-item v-if="show" :to="{name: 'multiSourceDataImpo'}">多源数据导入</el-breadcrumb-item>
<el-breadcrumb-item>上传</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
<script>
import { bus } from '@/views/sourceManage/multi/multi.js';
export default{
data(){
return{}
},
computed: {
show () {
// 跳转到当前上传界面,从bus拿参数进行使用
return bus.data.path === '/console/multiSourceDataImpor'
}
},
}
</script>
附:此过程可用路由守卫代替_beforeRouteEnter
<template>
<div class="container">
<el-breadcrumb class="indexNav" separator-class="el-icon-arrow-right">
<el-breadcrumb-item>资源管理</el-breadcrumb-item>
<el-breadcrumb-item v-if="!show" :to="{name: 'sourceManageFileList'}">文件</el-breadcrumb-item>
<el-breadcrumb-item v-if="show" :to="{name: 'multiSourceDataImpo'}">多源数据导入</el-breadcrumb-item>
<el-breadcrumb-item>上传</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
<script>
export default{
data(){
return{
show: false,
}
},
beforeRouteEnter (to, from, next) {
next(vm => {
if (from.name === 'multiSourceDataImport') {
vm.show = true
}
vm.newPath = from.name
})
},
}
</script>