(买了辆公路车,五一从北京出发骑行了一趟天津,10h,150km。很累但很爽,哈哈。路上看到了很多骑友,而且居然还有骑共享单车去天津的!看样子像是学生,实在佩服。)
前言
也是好久没更新文章了,一直说要学习来着,主要是下班时间和周末经不住游戏和短视频小姐姐的'诱惑',常常沉迷于二者,还是自律性太差了,以后争取每天学习一段时间。话说,jym每天下班都会干什么?不会吧,不会吧,不会都在内卷吧,欢迎评论区留言。
ok,言归正传,近期项目组开了一个新项目,用的是vue3+vite的框架,近期项目也是快完工了,正好抽时间总结一下,遇到的一些需求和解决方法。如果jym近期遇到了或者以后可能会遇到相似的需求,可以借鉴参考下。
字符串比对(diffjs)
先展示一下最终的效果
我们这个项目做的是一个流程,就是有一些数据,一些人可以去更改这些数据,但是更改完数据以后需要发起流程去审批,通过以后这条数据才会真正被修改。
那么审批人就需要知道发起人都修改了哪些数据,这就有了如图所示的需求。更改后的数据需要和原数据去比对,如果是新增的数据需要标红,删除的数据需要标红加删除线。
我这边用到了diffjs这个插件。数据上,后端返回了两个对象,oldData和newData,我们需要拿到两个data里相同字段的值进行比对,返回比对后的结果,就是用span标签包裹起来,然后用v-html去渲染。
代码实现:
js
import * as Diff from 'diff';
// 比较两个字符串,变化的标红,删除的加删除线
export const diffFun = (oldValue:string, newValue:string) => {
const testStr = Diff.diffChars(oldValue, newValue);
let str = '';
testStr.forEach((item:any) => {
if (item.added) {
str = `${str}<span style="color:red;">${item.value}</span>`;
} else if (item.removed) {
str = `${str}<span style="color:red;text-decoration: line-through;">${item.value}</span>`;
} else {
str = `${str}${item.value}`;
}
});
return str;
};
打印(printJS)
打印功能使用到了,printJS这个插件,printable是要打印的数据,field是要打印数据的字段名,displayName是要打印数据的表头名,columnSize可以设置列宽,但是会挤压最后一列。
js
import printJS from 'print-js';
// 打印函数
const printFun = async () => {
printJS({
printable: [...tableData], // 要打印的数据
properties: [
{ field: 'name', displayName: '名称' },
{ field: 'name', displayName: '名称' },
{ field: 'name', displayName: '名称' },
{ field: 'name', displayName: '名称' },
{ field: 'name', displayName: '名称', columnSize: '20%' },
{ field: 'name', displayName: '名称' },
{ field: 'name', displayName: '名称' },
{ field: 'name', displayName: '名称' },
{ field: 'name', displayName: '名称' },
{ field: 'name', displayName: '名称' },
{ field: 'name', displayName: '名称' }
],
type: 'json',
scanStyles: false, // 不适用默认样式
repeatTableHeader: false, // 打印json表头只显示在第一页
gridHeaderStyle: 'border: 1px solid #909399;text-align:center;', // 表格头样式
gridStyle: 'border: 1px solid #909399; text-align:center;', // 表哥体样式
style: '@page{size:auto;margin: 0cm 1cm 0cm 1cm;}'// 去除页眉页脚
// style:'@media print{@page {size:landscape}}' //横行打印
});
};
两端布局中间可拖拽功能实现
相关代码逻辑:
js
<template>
<div :style="{height:that.height}" class="box">
<el-row :gutter="10">
<div style="width: 20%" class="left">
<div class="resize" title="左右侧边栏">⋮</div>
<el-card :style="{height:treeHeight,overflow: 'auto'}">
left
</el-card>
</div>
<div style="width: 80%;" class="right">
<el-card :style="{height:treeHeight,overflow: 'auto'}">
right
</el-card>
</div>
</el-row>
</div>
</template>
<script>
// 左右拖动事件
function dragControllerLR () {
const resize = document.getElementsByClassName('resize') as any;
const left = document.getElementsByClassName('left') as any;
const right = document.getElementsByClassName('right') as any;
const box = document.getElementsByClassName('box') as any;
for (let i = 0; i < resize.length; i++) {
resize[i].onmousedown = function (e:any) {
// 颜色改变提醒
resize[i].style.background = '#818181';
const startX = e.clientX;
resize[i].left = resize[i].offsetLeft;
// 鼠标拖动事件
document.onmousemove = function (e) {
const endX = e.clientX;
let moveLen = resize[i].left + (endX - startX); // (endx-startx)=移动的距离。resize[0].left+移动的距离=左边区域最后的宽度
const maxT = box[0].clientWidth - resize[i].offsetWidth; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
if (moveLen < 50) moveLen = 50; // 左边区域的最小宽度为50px
if (moveLen > maxT - 150) moveLen = maxT - 150; // 右边区域最小宽度为150px
resize[i].style.left = moveLen; // 设置左侧区域的宽度
for (let j = 0; j < left.length; j++) {
left[j].style.width = moveLen + 'px';
right[0].style.width = box[0].clientWidth - moveLen + 'px';
}
};
// 鼠标松开事件
document.onmouseup = function (evt) {
// 颜色恢复
resize[i].style.background = '#d6d6d6';
document.onmousemove = null;
document.onmouseup = null;
resize[i].releaseCapture && resize[i].releaseCapture(); // 当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
};
resize[i].setCapture && resize[i].setCapture(); // 该函数在属于当前线程的指定窗口里设置鼠标捕获
};
};
}
// 在组件挂载完成后,调用dragControllerLR函数
onMounted(() => {
dragControllerLR();
});
</script>
<style scoped>
.box{
width: 100%;
}
/* 拖拽区div样式 */
.resize {
cursor: w-resize;
float: right;
position: relative;
top: 45%;
background-color: #d6d6d6;
border-radius: 5px;
margin-top: -10px;
width: 10px;
height: 50px;
background-size: cover;
background-position: center;
font-size: 32px;
color: white;
display: flex;
align-items: center;
justify-content: center;
}
</style>