feat: 接口返回数据需要根据多个枚举值动态计算结果渲染(多个枚举值是接口返回,并且不知道具体返回时间)

master
LCJ-MinYa 2 months ago
parent 5782f42db3
commit b254d008fc

@ -70,9 +70,3 @@ vue3-mgt-template/
使用了删除线的就代表已执行完成
### 任务列表
* 请关注以下两个文件夹
- /src/views/demo/computedWithEnumList
- /mock (mock接口返回computedWithEnumList组件内所需接口getPageInfo, getEnumList, getEnumList是一个通用接口每次根据传入的类型返回对应的枚举值比如传入性别 只返回性别的枚举值因此getEnumList需要循环多次执行获取所有枚举列表)
**要求**
- computedWithEnumList组件内需要的接口在mock内新建文件创建接口
- mock接口需要模拟延迟返回 getPageInfo随机200~500msgetEnumList接口随机15s

@ -5,6 +5,28 @@
## 对话记录
### 本次会话总结 (2025年10月30日)
本次会话完成了 `computedWithEnumList` 示例页面的开发任务,主要包含以下步骤:
1. **创建 Mock 接口**:
* 在 `mock/` 目录下新建了 `computedWithEnumList.ts` 文件。
* 在该文件中定义了两个接口:
* `getPageInfo`: 用于获取分页表格数据,并模拟了 200-500ms 的随机延迟。
* `getEnumList`: 用于根据类型获取枚举值列表(如性别、状态等),并模拟了 1-5s 的随机延迟,以测试异步场景。
2. **创建 Vue 组件**:
* 在 `src/views/demo/` 目录下创建了 `computedWithEnumList/index.vue` 页面组件。
* 该组件在挂载时会并行请求表格数据和多个枚举值列表。
* 使用计算属性(`computed`)将接口返回的原始枚举值(如 `1`, `2`)动态映射为对应的标签(如 `男`, `女`),解决了数据和枚举值返回时机不确定的问题。
3. **代码风格调整**:
* 初版组件使用了 Vue 3 的组合式 API`setup` 语法糖)。
* 根据用户要求,将组件重构为选项式 API 风格,同时保持了原有的全部功能和模板结构,以符合项目现有代码规范。
4. **路由集成**:
* 利用项目中 `src/router/modules/demo.ts` 的动态路由生成机制,新创建的页面组件被自动集成到路由系统中,无需手动配置,可以通过 `/demo/computedWithEnumList` 路径直接访问。
### 本次会话总结 (2025年10月14日)
本次会话主要围绕 **首页动态化改造** 展开,完成了以下核心功能:
@ -46,11 +68,19 @@
* `config.json` 文件内容恢复正常,证明了跨平台兼容性问题已解决。
### 任务列表
* ~~项目首页/welcome这个路由下是默认的的首页介绍页面但是现在这个页面是一个静态的页面是由一些模拟数据渲染的我现在希望完成功能如下~~
- ~~在package.json中添加一个命令当执行这个命令的时候可以本地统计/src/views下的/demo/python/utils/screen这四个模块下分别有多少个页面页面维度请按照router路由来统计例如/python文件夹有五个文件夹这就是5个页面。当统计完成后在/src/views/welcome中创建或者更新config.json文件以便后续页面可以直接读取json配置文件~~
- ~~请读取/src/view/welcome中页面其中页面的数据来源为/scripts/statistics.mjs请更新该脚本以便获得更多的信息来满足/src/view/welcome页面所需数据的渲染~~
* 项目首页/welcome这个路由下是默认的的首页介绍页面但是现在这个页面是一个静态的页面是由一些模拟数据渲染的我现在希望完成功能如下
- 在package.json中添加一个命令当执行这个命令的时候可以本地统计/src/views下的/demo/python/utils/screen这四个模块下分别有多少个页面页面维度请按照router路由来统计例如/python文件夹有五个文件夹这就是5个页面。当统计完成后在/src/views/welcome中创建或者更新config.json文件以便后续页面可以直接读取json配置文件
- 请读取/src/view/welcome中页面其中页面的数据来源为/scripts/statistics.mjs请更新该脚本以便获得更多的信息来满足/src/view/welcome页面所需数据的渲染
- 将/src/view/welcome/config.json作为数据源渲染到/src/view/welcome的vue组件中
* 本项目是一个个人的代码总结记录网站在部署生成环境的时候即执行pnpm build的时候也是需要查看console日志的现在请帮我打开生产环境的打印信息和日志.
- ~~将/src/view/welcome/config.json作为数据源渲染到/src/view/welcome的vue组件中~~
* ~~本项目是一个个人的代码总结记录网站在部署生成环境的时候即执行pnpm build的时候也是需要查看console日志的现在请帮我打开生产环境的打印信息和日志。~~
* ~~请关注以下两个文件夹
- /src/views/demo/computedWithEnumList
- /mock (mock接口返回computedWithEnumList组件内所需接口getPageInfo, getEnumList, getEnumList是一个通用接口每次根据传入的类型返回对应的枚举值比如传入性别 只返回性别的枚举值因此getEnumList需要循环多次执行获取所有枚举列表)
**要求**
- computedWithEnumList组件内需要的接口在mock内新建文件创建接口
- mock接口需要模拟延迟返回 getPageInfo随机200~500msgetEnumList接口随机15s~~

