vue2 watch 的使用
原理:
- 你「盯着」某个数据(比如
mainForm.materialType
) - 一旦它变了,就执行一个函数
解决问题:
过去的“盲目加载”问题,一旦多这样的数据加载多了,导致页面非常卡顿,后端数据库也不好受!!!
created() {this.loadMainApply() // ❌ 不管用户要不要,先加载主单this.loadDictList() // ❌ 字典还行this.loadDetailList() // ❌ 最严重:不管是不是 L7,都请求列表!
}
<template><div class="apply-detail-page" style="padding: 24px;"><!-- 主申请单 --><a-card title="主申请单" style="margin-bottom: 24px;"><div class="form-item"><label>申请单编号:</label><span>{{ mainForm.applyNo }}</span></div><div class="form-item"><label>物料类型:</label><a-selectv-model="mainForm.materialType"placeholder="请选择物料类型"style="width: 200px"><!-- 🔽 动态渲染字典 --><a-select-optionv-for="item in materialTypeOptions":key="item.value":value="item.value">{{ item.label }}</a-select-option></a-select></div><div class="form-item"><label>申请人:</label><span>{{ mainForm.applicant }}</span></div></a-card><!-- L7 列表 --><a-card title="详情列表" v-if="mainForm.materialType === 'L7' && detailList.length > 0"><a-table:dataSource="detailList":columns="columns":row-key="record => record.id":pagination="{ pageSize: 10 }"/></a-card></div>
</template><script>
export default {name: 'ApplyDetail',data() {return {mainForm: {applyNo: '',materialType: '',applicant: ''},detailList: [],l7DataLoaded: false,columns: [{ title: '项目', dataIndex: 'item' },{ title: '数量', dataIndex: 'qty' }],dictList: [], // 存放所有字典materialTypeOptions: [] // 存放 MATERIAL_TYPE 类型的选项}},created() {console.log('组件创建')this.loadDictList() // 先加载字典this.loadMainApply()},watch: {'mainForm.materialType'(newVal) {if (newVal === 'L7' && !this.l7DataLoaded) {this.loadDetailList()}}},methods: {// 模拟接口:返回 PromisefetchDictList() {return Promise.resolve({data: [{ type: 'MATERIAL_TYPE', value: 'L1', label: 'L1 - 普通物料' },{ type: 'MATERIAL_TYPE', value: 'L5', label: 'L5 - 特殊物料' },{ type: 'MATERIAL_TYPE', value: 'L7', label: 'L7 - 高级物料' },{ type: 'APPLY_STATUS', value: 'DRAFT', label: '草稿' },{ type: 'APPLY_STATUS', value: 'SUBMITTED', label: '已提交' }]})},fetchMainApply() {return Promise.resolve({data: {applyNo: 'AP20250827001',materialType: 'L1',applicant: '张三'}})},fetchDetailList() {console.log('[API] 正在请求 L7 列表数据...')return new Promise((resolve) => {setTimeout(() => {resolve({data: [{ id: 1, item: 'L7-校验模块', qty: 1 },{ id: 2, item: 'L7-加密组件', qty: 1 },{ id: 3, item: 'L7-审计日志', qty: 1 }]})}, 800)})},// -------------------------------// 使用 .then() 替代 async/await// -------------------------------loadDictList() {this.fetchDictList().then(res => {this.dictList = res.datathis.materialTypeOptions = res.data.filter(item => item.type === 'MATERIAL_TYPE')console.log('字典加载完成,物料类型选项:', this.materialTypeOptions)}).catch(error => {console.error('字典加载失败', error)})},loadMainApply() {this.fetchMainApply().then(res => {this.mainForm = res.dataconsole.log('主单加载完成:', res.data)}).catch(error => {console.error('主单加载失败', error)})},loadDetailList() {if (this.l7DataLoaded) {console.log('缓存命中:L7 数据已加载过,跳过请求')return}console.log('开始加载 L7 数据...')this.fetchDetailList().then(res => {this.detailList = res.datathis.l7DataLoaded = trueconsole.log('L7 数据加载完成')}).catch(error => {console.error('L7 数据加载失败', error)})}
}
}
</script><style scoped>
.form-item {margin-bottom: 16px;
}
.form-item label {display: inline-block;width: 100px;font-weight: 500;
}
</style>