近期项目上遇到的一些功能;字符串比对(diffjs)、打印功能(printJS)、两端布局中间可拖拽功能实现

(买了辆公路车,五一从北京出发骑行了一趟天津,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>
最后放上几张骑行时拍的照片
相关推荐
万物得其道者成几秒前
React Zustand状态管理库的使用
开发语言·javascript·ecmascript
小白小白从不日白1 分钟前
react hooks--useReducer
前端·javascript·react.js
下雪天的夏风14 分钟前
TS - tsconfig.json 和 tsconfig.node.json 的关系,如何在TS 中使用 JS 不报错
前端·javascript·typescript
青稞儿19 分钟前
面试题高频之token无感刷新(vue3+node.js)
vue.js·node.js
diygwcom25 分钟前
electron-updater实现electron全量版本更新
前端·javascript·electron
volodyan29 分钟前
electron react离线使用monaco-editor
javascript·react.js·electron
^^为欢几何^^37 分钟前
lodash中_.difference如何过滤数组
javascript·数据结构·算法
Hello-Mr.Wang42 分钟前
vue3中开发引导页的方法
开发语言·前端·javascript
程序员凡尘1 小时前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
编程零零七4 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql