class 与 await结合
class As { constructor() {} then(resolve, reject) { setTimeout(() => { resolve(true); }, 3000) } } (async () => { const b = await new As(); console.log(b); })()
fonts.less@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap'); .box { font-family: "Roboto"; }如果你再less文件中这么引入,那么一定是会报错的,这个报错要从两方面去理解:原生@import 语法被less占用less不支持在线css虽然less官方说如果你使用@import引入一个css文件,是会按照css原生语法去解析它的,但是它并没有说它支持一个在线链接,并且如果...
promise如果没有指定状态,那么就一直会处于pending中,如果长时间不处理,那么这个东西会一直存在于内存中,显然是不合理的。如果是一个超多请求项目,那么我们就需要考虑下性能问题了。promise中有一个rece方法,它接收一个promise作为值的数组,它的特性就是:哪个promise先执行,他就处理那一个,不管是resolve还是reject;在then中,他也只有一个值,不同于Promise.all方法返回的是一个数组,rece返回的值是最快完成的那个promise的返回值。利用这个特性,我们可以制作一个超时处理。function delayPromise(promise, ...
从uikit官方站点复制抽屉的代码本地运行,你会发现,它的抽屉默认居然是黑色的,根本不是官网上那种白色的样式。查询了好久,再github上issue上看到一些解释( OffCanvas only Dark),大概释义如下:官方的抽屉只有dark模式,不支持白色模式,也不支持反色的class(uk-light和uk-dark);而且官方对这个抽屉复写样式特别多,多到离谱,你能用上的元素,他都复写了,导致你就算把背景色复写成白色,你元素的字体颜色还是白色,而且nav组件的icon也被复写成白色svg了,这某种程度上复写样式基本无解了。唯一的解决办法就是不用官方的uk-offcanvas-ba...
找了很久,现有的库有两个:1. Mergenpm地址: Merge用法:import merge from 'merge'; const obj1 = { name: 2}; const obj2 = { value: 1 }; //合并 merge(obj1,obj2); console.log(obj1); //{name:2,value:1} //克隆合并-与目标对象无关联 const obj3 = merge(true,obj1,obj2); console.log(obj3); //{name:2,value:1} console.log(obj3...
有时候我们在vue中进行for循环,就会涉及到绑定唯一值key的问题,但是并不是任何时候都会存在所谓的唯一值,使用index下标明显是不合适的,官方也不推荐,除非你for循环出来的列表不用变化。所以一般常用的做法就是给for循环的对象添加一个属性,属性的值是随机的uuid或者时间戳。这样前端问题解决了,如果遍历的数据还需要提交到后端,那么不就多了一个属性,这个属性后端不需要的。所以,我们需要在提交数据前,对数据进行过滤。过滤又得for循环删除?那怎么行,有没有那种通用的,简单的方法。过滤方法/** * @description: 过滤对象中指定的属性,也可以拿来浅拷贝 * @para...
不允许循环引用的深拷贝function deepCopy(data) { const weakMap = new WeakMap(); function copy(data) { if (weakMap.has(data)) return null; //打断施法 const copyData = data instanceof Array ? [] : {}; weakMap.set(data, true); for (let [key, value] of Object.entries(data))...
前言js有一个31k多的star的开源复制库:clipboard.js;但是一些简单复制并不想安装一个库来解决,所以就想自己写一个。copy所需要的东西Selection 对象用于获取被用户选中的部分,通过toString()方法可以获取被选中的文本内容,以及js操作选中。MDN文档:SelectionexecCommand 对象用于以命令的形式来操作网页的内容,说白了就是用它来实现复制文本操作,复制的是选中的文本MDN文档:execCommand 需要注意的是,execCommand在未来将会被遗弃,因为这个api本身是从ie浏览器那边继承的,久而久之各大浏览器都对其做了兼容,虽然...
前言后端返回给前端的数据,有时候会是一个多层级对象,但是我们前端使用的时候,for循环遍历渲染时,多层级对象往往需要进行单独处理,因为还需要判断这个key值是否存在,否则会报错。强行让后端改变数据结构又好像不现实,无奈,只有自己处理了。掘金看到一位大佬文章《【算法】JS 实现对象的扁平化》感觉很合适,逻辑清晰。要求将对象中的层级扁平化,改成如下格式:// 实现一个 flatten 函数,实现如下的转换功能 const obj = { a: 1, b: [1, 2, { c: true }], c: { e: 2, f: 3 }, g: null, }; // 转换为 l...
预览图前言在刻度尺和辅助线的基础上增加键盘方向键事件,方便微调,毕竟鼠标拖拽浮动太大了。[hide]教程我们的逻辑是,用户点击图形选中,然后移动,因为我的图形都支持变形操作,所以我把键盘事件的监听放在了Transformer完成后触发。stage可以监听到click事件,所以也省去给每个图形添加。import Konva from "konva/lib/Core"; import { Rect } from "konva/lib/shapes/Rect"; import { Text } from "konva/lib/shapes/Te...
我们有两种方式获取,一种是new Date()得到时间对象,一种是Date函数对象静态方法获取。new Date()与Date的区别就是,前者是构造函数,后者是函数对象,函数对象返回的,只是我们需要的值,他不会有Date对象的内置方法(prototype),所以,它的使用更简洁明确,但是如果我们想要获取时间的年份,月份,星期几,那么new Date()才是最好的选择。new Date() 获取const date = new Date(); //没有传入参数获取当前本地时间 date.getTime(); //1626746413673 date.valueOf(); //1...
图形的加载在konva中,有两种方式加载图片,其原理都是需要加载图片dom,等图片完全加载完成再置入canvas中,官方的例子是这样的:var imageObj = new Image(); imageObj.onload = function() { var yoda = new Konva.Image({ x: 50, y: 50, image: imageObj, width: 106, height: 118 }); // add the shape to the layer layer.add(yoda); laye...
预览图前言之前出了刻度尺的教程,刻度尺有了,但是单一的存在功能并不直观,我们还需要辅助线功能,不多说,开搞[hide]教程添加辅助线逻辑稍微辅助一些,我们需要监听拖拽事件,但是如果监听每个图形的拖拽事件,那是非常不靠谱的想法,300个图形就有300个事件监听,显然不合理,好在konva的layer对象,是可以监听到所有可拖拽对象的拖拽事件的,我们不需要给每个图形添加,只需要监听layer即可。拖拽事件:dragstart 拖拽开始事件dragmove 拖拽中dragend 拖拽结束拖拽事件,我们可以通过event对象获取到被拖拽的目标图形:this.$layer.on("d...
预览图前言在使用konva库做图形拖拽的时候,你会发现konva没有提供刻度尺和辅助线的功能,导致你不知道你拖拽的实际坐标,这就很难受了,在谷歌百度查教程的时候,看见官方之前就给予过类似问题的回应。问题issues:How to add a ruler for konva官方回应(翻译):如果你需要这样的形状,就画画。作为文本 + 多行,或自定义形状(以获得更好的性能)既然搜索引擎和官方都没有类似的答案,我们就自己来。先搞定刻度尺问题。[hide]教程既然要画尺子,我们就要想怎么画,如果按照生活中的尺子,1cm一个竖线,我们1px一个竖线肯定是不行的,我的做法是,反正宽高很大,就5px一...
正常情况下,如果想让左侧黄色20px的元素右侧与父元素齐平,父元素100px,我们的算法是这样://100px - 20px transform: translateX(80px);x轴移动80px即可达到效果,但是如果我们同时使用scale放大,那么80px就不对了。transform:scale(2) translateX(80px);放大两倍后,你会发现平移的距离不对了。为什么?平移的距离明明就是70px啊!不着急,我们先看看不使用translateX平移,使用margin-left移动到与父元素右侧齐平再放大是什么样的。transform: scale(2); margin-le...
原理也没啥好藏着掖着的,就是为了保证密码难度,开头的字符一定是满足安全需要的,比如要求大小写数字加特殊字符,那么开头四位就一定是:大写一位、小写一位、数字一位、特殊字符一位;然后剩下的随机。/** * @description: 随机密码 * @param {*} len 密码位数 * @param {*} mode 密码难度:hide(大小写数字特殊字符)、medium(大小写数字)、low(小写数字) * @Date: 2021-07-02 15:52:32 * @Author: mulingyuer */ export const randomPass = functi...
使用canvas操作内容后,如果想保存图片之类的操作,就无可避免的要处理这一步,因为canvas导出的是base64格式的文件,如果你只做预览还好,存储的话,就要想办法了。我的想法是转成上传文件的那种file格式。方法如下:/** * @description: 将base64转换为文件对象 * @param {*} dataUrl base64 * @param {*} fileName 文件名 * @Date: 2021-06-30 14:33:47 * @Author: mulingyuer */ export function dataURLtoFile(dataUr...
预览图类源码/* * @Author: mulingyuer * @Date: 2021-06-21 11:29:12 * @LastEditTime: 2021-06-21 18:39:31 * @LastEditors: mulingyuer * @Description: canvas * @FilePath: \form-create\src\utils\canvas.js * 怎么可能会有bug!!! */ class Chart { constructor(options) { const defaultOptions = { el:...
本来是一个很简单的需求:const a = { b:1 }本来我的需求是判断,这个a对象里面b是否存在,但是b的值不确定,他可能是布尔值false,也可能是数字0,或者是空字符。那么if(a.b)就不太行了,一般来说,老前端一般都是用in 操作符。"b" in a; //true但是es6后,一般来说,不建议这样使用的,同时不建议的还有delete操作符。于是问了下群友,因为我记得es6有那么一个方法,可以判断一个对象的属性是否存在,并且不会去查prototype上的内容。但是我忘了啥名字来着!const a = { b:1 } a.hasOwnPrope...
目前前端最佳的方案其实有两种:a元素下载iframe 无闪下载事实上这两种下载方式,其实都存在相同的一个问题,就是如果下载的文件是跨域的(不是同域名下的问题,或者其他原因);并且这个文件浏览器可以直接打开的,比如:图片、文本文件。那么浏览器会直接打开文件,并不是触发下载,而如果下载的文件是安装包,压缩包zip这些,则是触发下载。这个问题就很头疼。a元素下载的缺点a元素下载,那么就必须设置download属性,这个属性可以接收一个参数,可以是带后缀的文件名,或者不带后缀。也可以为空,但是要设。不带后缀的话文件格式就会与下载的文件保持一致,如果带了格式后缀,可能导致下载的jpg文件,你设置为...
css3新增了三个伪类::required、:valid、:invalid:required 表示input不能为空时使用的:valid 表示通过,表单元素和form表单都有的伪类:invalid 表示不通过,表单元素和form表单都有的伪类其实如果要做一个表单css校验样式,:valid和:invalid就行了,但是实际操作上,:invalid还是有一些问题的。当表单元素有required属性的时候,该表单元素默认就是:invalid,也就说,必填的表单元素,一开始就是不通过。所以,如果此时设置:invalid伪类样式,是不合适的。解决办法就是:使用:placeholder-shown...
造这个轮子其实也是没得办法,搜不到合适的轮子用,就只能自己干了。使用场景我们有N个异步任务promise,他们没有顺序关系,谁先触发都无所谓,但是我们只关心一点,如果某一个任务出错,后续就不要运行了,只有全部都success完成,那么才运行成功后的处理方式then。当然,我们肯定不能使用Promise.all运行N个任务,这等于是同步触发了,如果我有2000个任务,难道你也一口气发2000个任务,那这就不现实了,所以这里我们要引入线程概念,一个进程可以有多个线程,那么进程就是管理器,线程就是我们一次可以发多少个请求。线程是可以配置的,我们可以指定触发多少个线程,当1个线程完成后,我们要填...
最近评论