el-table横向滚动条吸底处理方案思路

起因 工作中用到的 el-table显示大批量数据的时候,一页放不下,一般性的处理方案是限定了高,让表格固定表头之后内部可以滚动,不过因为实际操作中样式的问题,需要我把整个表格高度全部显示出来,这样就造成了一个问题,就是横向滚动不方便 不过作为mac用户已开始没啥感觉,但是被用windows的同事吐槽了好久,于是终于决定花半天时间解决 仓库 已开源,不想看的,可以直接看代码https://github.com/mizuka-wu/el-table-horizontal-scroll 或者安装npm i el-table-horizontal-scroll用指令的形式使用该项目 实现原理 其实是模拟了一个el-scroll进行同步,为了方便,制作成了一个指令 核心代码 通过Scroller类,创建一个scroller的dom,并插入到指令提供的el内部 el.appendChild(scroller.dom) 目标对象 const targetTableWrapperEl = el.querySelector('.el-table__body-wrapper') Scroller类 具体地址 主要负责了scroller的创建和管理,具体可以直接看代码 其模拟了一个el-scroll的dom结构(为了省的写样式) 大概会出现一个这样的dom结构 <!-- scroll/dom整个dom结构 --> <div class="el-scrollbar"> <!-- bar横条容器 --> <div class="'el-scrollbar__bar is-horizontal"> <!-- thumb滑块 --> <div class="el-scrollbar__thumb"></div> </div> </div> 然后整体就是对这个结构进行操作 例如,scroll的整体样式需要手动添加,让其可以自由浮动,然后显示在fixed列前,所以需要 scroller.style.height = '12px' scroller.style.position = 'fixed' scroller.style.bottom = 0 scroller.style.zIndex = 3 以及一些其他的调整,具体不再阐述 自动吸底原理 这个就是目前监听document的scroll事件,判断是否需要显示 核心判断代码就是判断el的底部是否出现在页面内 const viewHeight = window.innerHeight || document.documentElement.clientHeight const { bottom } = targetTableWrapperEl.getBoundingClientRect() // 当前的el-table的wrapper,可以在el内获取到 if (bottom <= viewHeight) { hideScroller() } else { showScroller() } 平时就position: fixed在页面底部,如果表格底部显示在页面里了,就自动隐藏即可 ...

July 9, 2019 · 2 min · 215 words · 水华

上传app卡在通过app store进行鉴定

cd ~ mv .itmstransporter/ .old_itmstransporter/ "/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/itms/bin/iTMSTransporter"

July 9, 2019 · 1 min · 7 words · 水华

如何删除除了Master之外的所有分支

如何删除除了Master之外的所有分支 切换到 master 删了其他的 git stash && git checkout master && git branch | grep -v "master" | xargs git branch -D

June 5, 2019 · 1 min · 22 words · 水华

一次node内存泄漏排查和解决

背景 公司需要对接各种渠道,进行渠道管理进行了统一规范,生成了 ChannelManager 这个类,上线后发现一直报警,内存居高不下,而且走势呈阶梯上升,判断发生了内存泄漏 技术栈 Nuxt 基于 nuxt 和 vue 开发的一套前端代码 nodejs 性能平台 alinode,一个 ali 官方出的用来监控整个 node 内存和机器运行情况的程序,非常好用,问题是数据有一定延时 解决的步骤 首先尝试临时解决问题 因为线上一共有四台机器跑 ssr,所以通过设置不同的 crontab 进行分批重启 pm2,使得服务不间断 下线问题的 feture 最近上线的 feture 只有 channelManager,于是回滚代码之后重新发布,发现问题解决,找到问题代码区域 CodeReview 开会大家回顾整个问题代码,分析之后发现可能的问题在于使用了 global 的 mixin,改成 Vue plugin 的形式使用,具体可以参考这个 issue 测试环境下发现问题依旧没有解决 验尸 对比了最近几次 alinode 抓下的堆快照,发现所有的闭包都是 vue 实例,而且都会有一个同样的 key$channelManager 找出问题所在 最终发现是上 channelManager 的时候在 nuxt 的 plugin 中使用了 inject,因为 inject 的时候是同一个实例,本身的目的是可以获取 channel 列表 module.exports = (ctx, inject) => { const ChannelManager = require('ChannelManager') inject('channelManager', ChannelManager) } 原因 在于 v8 的整个 gc 机制在于是否能够被访问到,因为 inject 之后不知道为何从 channelManager 能够访问到所有 inject 之后的 vue 实例,所以这一系列的 vue 对象都不可被回收 ...

June 1, 2019 · 1 min · 90 words · 水华

electron开机自动启动

直接 直接上 直接上代码 const exeName = path.basename(process.execPath) app.setLoginItemSettings({ openAtLogin: !openAtLogin, path: process.execPath, args: [ '--processStart', `"${exeName}"` ] }) }

February 11, 2019 · 1 min · 19 words · 水华

