Vuesax表格切换分页后element.style丢失,样式变白问题求助
问题描述
切换到第2页后再返回第1页时,表格原本设置的element.style丢失,显示为白色。尝试通过添加类控制样式但未成功,推测可能与使用v-if而非v-show有关,不清楚如何正确修复Vuesax的该问题。
代码片段
模板部分
<template #tbody> <vs-tr :key="i" v-for="(exchangedatasT, i) in $vs.getPage(exchangedatas1, page, max)" :data="exchangedatasT" class="tableColor" :class="{ lastDay: todayGo2 !== new Date().toISOString().substring(0, 10), }" > <vs-td ><p>{{ exchangedatasT.Machinecd }}</p></vs-td > <vs-td ><p>{{ exchangedatasT.Exchangedt }}</p></vs-td > <vs-td ><p>{{ exchangedatasT.ExchangeItemnm }}</p></vs-td > <vs-td ><p>{{ exchangedatasT.Specnm }}</p></vs-td > <vs-td class="pointer" :id="[`e${i}`]" @click="click2(i)"> <p> <span :id="[`s${i}`]"></span> {{ exchangedatasT.CntDay }} </p> </vs-td> <vs-td ><p>{{ exchangedatasT.ExchangeUser }}</p></vs-td > </vs-tr> </template>
脚本部分
created() { const vm = this; axios .post(``, { Machinecd: "Test", Exchangedt: vm.todayGo2, }) .then((response) => { const entries = Object.values(response.data); vm.exchangedatas1 = entries; for (let i = 0; i < Object.keys(response.data).length; i++) { this.ExchangeUser = response.data[i].ExchangeUser; this.CntDay = response.data[i].CntDay; setTimeout(() => { if (response.data[i].CntDay == 99999) { document.getElementById(`e${i}`).style.background = "#ceecc5"; document.getElementById(`e${i}`).style.color = "#176f24"; document.getElementById( `s${i}` ).innerHTML = `<span>更换完成: </span>`; } else if (response.data[i].CntDay > 20) { document.getElementById(`e${i}`).style.background = "#ceecc5"; document.getElementById(`e${i}`).style.color = "#176f24"; document.getElementById( `s${i}` ).innerHTML = `<span>检查完成: </span>`; } else if (response.data[i].CntDay > 10) { document.getElementById(`e${i}`).style.background = "#ffe079"; document.getElementById(`e${i}`).style.color = "#db751c"; document.getElementById( `s${i}` ).innerHTML = `<span>未检查: </span>`; } else { document.getElementById(`e${i}`).style.background = "#e96666"; document.getElementById(`e${i}`).style.color = "#ffffff"; document.getElementById( `s${i}` ).innerHTML = `<span>未检查: </span>`; } }, 1); } }) .catch((error) => { console.error(error); }); }
解决方案
问题根源
核心问题不是v-if/v-show,而是你直接通过原生DOM API设置样式和内容。Vuesax分页切换时,当前页的表格行会被重新渲染,之前通过document.getElementById设置的样式会因为DOM元素重建而丢失;加上setTimeout依赖DOM渲染时机,本身就不稳定。
修复步骤
1. 给数据添加响应式状态标识
在获取数据时,给每条数据添加状态类型,用响应式数据管理样式逻辑:
created() { const vm = this; axios .post(``, { Machinecd: "Test", Exchangedt: vm.todayGo2, }) .then((response) => { const entries = Object.values(response.data).map(item => { let statusType = ''; if (item.CntDay === 99999) { statusType = 'completed'; } else if (item.CntDay > 20) { statusType = 'checked'; } else if (item.CntDay > 10) { statusType = 'unchecked-warning'; } else { statusType = 'unchecked-danger'; } return { ...item, statusType }; }); vm.exchangedatas1 = entries; }) .catch((error) => { console.error(error); }); }
2. 模板中动态绑定样式与文本
去掉DOM操作相关的id,通过响应式状态绑定样式和文本:
<template #tbody> <vs-tr :key="exchangedatasT.Machinecd" <!-- 用数据唯一标识当key,避免索引引发的渲染问题 --> v-for="(exchangedatasT, i) in $vs.getPage(exchangedatas1, page, max)" :data="exchangedatasT" class="tableColor" :class="{ lastDay: todayGo2 !== new Date().toISOString().substring(0, 10) }" > <vs-td><p>{{ exchangedatasT.Machinecd }}</p></vs-td> <vs-td><p>{{ exchangedatasT.Exchangedt }}</p></vs-td> <vs-td><p>{{ exchangedatasT.ExchangeItemnm }}</p></vs-td> <vs-td><p>{{ exchangedatasT.Specnm }}</p></vs-td> <vs-td class="pointer" @click="click2(i)" :style="getTdStyle(exchangedatasT.statusType)" > <p> <span>{{ getStatusText(exchangedatasT.statusType) }}</span> {{ exchangedatasT.CntDay }} </p> </vs-td> <vs-td><p>{{ exchangedatasT.ExchangeUser }}</p></vs-td> </vs-tr> </template>
3. 定义样式与文本方法
在组件methods中添加工具方法,返回对应样式和文本:
methods: { getTdStyle(statusType) { switch(statusType) { case 'completed': case 'checked': return { background: '#ceecc5', color: '#176f24' }; case 'unchecked-warning': return { background: '#ffe079', color: '#db751c' }; case 'unchecked-danger': return { background: '#e96666', color: '#ffffff' }; default: return {}; } }, getStatusText(statusType) { switch(statusType) { case 'completed': return '更换完成:'; case 'checked': return '检查完成:'; default: return '未检查:'; } } }
可选:用CSS类替代内联样式
如果偏好CSS类管理样式,先定义类:
.bg-success { background-color: #ceecc5; color: #176f24; } .bg-warning { background-color: #ffe079; color: #db751c; } .bg-danger { background-color: #e96666; color: #ffffff; }
然后修改模板和方法:
<vs-td class="pointer" @click="click2(i)" :class="getTdClass(exchangedatasT.statusType)" >
getTdClass(statusType) { switch(statusType) { case 'completed': case 'checked': return 'bg-success'; case 'unchecked-warning': return 'bg-warning'; case 'unchecked-danger': return 'bg-danger'; default: return ''; } }
关键注意事项
- 不要用循环索引
i作为v-for的key,优先用数据自身的唯一标识(比如Machinecd),提升Vue渲染效率,避免不必要的DOM重建。 - 永远通过Vue响应式数据管理DOM状态,避免直接操作DOM,这是Vue开发的核心原则,能解决绝大多数渲染相关问题。
内容的提问来源于stack exchange,提问作者user19395617
相关产品推荐
相关产品推荐

