Table of contents
Specific implementation template:
2. Modify label and data binding
3. JavaScript part imports and creates objects
Official styles:
Before expanding:
Expand:
Original code:
<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>
Detailed code:
- First, according to the directive, two responsive variables of and are defined
v-model
in Vue , which are used to control the display and hiding of the borders of the parent table and child table respectively.setup()
parentBorder
childBorder
- Then, render the data as a table by passing the data array
tableData
to the property<el-table>
of the .:data
At the same time, the and variables:border
are bound using the property to dynamically control the display and hiding of the table border.parentBorder
childBorder
- In tables, use
<template>
tag and#default
syntactic sugar to define the content in the extended column. Expand columns to display more detailed information by clicking the icon or the row expand button.- In the extended column,
<el-table>
nesting is used to display information about family members. Similarly, the variable is also:border
bound using the propertychildBorder
to dynamically control the display of the border of the subtable.- When displaying the information of each family member, the
<p>
and<h3>
tags are used to display different text content, and<h3>
the tag is used to display the title "Family".
Project usage scenario:
There is one-to-many data in the project that you want to display, for example: a team corresponds to multiple members, the parent table displays team information, and the child table displays corresponding member information
Finished effect:
The parent table displays team information, and the child table displays corresponding member information
Specific implementation template:
1. Adjust the data structure
According to the table structure in your database, create an appropriate data structure to store team information and member information. Can be represented as JavaScript objects or arrays
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' } ] }, // ... 可以添加更多的团队信息 ];
In this example,
teamData
the array contains multiple team objects, each team object has a team nameteamName
and an array of team membersteamMembers
.Each team member object contains the member's name
name
, ageage
and positionposition
2. Modify label and data binding
<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>
In this modified code, change the in the label
tableData
toteamData
. In the parent grid, useteamData
the array as the data source and bind to the property<el-table>
of:data
the .In the extended column, use
props.row
to get information about the current team object, including the team name and an array of team members. Then use nested<el-table>
components to display information about each team member, usingprops.row.teamMembers
as a data source.
<el-table-column>
The attribute in the labelprop
is bound to the attribute name of the data object to correctly display each member's name, age, and position.3. JavaScript part imports and creates objects
import { ref } from 'vue'; // ... const parentBorder = ref(false); const childBorder = ref(false); const teamData = [ // 数据结构和示例中的相同 ];
- In this sample code,
ref
the function is imported and used in to create the switch variables andsetup()
for the borders of the parent and child tables .parentBorder
childBorder
- You can set the default switch state as you want, or change their values based on user actions.
- Through the above steps, you have successfully modified the code so that it can display the parent table and child table in the form of team information and member information. Please adjust the data structure and style according to your actual situation , and modify other relevant parts according to your needs
4. Pay attention
For
teamMember
the type definition of , an array of objects containing member information can be used. Each member object can contain attributes such as student number, name, major, grade, etc.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[]; }
In this definition,
teamMember
the type of the property is changedTeamMember[]
to represent anTeamMember
array of objects. EachTeamMember
object contains the student's student number, name, major, grade and other information.