我们是怎么从ng迁移到vue的

我们是如何从ng1迁移ing到vue的 原本的技术栈 ng1 + gulp + slim + vue *2 + iframe 的一个后端管理项目 这是一个本身因为人手不足,一开始由后端同学创建的后端管理项目,基本采用了gulp + ng1来进行开发,同时前端接手之后为了方便开发以及跟上潮流,采用了新开子目录使用vue开发,nginx和iframe进行整合的方式,最后一个项目变成了三个项目,其实最开始进行开发的时候,连怎么启动都不知道😂 要解决的问题 项目的层级结构 原本的结构 顶级目录只包含多个子文件夹以及build.sh,每个子项目需要独立进行编译以及开发 新的结构 采用signle-spa作为入口文件解决方案,统一管理所有项目的入口文件,实现一次启动,所有项目都能一起开发以及编译,省去了来回切换以及端口冲突 构建语言的混乱 原本的架构 原本的app是使用ng1来进行编写js部分,slim来编写页面模版,同时使用gulp来完成遍历所有的js文件,并打包到一个js中,后来一些新的页面部分采用iframe引入另一个vue-cli项目,两者之间通过cookie来进行登录数据的共享。 更新之后的架构 因为模版文件的问题,仍然以gulp为主,webpack负责vue和原本app的js打包和资源文件的编译工作,大家约定好,原本的ng部分尽量不更新,新的采用vue进行编写 逐步过渡 原本的方案 老的不管它,需要更新就回去更新,新的需求去vue的项目中编写 现在的方案 single-spa进行页面的拆分,将需要更新的老的ng部分作为一个新的子app,拆分出来之后再进行更新,保证局部更新,不影响整体 解决过程 编译工具 确定了整体的迁移方案之后,就是首先对编译工具的改造了,最开始是想把gulp先替换成webpack的(因为习惯配置webpack了,以及webpack4 + babel7真的编译速度快了很多) 但是因为slim始终找不到适合使用的webpack插件的关系,最终决定还是保留gulp进行编译ng的相关的html文件 小问题 gulp支持webpack的问题 gulp-webpack插件支持的webpack版本是2,但是目标是使用4(为了快),好在webpack支持使用node来进行调用,只要在编译结束之后给gulp一个回调就可以了 const webpack = require('webpack') const fs = require('fs') module.exports = function (webpackConfig) { return new Promise((resolve, reject) => { const compiler = webpack(webpackConfig); compiler.run((err, stats) => { if (err) { console.error(err) reject(err) } // 输出 process.stdout.write(stats.toString({ // stats对象中保存着编译过程中的各种消息 colors: true, // 增加控制台颜色开关 modules: false, // 不增加内置模块信息 children: false, // 不增加子级信息 chunks: false, // 允许较少的输出 chunkModules: false // 不将内置模块的信息加到包信息 }) + '\n\n') }) compiler.hooks.afterEmit.tap('gulp', function() { resolve() }) }) } 同理,devServer也使用自定义的脚本, 当然因为公司原因,其中的api切换也直接放在devServer的before中 ...

January 3, 2019 · 2 min · 326 words · 水华

html上实现div按照宽高比自适应

html 上实现 div 按照宽高比自适应 原理很简单,padding 的百分比是根据宽度作为百分比自动设置的,所以容器上使用 .container { height: 0; padding-top: 114%; .data { width: 100%; height: 100%; } } 就可以了

November 25, 2018 · 1 min · 21 words · 水华

一段从js数组中获取重复数据的代码

Array.prototype.duplicate=function() { let tmp = []; this.concat().sort().sort(function(a,b){ if(a==b && tmp.indexOf(a) === -1) tmp.push(a); }); return tmp; }

October 18, 2018 · 1 min · 17 words · 水华

axios如何中断请求

axios 是一个非常方便的请求库,但是缺没有原生提供一个 abort 接口,因为 axios 的返回是一个 promise,我们可以利用 promise 的特性来实现一个 abort 方法 Promise.race promise.race 方法从字面意思上就是赛跑,其中只要有任意一个完成了,就返回完成的那个,有一个失败了,就改为失败,利用这个特性就能完成我们的 abort 方法 Promise.race([ // 等待取消组 new Promise((_resolve, reject) => { notify.onClose = function() { reject(new Error('手动停止导出!')) } }), // 获取数据组 axios.get() ) 当然,例子中利用了 element-ui 的 notify 组件,绑定了 notify 组件的 onClose 方法,实际上也可以通过封装对象的方式实现

October 15, 2018 · 1 min · 45 words · 水华

记不住快捷键怎么办

身为一个程序员怎么可以使用鼠标这么low的操作呢,但是快捷键就是记不住啊 Chectsheet 按住command键两秒钟,CheatSheet就会自动弹出来,告诉你当前程序的快捷键都有哪些。简直是神器啊 下载地址 点我下载

October 15, 2018 · 1 min · 5 words · 水华