@ -0,0 +1,75 @@
// 模拟获取computedWithEnumList页面所需接口
import { defineFakeRoute } from 'vite-plugin-fake-server/client';
import { faker } from '@faker-js/faker';
// 模拟后端延迟返回
const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
// 模拟枚举值
const enums = {
// 性别
gender: [
{ label: '男', value: 1 },
{ label: '女', value: 2 },
{ label: '未知', value: 0 },
],
// 状态
status: [
{ label: '启用', value: 1 },
{ label: '禁用', value: 0 },
],
// 角色
role: [
{ label: '管理员', value: 'admin' },
{ label: '普通用户', value: 'common' },
],
};
export default defineFakeRoute([
{
url: '/computed-with-enum-list/get-page-info',
method: 'post',
response: async ({ body }) => {
// 模拟延迟
await delay(faker.number.int({ min: 200, max: 500 }));
const list = [];
for (let i = 0; i < body.pageSize; i++) {
list.push({
id: faker.string.uuid(),
name: faker.person.fullName(),
gender: faker.helpers.arrayElement([0, 1, 2]),
status: faker.helpers.arrayElement([0, 1]),
role: faker.helpers.arrayElement(['admin', 'common']),
createTime: faker.date.past(),
});
}
return {
success: true,
code: 200,
data: {
list,
total: 100,
pageSize: body.pageSize,
pageNumber: body.pageNumber,
},
};
},
},
{
url: '/computed-with-enum-list/get-enum-list',
method: 'get',
response: async ({ query }) => {
// 模拟超长延迟
await delay(faker.number.int({ min: 1000, max: 5000 }));
const type = query.type as keyof typeof enums;
return {
success: true,
code: 200,
data: enums[type] || [],
};
},
},
]);

