vue实现左右菜单联动实现
实现思路
Vue实现左右菜单联动通常需要两个组件:左侧的导航菜单和右侧的内容区域。通过监听左侧菜单的点击事件,动态更新右侧内容。核心在于数据绑定和事件传递。
基础代码结构
使用Vue的单文件组件(SFC)结构,分为左菜单和右内容两个组件。
<template>
<div class="container">
<LeftMenu :items="menuItems" @select="handleMenuSelect" />
<RightContent :activeItem="activeItem" />
</div>
</template>
<script>
import LeftMenu from './LeftMenu.vue'
import RightContent from './RightContent.vue'
export default {
components: { LeftMenu, RightContent },
data() {
return {
menuItems: [
{ id: 1, title: '菜单1' },
{ id: 2, title: '菜单2' }
],
activeItem: null
}
},
methods: {
handleMenuSelect(item) {
this.activeItem = item
}
}
}
</script>
左侧菜单组件
左侧菜单组件负责渲染菜单项并触发选择事件。
<template>
<div class="left-menu">
<div
v-for="item in items"
:key="item.id"
@click="$emit('select', item)"
:class="{ 'active': item.id === activeId }"
>
{{ item.title }}
</div>
</div>
</template>
<script>
export default {
props: ['items'],
emits: ['select']
}
</script>
右侧内容组件
右侧内容组件根据当前选中的菜单项显示对应内容。
<template>
<div class="right-content">
<div v-if="activeItem">
<h3>{{ activeItem.title }}</h3>
<p>这里是 {{ activeItem.title }} 的内容</p>
</div>
</div>
</template>
<script>
export default {
props: ['activeItem']
}
</script>
样式优化
为左右布局添加基础样式,确保视觉上的联动效果。
.container {
display: flex;
height: 100vh;
}
.left-menu {
width: 200px;
border-right: 1px solid #eee;
}
.left-menu div {
padding: 10px;
cursor: pointer;
}
.left-menu div.active {
background: #f0f0f0;
}
.right-content {
flex: 1;
padding: 20px;
}
动态内容加载
如需根据菜单项加载异步内容,可在右侧组件中使用watch监听activeItem变化。
<script>
export default {
props: ['activeItem'],
data() {
return {
content: null
}
},
watch: {
activeItem: {
immediate: true,
handler(newVal) {
if (newVal) {
this.loadContent(newVal.id)
}
}
}
},
methods: {
async loadContent(id) {
const res = await fetch(`/api/content/${id}`)
this.content = await res.json()
}
}
}
</script>
路由集成
若项目使用Vue Router,可将菜单联动与路由结合,通过router-link实现导航。

<template>
<div class="left-menu">
<router-link
v-for="item in items"
:key="item.id"
:to="item.path"
active-class="active"
>
{{ item.title }}
</router-link>
</div>
</template>






