终于遇到需要css计算属性的需求啦~业务理解是“展示GPU在系统、业务、释放中、可用4中状态下的占比”,本项目基于vue3+element,数据展示使用了el-table,这篇记录一下使用过程中的坑。
css计算属性的直接写法
大概实现效果如下:
占比条(percent bar)需要在column中定制化处理,使用一个宽度固定的块ul作为容器,里面排列4个小块li,4个小块的宽度是计算所得的。
| <el-table-column label="GPU" width="120" align="center"> <template #default="scope"> <p>{{ scope.row.gpu_card_text }}</p> <ul class="percent"> <li :style="scope.row.w1Style"></li> <li :style="scope.row.w2Style"></li> <li :style="scope.row.w3Style"></li> <li :style="scope.row.w4Style"></li> </ul> </template> </el-table-column>
|
样式计算属性代码设置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| tempList.map((i) => { let w1 = (i.gpu_card[0] / sum) * 100; let w2 = (i.gpu_card[1] / sum) * 100; let w3 = (i.gpu_card[2] / sum) * 100; let w4 = (i.gpu_card[3] / sum) * 100; let w1Style = computed(() => { return { "--width": w1 + "%" }; }); let w2Style = computed(() => { return { "--width": w2 + "%" }; }); let w3Style = computed(() => { return { "--width": w3 + "%" }; }); let w4Style = computed(() => { return { "--width": w4 + "%" }; }); return Object.assign(i, { w1Style, w2Style, w3Style, w4Style }); }); dataList.tableData = tempList;
|
还需要在css中添加:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| .percent { display: flex; width: 100px; border-radius: 5px; overflow: hidden; li { height: 10px; } li:nth-child(1) { background-color: red; width: var(--width); } li:nth-child(2) { background-color: yellow; width: var(--width); } li:nth-child(3) { background-color: blue; width: var(--width); } li:nth-child(4) { background-color: green; width: var(--width); } }
|
做成一个组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| <template> <ul class="percent"> <li :style="w1Style"></li> <li :style="w2Style"></li> <li :style="w3Style"></li> <li :style="w4Style"></li> </ul> </template> <script lang="ts"> import { defineComponent, computed } from "vue"; export default defineComponent({ name: "percent-bar", props: { data: { type: Array, }, }, setup(props) { let tempList = props.data; const sum = tempList.reduce((prev, cur) => { return Number(prev) + Number(cur); }); let w1 = (Number(tempList[0]) / Number(sum)) * 100; let w2 = (Number(tempList[1]) / Number(sum)) * 100; let w3 = (Number(tempList[2]) / Number(sum)) * 100; let w4 = (Number(tempList[3]) / Number(sum)) * 100; let w1Style = computed(() => { return { "--width": w1 + "%" }; }); let w2Style = computed(() => { return { "--width": w2 + "%" }; }); let w3Style = computed(() => { return { "--width": w3 + "%" }; }); let w4Style = computed(() => { return { "--width": w4 + "%" }; }); return { w1Style, w2Style, w3Style, w4Style, }; }, }); </script>
<style lang="scss" scoped> .percent {...} </style>
|
在父组件中这样调用
| <el-table-column label="GPU" width="120" align="center"> <template #default="scope"> <p>{{ scope.row.gpu_card_text }}</p> <percent-bar :data="scope.row.gpu_card"></percent-bar> </template> </el-table-column>
|
Q & A
在编写组件的时候,先使用了循环渲染,但是发现元素没有渲染出来,查看浏览器发现style上没有挂载成功。具体原因有待研究。