@ -146,6 +146,10 @@ const titleArr = [
key: 'computedRules',
title: 'ElementUI的form组件使用rules时动态计算并传入组件实例',
},
{
key: 'computedWithEnumList(AI)',
title: '接口返回数据需要根据多个枚举值动态计算结果渲染(多个枚举值是接口返回,并且不知道具体返回时间)',
},
{
key: 'computedWithEnumList',
title: '接口返回数据需要根据多个枚举值动态计算结果渲染(多个枚举值是接口返回,并且不知道具体返回时间)',

@ -0,0 +1,129 @@
<script lang="ts">
import { defineComponent } from 'vue';
import axios from 'axios';
export default defineComponent({
name: 'ComputedWithEnumList',
data() {
return {
//
loading: false,
//
tableData: [],
//
pagination: {
pageNumber: 1,
pageSize: 10,
total: 0,
},
//
enums: {
gender: [],
status: [],
role: [],
},
};
},
computed: {
//
enumMap() {
const map = {
gender: {},
status: {},
role: {},
};
for (const key in this.enums) {
this.enums[key].forEach((item) => {
map[key][item.value] = item.label;
});
}
return map;
},
},
methods: {
//
async getPageInfo() {
try {
const res = await axios.post('/computed-with-enum-list/get-page-info', {
pageNumber: this.pagination.pageNumber,
pageSize: this.pagination.pageSize,
});
if (res.data.success) {
this.tableData = res.data.data.list;
this.pagination.total = res.data.data.total;
}
} catch (error) {
console.error('获取表格数据失败:', error);
}
},
//
async getEnumList(type: string) {
try {
const res = await axios.get('/computed-with-enum-list/get-enum-list', { params: { type } });
if (res.data.success) {
this.enums[type] = res.data.data;
}
} catch (error) {
console.error(`获取枚举值(${type})失败:`, error);
}
},
//
formatGender(row) {
return this.enumMap.gender[row.gender] || row.gender;
},
formatStatus(row) {
return this.enumMap.status[row.status] || row.status;
},
formatRole(row) {
return this.enumMap.role[row.role] || row.role;
},
},
async mounted() {
this.loading = true;
await Promise.all([this.getPageInfo(), this.getEnumList('gender'), this.getEnumList('status'), this.getEnumList('role')]);
this.loading = false;
},
});
</script>
<template>
<div class="p-4">
<el-card>
<template #header>
<div class="card-header">
<span>计算属性与枚举值列表(AI实现使用table的formatter属性确实更优雅但是有局限性)</span>
</div>
</template>
<el-table
:data="tableData"
v-loading="loading"
border
stripe
>
<el-table-column
prop="name"
label="姓名"
/>
<el-table-column
prop="gender"
label="性别"
:formatter="formatGender"
/>
<el-table-column
prop="status"
label="状态"
:formatter="formatStatus"
/>
<el-table-column
prop="role"
label="角色"
:formatter="formatRole"
/>
<el-table-column
prop="createTime"
label="创建时间"
/>
</el-table>
</el-card>
</div>
</template>

@ -1,40 +1,130 @@
<template>
<div class="p-5 space-y-5 !bg-gray-100">
<el-card
header="页面请求一个初始化数据初始化数据中只返回了枚举值的key, 需要异步获取所有枚举列表多个枚举值是接口返回并且不知道具体返回时间然后根据key获取对应的value再进行渲染"
>
</el-card>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import axios from 'axios';
<script>
export default {
export default defineComponent({
name: 'ComputedWithEnumList',
data() {
return {
pageInfo: {},
enumList: [
{
//
sexOptions: [],
//
eduList: [],
//
marriageList: [],
//
idTypeList: [],
//
jobList: [],
//
nationList: [],
},
//
loading: false,
//
tableData: [],
//
tableColumns: [
{ prop: 'name', label: '姓名' },
{ prop: 'gender', label: '性别' },
{ prop: 'status', label: '状态' },
{ prop: 'role', label: '角色' },
{ prop: 'createTime', label: '创建时间' },
],
//
pagination: {
pageNumber: 1,
pageSize: 10,
total: 0,
},
//
enums: {
gender: [],
status: [],
role: [],
},
};
},
created() {
this.getPageInfo();
this.getEnumList();
computed: {
//
enumMap() {
const map = {
gender: {},
status: {},
role: {},
};
for (const key in this.enums) {
this.enums[key].forEach((item) => {
map[key][item.value] = item.label;
});
}
return map;
},
cptTableData() {
return this.tableData.map((item) => {
return {
...item,
gender: this.formatGender(item),
status: this.formatStatus(item),
role: this.formatRole(item),
};
});
},
},
methods: {
//
async getPageInfo() {
try {
const res = await axios.post('/computed-with-enum-list/get-page-info', {
pageNumber: this.pagination.pageNumber,
pageSize: this.pagination.pageSize,
});
if (res.data.success) {
this.tableData = res.data.data.list;
this.pagination.total = res.data.data.total;
}
} catch (error) {
console.error('获取表格数据失败:', error);
}
},
//
async getEnumList(type: string) {
try {
const res = await axios.get('/computed-with-enum-list/get-enum-list', { params: { type } });
if (res.data.success) {
this.enums[type] = res.data.data;
}
} catch (error) {
console.error(`获取枚举值(${type})失败:`, error);
}
},
//
formatGender(row) {
return this.enumMap.gender[row.gender] || row.gender;
},
formatStatus(row) {
return this.enumMap.status[row.status] || row.status;
},
formatRole(row) {
return this.enumMap.role[row.role] || row.role;
},
},
};
async mounted() {
this.loading = true;
await Promise.all([this.getPageInfo(), this.getEnumList('gender'), this.getEnumList('status'), this.getEnumList('role')]);
this.loading = false;
},
});
</script>
<style lang="scss" scoped></style>
<template>
<div class="p-4">
<el-card>
<template #header>
<div class="card-header">
<span>计算属性与枚举值列表(自己实现不使用table的formatter属性)</span>
</div>
</template>
<el-table
:data="cptTableData"
v-loading="loading"
border
stripe
>
<el-table-column
v-for="column in tableColumns"
:key="column.prop"
:prop="column.prop"
:label="column.label"
/>
</el-table>
</el-card>
</div>
</template>

Loading…
Cancel
Save