vue主从表实现
Vue 主从表实现方法
主从表(Master-Detail)是一种常见的数据展示模式,主表展示主要数据列表,从表展示选中主表项的详细信息或关联数据。以下是几种实现方式:
使用 v-model 和计算属性
主表通过列表渲染,从表根据主表选中项动态显示内容:
<template>
<div class="master-detail">
<!-- 主表 -->
<ul class="master-list">
<li
v-for="item in masterData"
:key="item.id"
@click="selectedItem = item"
:class="{ active: selectedItem === item }"
>
{{ item.name }}
</li>
</ul>
<!-- 从表 -->
<div class="detail-view" v-if="selectedItem">
<h3>{{ selectedItem.name }} 的详细信息</h3>
<p>ID: {{ selectedItem.id }}</p>
<p>描述: {{ selectedItem.description }}</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
masterData: [
{ id: 1, name: '项目1', description: '这是项目1的描述' },
{ id: 2, name: '项目2', description: '这是项目2的描述' },
{ id: 3, name: '项目3', description: '这是项目3的描述' }
],
selectedItem: null
}
}
}
</script>
使用路由参数实现
适合主从表在不同页面展示的场景:
// 路由配置
{
path: '/master',
component: MasterList,
children: [
{
path: 'detail/:id',
component: DetailView,
props: true
}
]
}
主表组件中导航到详情:

<router-link :to="`/master/detail/${item.id}`">查看详情</router-link>
从表组件接收参数:
props: ['id'],
computed: {
detailItem() {
return this.masterData.find(item => item.id === this.id)
}
}
使用 Vuex 状态管理
适合复杂应用中的数据共享:

// store.js
state: {
masterData: [...],
selectedId: null
},
mutations: {
selectItem(state, id) {
state.selectedId = id
}
},
getters: {
selectedItem: state => {
return state.masterData.find(item => item.id === state.selectedId)
}
}
组件中使用:
<!-- 主表 -->
<li @click="$store.commit('selectItem', item.id)">{{ item.name }}</li>
<!-- 从表 -->
<div v-if="$store.getters.selectedItem">
{{ $store.getters.selectedItem.details }}
</div>
使用动态组件
适合从表有不同展示形式的场景:
<component :is="detailComponent" :item="selectedItem"></component>
components: {
BasicDetail,
AdvancedDetail
},
computed: {
detailComponent() {
return this.selectedItem?.type === 'advanced' ? 'AdvancedDetail' : 'BasicDetail'
}
}
样式建议
主从表布局通常使用CSS Flexbox或Grid:
.master-detail {
display: grid;
grid-template-columns: 300px 1fr;
gap: 20px;
}
.master-list {
border-right: 1px solid #eee;
}
.detail-view {
padding: 20px;
}
.active {
background-color: #f0f0f0;
}
以上方法可根据具体需求组合使用,简单场景推荐第一种方法,复杂应用建议使用Vuex或路由方案。






