vue实现左右菜单联动实现
Vue 实现左右菜单联动
使用事件总线通信
在 Vue 中可以通过事件总线实现左右菜单的通信。创建一个中央事件总线实例,让左右菜单通过事件监听和触发实现联动。
// eventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
在左侧菜单组件中触发事件:
// LeftMenu.vue
import { EventBus } from './eventBus';
methods: {
handleMenuClick(item) {
EventBus.$emit('menu-selected', item.id);
}
}
在右侧菜单组件中监听事件:
// RightMenu.vue
import { EventBus } from './eventBus';
created() {
EventBus.$on('menu-selected', (menuId) => {
this.activeMenuId = menuId;
});
}
使用 Vuex 状态管理
对于更复杂的联动逻辑,可以使用 Vuex 集中管理状态。定义共享的状态和 mutations,让左右菜单通过 commit 和 getters 实现联动。
// store.js
export default new Vuex.Store({
state: {
activeMenuId: null
},
mutations: {
setActiveMenu(state, menuId) {
state.activeMenuId = menuId;
}
}
});
左侧菜单触发 mutation:
// LeftMenu.vue
methods: {
handleMenuClick(item) {
this.$store.commit('setActiveMenu', item.id);
}
}
右侧菜单响应状态变化:
// RightMenu.vue
computed: {
activeMenuId() {
return this.$store.state.activeMenuId;
}
}
使用父子组件通信
如果左右菜单是父子组件关系,可以通过 props 和 $emit 实现联动。父组件维护共享状态,通过 props 传递给子组件,子组件通过事件通知父组件更新状态。
父组件:
// ParentComponent.vue
<template>
<div>
<LeftMenu :activeId="activeMenuId" @menu-change="handleMenuChange" />
<RightMenu :activeId="activeMenuId" />
</div>
</template>
<script>
export default {
data() {
return {
activeMenuId: null
};
},
methods: {
handleMenuChange(menuId) {
this.activeMenuId = menuId;
}
}
};
</script>
左侧子组件:
// LeftMenu.vue
<template>
<div>
<div v-for="item in menuItems" @click="$emit('menu-change', item.id)">
{{ item.name }}
</div>
</div>
</template>
右侧子组件:
// RightMenu.vue
<template>
<div>
<div v-if="activeId === 1">Content for Menu 1</div>
<div v-if="activeId === 2">Content for Menu 2</div>
</div>
</template>
<script>
export default {
props: ['activeId']
};
</script>
使用 provide/inject
对于深层嵌套的组件,可以使用 provide/inject 实现跨层级通信。祖先组件提供数据,后代组件注入使用。
祖先组件:
// Ancestor.vue
export default {
provide() {
return {
menuData: {
activeId: this.activeMenuId,
setActiveId: this.setActiveId
}
};
},
data() {
return {
activeMenuId: null
};
},
methods: {
setActiveId(id) {
this.activeMenuId = id;
}
}
};
后代组件:
// Descendant.vue
export default {
inject: ['menuData'],
methods: {
handleClick() {
this.menuData.setActiveId(123);
}
}
};






