目录
官方样式:
展开前:
展开:
原始代码:
代码详解:
项目使用场景:
完成效果:
具体实现范本:
1.调整数据结构
2. 修改标签和数据绑定
3. JavaScript 部分导入和创建对象
4.注意
官方样式:
展开前:
展开:
原始代码:
<template> switch parent border: <el-switch v-model="parentBorder" /> switch child border: <el-switch v-model="childBorder" /> <el-table :data="tableData" :border="parentBorder" style="width: 100%"> <el-table-column type="expand"> <template #default="props"> <div m="4"> <p m="t-0 b-2">State: {{ props.row.state }}</p> <p m="t-0 b-2">City: {{ props.row.city }}</p> <p m="t-0 b-2">Address: {{ props.row.address }}</p> <p m="t-0 b-2">Zip: {{ props.row.zip }}</p> <h3>Family</h3> <el-table :data="props.row.family" :border="childBorder"> <el-table-column label="Name" prop="name" /> <el-table-column label="State" prop="state" /> <el-table-column label="City" prop="city" /> <el-table-column label="Address" prop="address" /> <el-table-column label="Zip" prop="zip" /> </el-table> </div> </template> </el-table-column> <el-table-column label="Date" prop="date" /> <el-table-column label="Name" prop="name" /> </el-table> </template> <script lang="ts" setup> import { ref } from 'vue' const parentBorder = ref(false) const childBorder = ref(false) const tableData = [ { date: '2016-05-03', name: 'Tom', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', family: [ { name: 'Jerry', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Spike', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Tyke', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, ], }, { date: '2016-05-02', name: 'Tom', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', family: [ { name: 'Jerry', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Spike', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Tyke', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, ], }, { date: '2016-05-04', name: 'Tom', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', family: [ { name: 'Jerry', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Spike', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Tyke', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, ], }, { date: '2016-05-01', name: 'Tom', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', family: [ { name: 'Jerry', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Spike', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Tyke', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, ], }, { date: '2016-05-08', name: 'Tom', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', family: [ { name: 'Jerry', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Spike', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Tyke', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, ], }, { date: '2016-05-06', name: 'Tom', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', family: [ { name: 'Jerry', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Spike', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Tyke', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, ], }, { date: '2016-05-07', name: 'Tom', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', family: [ { name: 'Jerry', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Spike', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, { name: 'Tyke', state: 'California', city: 'San Francisco', address: '3650 21st St, San Francisco', zip: 'CA 94114', }, ], }, ] </script>
代码详解:
- 首先,根据
v-model
指令,在 Vue 的setup()
中定义了parentBorder
和childBorder
两个响应式变量,分别用于控制父表格和子表格的边框显示与隐藏。- 然后,通过传入数据数组
tableData
给<el-table>
的:data
属性,将数据渲染为表格。同时,使用:border
属性绑定了parentBorder
和childBorder
变量,以实现动态控制表格边框的显示与隐藏。- 在表格中,使用
<template>
标签和#default
的语法糖来定义扩展列中的内容。扩展列通过点击图标或者行展开按钮来显示更多详细信息。- 在扩展列中,使用了
<el-table>
嵌套来展示家庭成员的信息。同样地,也使用了:border
属性绑定了childBorder
变量,以便动态控制子表格边框的显示。- 在展示每个家庭成员的信息时,使用了
<p>
和<h3>
标签来显示不同的文本内容,其中<h3>
标签用于显示 "Family" 这个标题。
项目使用场景:
项目中有一对多的数据想要展示,例如:一个团队对应多个成员,父表格展示团队信息,子表格展示对应成员信息
完成效果:
父表格展示团队信息,子表格展示对应成员信息
具体实现范本:
1.调整数据结构
根据你的数据库中的表结构,创建一个适当的数据结构来存储团队信息和成员信息。可以使用 JavaScript 对象或数组的形式来表示
const teamData = [ { teamName: 'Team A', teamMembers: [ { name: 'John', age: 25, position: 'Manager' }, { name: 'Alice', age: 30, position: 'Developer' }, { name: 'Bob', age: 28, position: 'Designer' } ] }, { teamName: 'Team B', teamMembers: [ { name: 'Mike', age: 32, position: 'Manager' }, { name: 'Sarah', age: 27, position: 'Developer' }, { name: 'Emily', age: 29, position: 'Designer' } ] }, // ... 可以添加更多的团队信息 ];
在这个例子中,
teamData
数组包含了多个团队对象,每个团队对象都有团队名称teamName
和团队成员数组teamMembers
。每个团队成员对象都包含了成员的姓名
name
、年龄age
和职位position
2. 修改标签和数据绑定
<el-table :data="teamData" :border="parentBorder" style="width: 100%"> <el-table-column type="expand"> <template #default="props"> <div> <h3>Team Name: {{ props.row.teamName }}</h3> <el-table :data="props.row.teamMembers" :border="childBorder"> <el-table-column label="Name" prop="name" /> <el-table-column label="Age" prop="age" /> <el-table-column label="Position" prop="position" /> </el-table> </div> </template> </el-table-column> <el-table-column label="Team Name" prop="teamName" /> </el-table>
在这个修改后的代码中,将标签中的
tableData
修改为teamData
。在父表格中,使用teamData
数组作为数据源,并绑定到<el-table>
的:data
属性上。在扩展列中,使用
props.row
来获取当前团队对象的信息,包括团队名称和团队成员数组。然后通过嵌套的<el-table>
组件来展示每个团队成员的信息,使用props.row.teamMembers
作为数据源。
<el-table-column>
标签中的prop
属性与数据对象的属性名进行绑定,以正确地显示每个成员的姓名、年龄和职位。3. JavaScript 部分导入和创建对象
import { ref } from 'vue'; // ... const parentBorder = ref(false); const childBorder = ref(false); const teamData = [ // 数据结构和示例中的相同 ];
- 在这个示例代码中,导入了
ref
函数,并在setup()
中使用它来创建父表格和子表格边框的开关变量parentBorder
和childBorder
。- 你可以根据需要设置默认的开关状态,或者根据用户的操作来改变它们的值。
- 通过以上步骤,你已经成功地修改了代码,使其能够展示父表格和子表格,并以团队信息和成员信息的形式呈现。请根据你的实际情况调整数据结构和样式,并根据需求修改其他相关部分
4.注意
对于
teamMember
的类型定义,可以使用一个包含成员信息的对象数组。每个成员对象可以包含学号、姓名、专业、年级等属性interface TeamMember { studentID: string; studentName: string; major: string; grade: string; lab: string; } interface Team { teamName: string; projectName: string; projectIntro: string; coach: string; contest: string; award: string; teamMember: TeamMember[]; }
在这个定义中,
teamMember
属性的类型被修改为TeamMember[]
,表示一个TeamMember
对象的数组。每个TeamMember
对象包含了学生的学号、姓名、专业、年级等信息。