项目场景:
后端 :数据拿去,自己玩个日志管理页面出来
{
"curent": {
"ub_real_name": "扬钧测试账号",
"op_time": "2022-03-18 14:15:08",
"op_type": "修改",
"op_detail": {
"商机编码": "2022031717320012345",
"运维厂商": "运维方",
"厂商类型": 1,
"联系人名字": "李武",
"联系方式": "18200376981",
"服务内容": "运维项目"
}
},
"last": {
"ub_real_name": "扬钧测试账号",
"op_time": "2022-03-17 17:36:01",
"op_type": "新增",
"op_detail": {
"商机编码": "2022031717320012345",
"运维厂商": "运维中选单位",
"厂商类型": 0,
"联系人名字": "李四",
"联系方式": "18200375981",
"服务内容": null
}
}
}
我 :你这也太直接了吧哥,没图俺不做,不然到时候不满意又要让我改。
后端 :老板!快来啊,这切图仔又尥蹶子了,不配合工作哦,芜湖~ 我可以下班了。
老板 :嗯?! 你做不做的,看看人后端的黑眼圈,你惭愧不,看看你和他的发量,你怎么回事?
我 :俺做,俺做,老板您回去吧,回去好好休息下。。。
后端 :last 是 上一次日志的数据, curent是本次日志的数据,last不一定有,注意页面的显示效果。
我 :得嘞,交给我了哥,瞧好吧。
开始实现:
最初的布局 :
如下图,借鉴网上现成的日志页面,我想分左右两部分来分别展示本次和上次日志信息
不过 很快啊,啪的一下,就被否决了, 因为 需要满足 对比效果明显 的 功能点, 确实我这种方案对比不够明显,而且最好数据不一致的时候能 标识 一下
优化后的页面效果:
如下图所示 :
有last的情况 无last的情况
解析:
三个基础字段 : (同理,last也是一样的,直接取出来就可以了)
代码:
<div class="db">
<table>
<thead>
<tr>
<td rowspan="2" style="width: 100px"></td>
<td style="text-align: center"><el-tag type="success">当前日志</el-tag></td>
<td v-if="op_detail_last" style="text-align: center"><el-tag type="info">上次日志</el-tag></td>
</tr>
<tr>
<td>
<div class="info_td">
<div>操作人: {{curent_obj.ub_real_name}}</div>
<div>操作时间: {{curent_obj.op_time}}</div>
<div>操作类型: {{curent_obj.op_type}}</div>
</div>
</td>
<td v-if="op_detail_last">
<div class="info_td">
<div>操作人: {{last_obj.ub_real_name}}</div>
<div>操作时间: {{last_obj.op_time}}</div>
<div>操作类型: {{last_obj.op_type}}</div>
</div>
</td>
</tr>
</thead>
<tbody>
在这里写的时候遇到一个写法的失误
详见下方说明
</tbody>
</table>
</div>
难点:
关键还是这个 op_detail 里面的数据,
在last里面 也有一份这样的数据,这两个op_detail 里面的key 是相似的
即:有可能key完全一样,也有可能 这两者之间 的key多一个少一个之类的,不确定
最开始tbody里面的写法:
1. 从下面的 td 渲染结构可以看出 我想构造一个 need_arr
2. 这个 need_arr 里面的每一个 v 都包含 三个键值对
3. 这样就很方便直接 渲染出来了
4. 但是, 细看文章开头后端那个B给的是json,这样做不是不可以,就是不太优雅,很麻烦和笨重
5. 而且,v.key 不能保证 v.val_curent 和 v.val_last 都有,因为这两份数据的key不一定相等
<tr v-for="(v,index) in need_arr" :key="index">
<td>{{v.key}}</td>
<td>{{v.val_curent}}</td>
<td>{{v.val_last}}</td>
</tr>
优化后原理图解析:
如图 :构造一个这两份数据的 公共key数组,合并然后去重 —— log_detail_keys
优化后的tbody写法:
HTML:
<tr v-for="(v,index) in log_detail_keys" :key="index"
:class="{'diff': isEq(op_detail, op_detail_last, v)}">
<td>{{v}}</td>
<td>{{op_detail ? op_detail[v] :"-"}}</td>
<td v-if="op_detail_last">{{op_detail_last[v]}}</td>
这里 v-if 不好哈,不要轻易模仿,
应该用 compted + filter 来做
可惜我比较懒而已
</tr>
js:
data:{
return {
log_detail_keys: [],
}
}
methods:{
用一个方法 比较方便地判断 应不应该 渲染 "diff"这个类 (默认不渲染)
传两个对象和 他们都有的k 进去做判断
避免了在dom上面写一大堆的 判断条件
isEq(a, b, k){
if(!b){
return false;
}
if(a[k] != b[k]){
return true;
}
return false;
},
query_log_detail(id) {
每次调这个方法要记得清空 公共key和 这两份数据
不然模态框显示会有问题,
this.log_detail_keys = null;
this.op_detail = null;
this.op_detail_last = null;
this.$axios({
url: "/query_log_detail",
responseType: "json",
method: "POST",
data: {
id: id,
},
})
.then((data) => {
let _data = data.data.data;
if (data.status == 200) {
构造一个 临时数组
let gk = []
if(_data.curent){
把它和第一份数据的keys 合并
gk = [...Object.keys(_data.curent.op_detail), ...gk]
this.curent_obj.ub_real_name = _data.curent.ub_real_name;
this.curent_obj.op_time = _data.curent.op_time;
this.curent_obj.op_type = _data.curent.op_type;
this.op_detail = _data.curent.op_detail;
}
if(_data.last){
如果有 last 再把它的keys和上面数据 一起合并
gk = [...Object.keys(_data.last.op_detail), ...gk]
this.last_obj.ub_real_name = _data.last.ub_real_name;
this.last_obj.op_time = _data.last.op_time;
this.last_obj.op_type = _data.last.op_type;
this.op_detail_last = _data.last.op_detail;
}
es6去重,公共keys就构造好了
gk = [...new Set(gk)]
赋值即可
this.log_detail_keys = gk
}
})
},
}
结语:
- 要想下班早,基础得打好
- 后端惹不起,精力无人比
- 老板你真好,马儿不吃草
- 编不出来了,csdn各大佬
|