Tag一下
- Alibaba Fusion Design
- 基于 React技术栈实现设计师与工程师的协作平台
基础库
sass/less
- sass相关变种说明: https://www.cnblogs.com/yyh1/p/15954139.html
- 目前sass官方主推的是 dart-sass
- sass 是由 ts调用 dart-sass实现的工具类,来编译 sass(以前是由单纯的 ts实现的)
- 只支持
::v-deep
- 只支持
- dart-sass 是由 dart 实现的,通过 dart vm 运行 dart 是编译 sass(在 npm 可以看到该包已不被开放下载了)
- node-sass 是由 node 调用 底层 c++ 实现的 libsass 来编译 sass
- 支持
/deep/
和::v-deep
- 支持
lodash工具类
- lodash、lodash中文网
- Math 数学计算,类似mathjs
add
、subtract
、multiply
、divide
两个数的加减乘除_.add(0.1, 0.2)
// 0.30000000000000004
- merge 可进行深度覆盖
1 | const a = {a: 1, b: {b1: 2}, c: [{c1: 3}]}; |
- groupBy
1 | // 多字段分组案例 |
xe-utils
- xe-utils
- merge
1 | const a = {a: 1, b: {b1: 2}, c: [{c1: 3}]}; |
cross-env启动时增加环境变量
1 | // 安装 |
dayjs时间操作
1 | import dayjs from 'dayjs' |
数学计算
js精度问题: https://www.cnblogs.com/xjnotxj/p/12639408.html
0.1 + 0.2 => 0.30000000000000004
使用 toFixed() 函数
四舍五入存在精度问题,存在问题toFixed必须设置精度(默认是整数)
1
2
3
4
5
6
7
8// 像 round()、floor()、ceil() 等都不能真正的四舍五入,有精度问题
parseFloat((0.10 + 0.25).toFixed(1)); // 0.3
Math.ceil(12.34); // 13 向上取整
Math.floor(12.34); // 12 向下取整
Math.round(12.34); // 12 四舍五入取整
Math.round(12.54); // 13 四舍五入取整
100.456001.toFixed(2); // 100.46
100.456001.toFixed(3); // 100.456toFixed优化方法(未进行全面测试)。参考:https://juejin.cn/post/7222475192932007992
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
52
53export const toFixed = (num, digits = 0) => {
let zeroStrNum = num.toString();
// 处理科学计算情况
if (zeroStrNum.includes('e')) {
const matchList = zeroStrNum.match(/\d(?:\.(\d*))?e([+-]\d+)/);
zeroStrNum = num.toFixed(Math.max(0, (matchList[1] || '').length) - Number(matchList[2]));
}
let isNegativeNum = false;
// 判断是否为负数
if (zeroStrNum.startsWith('-')) {
isNegativeNum = true;
zeroStrNum = zeroStrNum.slice(1);
}
// 获取小数点位置
const dotIndex = zeroStrNum.indexOf('.');
// 如果是整数/保留小数位数等于超过当前小数长度,则直接用toFixed返回
if (dotIndex === -1 || zeroStrNum.length - (dotIndex + 1) <= digits) {
return num.toFixed(digits);
}
// 找到需要进行四舍五入的部分
const numArr = (zeroStrNum.match(/\d/g) || []).slice(0, dotIndex + digits + 1);
// 核心处理逻辑
if (parseInt(numArr[numArr.length - 1], 10) > 4) {
// 如果最后一位大于4,则往前遍历+1
for (let i = numArr.length - 2; i >= 0; i -= 1) {
numArr[i] = String(parseInt(numArr[i], 10) + 1);
// 判断这位数字 +1 后会不会是 10
if (numArr[i] === '10') {
// 10的话处理一下变成 0,再次for循环,相当于给前面一个 +1
numArr[i] = '0';
} else {
// 小于10的话,就打断循环,进位成功
break;
}
}
}
// 将小数点加入数据
numArr.splice(dotIndex, 0, '.');
// 处理多余位数
numArr.pop();
// 如果事负数,添加负号
if (isNegativeNum) {
numArr.unshift('-');
}
return Number(numArr.join('')).toFixed(digits);
}
使用第三方库解决
- decimal.js 文件大小132K
- Math.js 文件大小1.74M
- big.js
- bignumber.js
银行家不使用四舍五入(存在1.05这个数会让银行亏钱),而是使用
四舍六入五取偶
。toFixed不能完全满足此近似算法,可使用第三方包bankers-rounding
规则:四舍六入五考虑,五后非空就进一,五后为空看奇偶,五前为偶应舍去,五前为奇要进一
1
2
3
4
5
69.8249=9.82
9.82671=9.83
9.8350=9.84
9.8351 =9.84
9.8250=9.82
9.82501=9.83
decimal.js
1 | Decimal.add(0.1, 0.2).toNumber() // 0.3 |
- mathjs
1 | npm install mathjs -S |
省市区级联
省市区数据
- “省份、城市、区县” 三级联动数据 pca-code.json
- 支付宝小程序提供Excel(名称不带省市两个字): https://opendocs.alipay.com/isv/10327
- 2020年7月中华人民共和国县以上行政区划代码: http://www.mca.gov.cn/article/sj/xzqh/2020/2020/20200908007001.html
腾讯地图提供接口和Excel简易版: https://lbs.qq.com/service/webService/webServiceGuide/webServiceDistrict
- Excel存在问题:如海南省-儋州市-xxx镇不会显示,海南省-省直辖县级行政区划-五指山市等不会显示
- 接口如访问(需要从上述lbs.qq.com网页进行点击访问):https://apis.map.qq.com/ws/district/v1/list?key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77 只能通过城市代码区分父子关系,带经纬度
基于简易版Excel进行处理
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-- 1.创建表sys_city_code
CREATE TABLE `sys_city_code` (
`id` int NOT NULL,
`province_name` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '',
`province_code` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`city_name` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '',
`city_code` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`area_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT '',
`area_code` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`type` smallint DEFAULT NULL,
PRIMARY KEY (`id`)
);
-- 2.通过Navicat导入Excel创建临时表sys_city_code_tmp
-- 3.插入数据
insert into sys_city_code
select
(@i:=@i+1) id
,if(substring_index(t.name, ',', 1) != '', substring_index(t.name, ',', 1), replace(substring_index(t.name, ',', 2), ',', '')) province_name
,concat(substring(t.adcode, 1, 2), '0000') province_code
,substring_index(substring_index(t.name, ',', 2), ',', -1) city_name
,concat(substring(t.adcode, 1, 4), '00') city_code
,substring_index(t.name, ',', -1) area_name
,t.adcode area_code
,case when concat(substring(t.adcode, 1, 2), '0000') = t.adcode then 1 when concat(substring(t.adcode, 1, 4), '00') = t.adcode then 2 else 3 end type
from (select adcode, replace(name,'中国,','') name from sys_city_code_tmp) t
,(select @i:=0) j;
--4.作废临时表
drop table sys_city_code_tmp;
vue-area-linkage 省市区选择器(需结合省市区数据)
- area-puppeteer 省市区数据
AJAX
axios
- 参考springboot-vue.md#文件上传下载案例
- axios基本使用
1 | axios.get("/hello?id=1").then(response => { |
axios参数后端接受不到 ^2
get请求传递数组
1
2
3
4
5
6
7
8
9
10
11let vm = this
this.$axios.get("/hello", {
params: {
typeCodes: ["CustomerSource", "VisitLevelCode"]
},
paramsSerializer: function(params) {
return vm.$qs.stringify(params, {arrayFormat: 'repeat'}) // 此时this并不是vue对象
}
}).then(response => {
console.log(response.data)
});post请求无法接收
- 使用
qs
插件(推荐,会自动设置请求头为application/x-www-form-urlencoded
) axios
使用x-www-form-urlencoded
请求,参数应该写到param
中1
2
3
4
5
6
7
8
9
10
11
12
13axios({
method: 'post', // 同jquery中的type
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
url: 'http://localhost:8080/api/login',
params: {
username: 'smalle',
password: 'smalle'
}
}).then((res)=>{
})- axios的params和data两者关系
- params是添加到url的请求字符串中的,一般用于GET请求
- data是添加到请求体body中的,用于POST请求。Spring中可在通过
getUser(@RequestBody User user)
获取body中的数据,从request对象中只能以流的形式获取 - 如果POST请求参数写在
data
中,加headers: {'Content-Type': 'application/x-www-form-urlencoded'}
也无法直接获取,必须通过@RequestBody)
- jquery在执行post请求时,会设置Content-Type为application/x-www-form-urlencoded,且会把data中的数据以url序列化的方式进行传递,所以服务器能够正确解析
- 使用原生ajax(axios请求)时,如果不显示的设置Content-Type,那么默认是text/plain,这时服务器就不知道怎么解析数据了,所以才只能通过获取原始数据流的方式来进行解析请求数据
- SpringSecurity登录必须使用POST
- axios的params和data两者关系
- 使用
qs插件使用
- qs插件会自动设置请求头为
application/x-www-form-urlencoded
1 | // 安装:npm install qs -D |
UI库
富文本编辑器
Tinymce
Vue相关UI库
AntDesign
- https://www.antdv.com/components/overview-cn
- 蚂蚁开源,支持React/Vue/Angular等,支持移动端
ElementUI
- 主题/配色
- 表单同步验证
1 | let pass = true |
- 远程搜索数据回显
1 | <span v-if="!shipBill.payerCodShow">{{ shipBill.payerNam }} <Icon type="ios-create" @click="() => shipBill.payerCodShow = true"/></span> |
- el-drawer
- 防止整个页面被遮住。modal-append-to-body的使用:遮罩层是否插入至 body 元素上,若为 false,则遮罩层会插入至 Drawer 的父元素上
1 | <template> |
- z-index
- 如果没有初始化,也没在use时给定z-index,则默认2000
vxe-table
- 一款基于Vue的表格插件,支持大量数据渲染,编辑表格等功能
- github
- doc
- 历史文档 根据vxe-table版本发布日期查找提交记录,然后查看对应时间区间的文档源码
- 优点
- 大数据表格
- 自带打印功能:区域、分页、模板、样式等打印功能
- 说明
- vxe-table 只能用于静态列(vxe-table-column,避免使用 v-for 去动态修改,如果要动态列其使用 v-grid)
- vxe-grid 支持一切动态场景
- grid 继承 table 100%的功能,vxe-grid 的性能也比 vxe-table 快一倍
- vue 多数情况还是推荐使用语义化标签的形式;而对于动态场景用 grid 就更加灵活,可以实现远程配置化一体化
- 表格显示/隐藏后样式丢失问题,弹框表格列宽问题
auto-resize
或sync-resize
绑定指定的变量来触发重新计算表格。参考:https://xuliangzhan_admin.gitee.io/vxe-table/#/table/advanced/tabs
- 和iview等组件结合使用时,modal等z-index存在冲突(如表格列过长提示),建议弹框和弹框中涉及z-index的元素使用同一组件,如全部使用vxe-table
- table对应属性
1 | "row"(当前选中或取消选中行), |
- column对应属性
1 | ['type', 'property'(字段代码), 'field'(字段代码), 'title'(列显示), 'width', 'minWidth', 'maxWidth', 'resizable', 'fixed', 'align', 'headerAlign', 'footerAlign', 'showOverflow', 'showHeaderOverflow', 'showFooterOverflow', 'className', 'headerClassName', 'footerClassName', 'formatter', 'sortable', 'sortBy', 'sortType', 'sortMethod', 'remoteSort', 'filters', 'filterMultiple', 'filterMethod', 'filterResetMethod', 'filterRecoverMethod', 'filterRender', 'treeNode', 'cellType', 'cellRender', 'editRender', 'contentRender', 'exportMethod', 'footerExportMethod', 'titleHelp', 'titlePrefix', 'params', 'id', 'parentId', 'visible', 'halfVisible', 'defaultVisible', 'checked', 'halfChecked', 'disabled', 'level', 'rowSpan', 'colSpan', 'order', 'sortTime', 'renderWidth', 'renderHeight', 'resizeWidth', 'renderLeft', 'renderArgs', 'model', 'renderHeader', 'renderCell', 'renderFooter', 'renderData', 'slots'] |
- 多选 + 修改页面表格数据(仅修改页面数据)。选中事件方法和选中所有事件方法是两个方法
1 | // tableSourceData |
- 监听行的选中事件
1 | // <vxe-table @checkbox-change="checkboxChange"> |
表格筛选
通过设置 filters 属性和 filter-method 方法可以开启列筛选功能,通过 filter-multiple=false 设置为单选
filters不支持动态修改筛选配置,可通过setFilter方法
1
2
3
4this.hobbyOpts = XEUtils.orderBy(XEUtils.uniq(this.listData.map(x => x.hobby))).map(x => {
return {label: x, value: x}
})
this.$refs.userTable.setFilter('hobby', this.hobbyOpts)
如果是服务端筛选,只需加上 filter-config={remote: true} 和 filter-change 事件就可以实现
- 本地筛选和服务端筛选不能同时使用,会优先触发filter-change,而不触发filter-method
- 可编辑表格、滚动分页
1 | <!-- |
- vxe-grid
1 | <!-- toolbar-config: 工具栏,开启字段自定义、打印、导出;custom-config:字段自定义配置,此时将自定义字段保存到localStorage,否则每次刷新会重置(需要定义全局唯一ID,整个项目全部保存在名为VXE_TABLE_CUSTOM_COLUMN_VISIBLE的localStorage中) --> |
- 打印,参考
1 | import VXETable from 'vxe-table' |
arco
- https://arco.design/
- 字节跳动开源,支持React和Vue,有对应移动端版本
iview
- 参考iview.md
Avue
- 官网
- 内置函数(全局API,在vue组件中可直接使用this调用)
validatenull
校验是否为空(null/''/0/[]/{}
)findObject
从数组中查找对象- 如
const saleNoObj = this.findObject(this.crudOptionData.column | this.formColumn, 'saleNo'); saleNoObj.disabled = true;
找到对象属性配置后,并修改(动态修改属性需要有默认值,即此时必须提前设置disabled=null属性,否则vue无法动态监测新增的属性进行双向绑定)
- 如
vaildData
验证表达式/属性- 如
this.vaildData(this.permission.party_permission_add, false)
默认根据第一个参数值进行判断,否则取第二个参数为默认值
- 如
$Print
$Clipboard
$Log
控制台彩色日志$NProgress
$Screenshot
deepClone
对象/数组深拷贝dataURLtoFile
isJson
setPx
设置css像素sortArrys
findArray
downFile
loadScript
加载js/css文件watermark
asyncValidator
- 内置指令
v-dialogdrag
作用于dialog,可进行拖拽
- 获取ref
- 在crud组件中
const avatarRef = this.$refs.crud.getPropRef('avatar')
可获取到表单的avatar图片上传组件元素ref,从而使用avatarRef.$refs.temp.handleSuccess
进行调用(temp是由于中间动态判断了表单元素) - 获取crud弹框表单中的element form引用:
this.$refs.crud.$refs.dialogForm.$refs.tableForm.$refs.form
- 在crud组件中
表格组件常用参数(option)
1 | { |
常见问题
- 可编辑表格点击新增后还是弹框显示
- 可编辑表格需要设置
cellBtn=true
,需要编辑的字段需要设置cell=true
,并且需要设置addBtn=false
(这是普通表格的新增)和addRowBtn=true
(可编辑表格的新增)
- 可编辑表格需要设置
- change事件进入两遍(Bug v2.8.26),解决如下
1 | column: [ |
原理介绍
- 目录结构
1 | packages # 实际重写组件目录 |
- packages/element-ui/upload/index.vue
1 | <template> |
- 混入功能举例说明
1 | // packages/core/common/props.js |
ag-grid超强表格
MyUI
- MyUI
- 包含基础组件、图表、地图、关系图、大屏等功能
- 内置了百度、高德
- 支持与ECharts结合实现散点、飞行迁徙等基于地理位置的图表
Quasar
Quasar
:基于Vue的UI框架,可以整合Cordova
开发移动App,也可以整合Electron
开发桌面程序- 常用习惯
Ripple
可以使按钮展示出波纹,不使用此波纹则需要去掉quasar.conf.js
-directives
中的Ripple
项
Select下拉
- 常用功能
- 自定义前台搜索
- 远程搜索
- 自定义选项模板(value和label字段可自定义)
- 选中返回item对象
- 可多选
- 可清除
- 可transfer到body
- Vue-multiselect
- 缺点
- 单选不能清除
- 缺点
- multiple-select
- 支持选项横向排列
- 缺点
- 网站速度慢,没细测试
- Vue Treeselect
- 支持大数据量
- 缺点
- value和label字段无法自定义,必须后台返回字段名为id来代表value
- vue-tree
- Vue multi select
- 支持选项tab分页功能
底层硬件库
Clipboard 复制内容到剪贴板
- 必须要绑定Dom
- 必须要触发点击事件(触发其他Dom的点击事件,然后js触发目的dom的点击事件也可)
扫码/条码生成
H5页面扫码
- 在微信浏览器打开H5页面,可引入微信的js SDK解决(需域名和微信公众号绑定)
- 在系统浏览器打开H5页面
- 基于jsQR、vue-qrcode-reader(本质基于jsQR)
- 调取摄像头(进行录像)识别二维码,每个页面需要同意调用摄像头(网页可设置永久同意)
- 优点是无需拍照确认识别(会自动识别,出错率低),但是必须要https才行
- 基于jsqrcode库,可进行二维码/条形码解析,可生成条形码
- 参考:https://www.cnblogs.com/yisuowushinian/p/5145262.html,此方案在前端 js 解析二维码,依赖
jsqrcode
- 这个库已经支持在浏览器端呼起摄像头的操作了,但是依赖一个叫
getUserMedia
的属性,该属性移动端的浏览器支持的都不是很好,低版本只能间接的上传图片的方式解析二维码 - 此插件需要配合 zepto.js 或者 jQuery.js 使用(主要用来拍照的,如果使用uni-app则不需要此依赖,可使用uni.chooseImage拍照);webpack打包需要canvas
- 安装
cnpm install jsqrcode -S
、cnpm install canvas -S
- 安装
- 扫码时无扫码框,需要点击拍照 - 确定识别(iphone7扫二维码成功,条形码不成功)
- 缺点需要确认拍照进行识别,拍照需要清晰,出错率高
- 参考:https://www.cnblogs.com/yisuowushinian/p/5145262.html,此方案在前端 js 解析二维码,依赖
- 基于
quagga.js
库,可进行条形码解析- 如uni-app插件:https://ext.dcloud.net.cn/plugin?id=1619
- 基于jsQR、vue-qrcode-reader(本质基于jsQR)
H5页面扫码案例(基于uni-app)
- 扫码流程
- 通过微信浏览器访问的,默认调用微信扫码。需要引入
weixin-js-sdk
- 通过手机普通浏览器访问的,如果是https模式访问,则调用摄像头录像扫码,需引入
vue-qrcode-reader
- 如果是普通浏览器访问,且以http默认访问,则调用拍照扫码,需引入
jsqrcode
和canvas
- 通过微信浏览器访问的,默认调用微信扫码。需要引入
- scan.vue
1 | <template> |
- wechat.js
1 | // #ifdef H5 |
- 调用
1 | <template> |
条码生成
- 相关插件
jsqrcode
可生成二维码jsbarcode
可生成条形码- 对应的vue插件
打印
常见打印纸大小(宽mm*高mm,可在wps中查看):A1 = {841,594}, A2 = {420,594}, A3 = {420,297}, A4 = {210,297}, A5 = {210,148}, A6 = {105,148}, A7 = {105,74}, A8 = {52,74}, B1 = {1e3,707}, B2 = {500,707}, B3 = {500,353}, B4 = {250,353}, B5 = {250,176}, B6 = {125,176}, B7 = {125,88}, B8 = {62,88} ^3
- web打印问题(分页问题等)
- 可使用
page-break-after
等css参数解决,如<div style="page-break-after: auto | always"></div>
。参考:https://www.w3school.com.cn/cssref/index.asp#print- 如果分页无效可考虑将div的高度直接设置成一页纸的高度,如
div {height: 297mm}
- 如果分页无效可考虑将div的高度直接设置成一页纸的高度,如
- 修改默认打印边距
@page {margin: 24px 18px 0 18px;}
,或者在chrome打印预览时通过自带界面修改 - 修改纸张方向
@page {size: portrait | landscape;}
,其中portrait纵向、landscape横向,设置后则无法在预览页面修改。谷歌支持,火狐85.0还不支持 - 至于mm和px换算
- 公制长度单位与屏幕分辨率进行换算时,必须用到一个DPI(Dot Per Inch, 像素/英寸)指标。网页打印中,默认采用的是96dpi(像素/英寸),而非72dpi
- A4为 210mm*297mm,而1英寸=25.41mm,浏览器默认为96dpi(像素/英寸),因此对应像素为 794px*1123px
- 此处A4,打印页边距设定为 0mm 时,网页内最大元素的分辨率794×1123
- 可设置div高度为297mm,然后通过js获取div.clientHeight得出像素高度
- 通过高度计算时,一般结合div的clientHeight进行计算,还需考虑页面边距。通过 1123px 等像素和手动计算高度分页,总是存在误差,效果不好
- 如果元素未
display: none;
则不会显示在打印界面 - table打印问题(参考下文案例)
- table包含thead、tfoot(写在tbody上面)、tbody
- 如果一个表格太长,会自动分页,则thead和tfoot会在每一页出现(有说需额外设置
display: table-header-group
,实测无需) - 如果不希望thead重复出现,可将表头行写到tbody中
- 当table分页后,没一页会自动出现一个分页横线,暂未找到简单方法去掉。可通过增加
<tfoot></tfoot>
(里面不要有数据,否则可能会出现tfoot边框无法去掉,有时候也不管用),来占位,并设置小page边距 - 当有多个小table时,需要自动判断一页显示的table个数。如vue,先渲染出页面,再计算每个table的高度,当超过一定高度,则增加一个
<div style="page-break-after: always"></div>
使其自动分页
- 可使用
- 基于lodop打印控件
基于hiprint插件
- 特点:基于Jquery;可视化配置模板(数据基于字段名自动填充),自动分页打印;可免费使用
- 缺点:源代码没开源,没有抽离 npm 包。github打包代码
基于vue使用参考:https://blog.csdn.net/byc233518/article/details/107705278
1
2
3
4
5
6// 修改源码
var hiprint = function (t) {
export const hiprint = function (t) {
if (this._android && this._android <= 2.1) {
if (this && this._android && this._android <= 2.1) {打印后关闭页面(监听事件)
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// 方法一:只有在引入socket.io.js才生效
hiprintTemplate.on('printSuccess', () => {})
hiprintTemplate.on('printError', () => {})
// 方法二 (vue案例)
this.printTemplate(this.printData)
this.addPrintEvent(() => {
window.close()
})
// 定义
addPrintEvent(afterPrintEvent, beforePrintEvent) {
// setTimeout 等待hiwprint_iframe加入到body中
setTimeout(() => {
// hiprintTemplate.print 最终是基于 jquery.hiwprint.js 虚拟出一个 iframe 进行打印的
let contentWindow = window.frames['hiwprint_iframe'].contentWindow
let beforePrint = () => {
beforePrintEvent && beforePrintEvent()
}
let afterPrint = () => {
afterPrintEvent && afterPrintEvent()
}
if (contentWindow.matchMedia) {
var mediaQueryList = contentWindow.matchMedia('print')
mediaQueryList.addListener(function (mql) {
if (mql.matches) {
beforePrint()
} else {
afterPrint()
}
})
}
contentWindow.onbeforeprint = beforePrint
contentWindow.onafterprint = afterPrint
}, 0)
}
基于print-js
- 使用vxe-table等插件自带打印功能
- 自定义js参考
1 | /* |
- 监听打印前后事件
1 | var beforePrint = function() { |
- vue和electron打印问题
1 | // 方案一(原生API,不推荐):VUE和electron中均可正常局部打印,只不过打印完主界面会刷新。且使用<div style="page-break-after:always"></div>强制分页也存在问题 |
- table打印案例
1 | <div class="sq-print"> |
生成PDF
1 | // 建议局部导入,此处仅做参考 |
- 自定义
jspdf.js
1 | // 导出页面为PDF格式 |
生成ZIP文件
- 安装
1 | npm install jszip -S |
- 使用参考生成PDF
网页保存为图片
- html2canvas、使用参考:https://segmentfault.com/a/1190000011478657
- html2canvas操作隐藏元素
<div style="position: absolute; opacity: 0.0;">
- Failed to execute ‘createPattern’ on ‘CanvasRenderingContext2D’: The image argument is a canvas element with a width or height of 0.
- 参考 https://stackoverflow.com/questions/20605269/screenshot-of-hidden-div-using-html2canvas
录屏
- 参考: https://www.cnblogs.com/houxianzhou/p/15554622.html
- 参考: https://zhuanlan.zhihu.com/p/584484268
- 可在控制台进行测试(支持js调用chrome录屏功能)
1 | const body = document.body; |
其他
mockjs模拟数据
- 语法
Mock.mock(rurl, rtype, function(options))
- rurl:拦截的请求地址,支持正则。不使用正则是为完全不配,如
/user/getMenu
无法匹配http://localhost/user/getMenu
,也无法匹配参数/user/getMenu?type=0
- rtype:请求类型,get/post等
- 回调函数,需要返回最终结果(相当于模拟后台请求返回)。options(url: 包括请求传参数、type: GET/POST等、body: body体参数)
- rurl:拦截的请求地址,支持正则。不使用正则是为完全不配,如
- 示例
1 | import Mock from 'mockjs' |
docz项目文档生成
codemirror代码编辑
- codemirror
- 参考
- vue使用,安装
npm install vue-codemirror --save
(会自动安装codemirror)
1 | <div> |
JS直接基于HTML导出CSV和EXCEL
- 使用JS将Table数据导出到Excel里(第二种):https://blog.csdn.net/qq_35340913/article/details/102590714
- js将表格html-table导出为CSV文件并下载(存在逗号转义问题):https://blog.csdn.net/djk8888/article/details/120848912
工具函数
防抖和节流
- 防抖debounce:某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次
- 节流throttle
- 首节流:第一次会马上执行,之后的操作不一定会执行。可以理解问第一次执行,最后一次不执行
- 尾节流:第一次不会马上执行,而是一段时间后在执行。可以理解为第一次不执行,最后一次执行
- 兼顾型节流:第一次会马上执行,最后一次也会执行
- 参考: https://blog.csdn.net/TomNumber/article/details/125411679
- 基于lodash
- 其提供的throttle和debounce仍会出现重复点击按钮,还是会多次执行,只不过多次执行有几秒的间隔
- 下文自定义的throttle方法无此问题,在2s内重复点击只执行一次
1 | import _ from 'lodash' |
- 手动实现参考(异步)
1 | // 兼顾型节流 |
- 手动实现参考(同步):https://www.jb51.net/article/212746.htm
1 | // 防抖 |
移动端
- vConsole 腾讯开源网页调试工具(即小程序调试工具)
参考文章