
前端杂谈
文章平均质量分 54
元无心
2023年尽量不摆烂
展开
-
axios 下载图片和 JSON 出现乱码的可能解决办法
用 axios 下载文件已经是个老生常谈的话题了,但是仍然还是会有一些小坑。本文简单说说使用 axios 下载图片和 JSON 出现乱码时可能的解决办法。没有正确设置 responseType,需要在请求头中正确设置 responseType。构造 Blob 时没有指定正确的 type。通常服务端会返回二进制流,如何正确接受二进制流是个问题。直接贴代码吧,这段代码的通用性会稍好一些,只不过使用了 ES6 以后的语法,需要处理:const {data: imageBlob, headers} =原创 2021-12-29 17:27:27 · 1635 阅读 · 0 评论 -
从418 I‘m a teapot想到的
下午不知道咋回事就想到了这个状态码,突然好奇有没有人用,就简单了解了一下它的来历,以及思考了一下它的使用场景。事实上,418甚至都不算是一个HTTP的状态码。它来源于当年的一个愚人节玩笑,所谓的“超文本咖啡壶控制协议”,Hyper Text Coffee Pot Control Protocol。在这个协议里规定了两种错误状态码,一种是406 not acceptable(当然,含义与HTTP的不同),另一种就是这次的418 I’m a teapot,表示服务器是一个茶壶,不能煮咖啡。这当然是一个玩笑原创 2021-07-20 19:25:08 · 4999 阅读 · 1 评论 -
package.json中版本号前面~和^的区别
指定版本:比如1.2.2,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。波浪号(tilde):比如~1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号。插入号(caret):比如ˆ1.2.2,表示安装1.x.x的最新版本(不低于1.2.2),但是不安装2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来.转载 2020-09-28 19:47:29 · 4553 阅读 · 1 评论 -
前端做题家之JavaScript
最近精神状态不太好,没心思写博客。前段时间听说了牛客网,看到上面全是面试题,虽然并不打算找工作,但是做题家的属性觉醒了,就每天做点题玩一玩。虽然我一直自诩“语言律师”,但是看到这些刁钻的面试题,还是有点应付不过来……不过,今天已经把JS的技能值刷满了,稍微有点心得,想了想觉得还是写个博客,摘录一些我觉得比较有意思的题目。名义上是JS的题目,其实并不完全是,还是有一些别的领域的内容。如果不给cookie设置过期时间会怎么样?会在浏览器会话结束时过期。事实上,我还真没试过……不过我倒是想到了sess原创 2020-09-27 20:32:08 · 449 阅读 · 0 评论 -
关于JavaScript中new运算符的一些理解
最近看到一道很有意思的面试题,问输出是多少:var name = "global";var obj = { name: "local", foo: function () { this.name = "foo"; }.bind(window)};var bar = new obj.foo();setTimeout(function () { console.log(window.name);}, 0);console.log(bar.name);var bar3 =原创 2020-09-09 22:09:41 · 305 阅读 · 0 评论 -
精读ECMAScript规范:全局对象
今天看到一个很有意思的问题:setTimeout是不是全局函数?这个问题,我第一反应是“是”,因为setTimeout是挂在window对象的一个方法(也就是window.setTimeout),而window是浏览器环境下的全局对象,所以setTimeout显然是全局函数。但是也有人说不是,因为方法(methods)和函数(functions)是两码事,全局函数应该是不通过任何对象即可调用的,而setTimeout是隐式的window.setTimeout调用。从这个角度来说,setTimeout应该原创 2020-09-09 20:07:29 · 390 阅读 · 0 评论 -
关于前端代码结构的一些思考
过了两天重新再读,有点语无伦次;不过确实我的真情实感。有一段时间没写博客了,简单谈谈最近对代码结构的一些思考。事实上,我总觉得这些问题有一点共性,但也并没有做过实证研究,所以也仅仅是我个人的感想罢了。两年之前接到第一个项目的时候,当时啥也不知道,就一通乱写,把所有的代码都放在一个包里;似乎把所有的代码都放在同一个包里会让人更有安全感。那个时候也不知道为啥,对模块化有一种奇怪的抵触,好像把代码分割之后就会失去对它的控制。一年多之前学软工二,那是我最沉迷OOP的时期。意识到模块化的好处之后,我急于将所有原创 2020-09-02 23:00:45 · 855 阅读 · 0 评论 -
记一次前端无法关闭的排障过程
晚上喝了半瓶酒,然后洗了个澡,正在贴地飞行的时候,被隔壁给拽到了地面上:他的前端关不掉了。我说怎么可能呢,啥症状?他说他把前端部署到80端口了,然后无论怎么搞都关不掉,重启了也没用。我说你看看80端口的进程,然后他熟练打出了netstat -ano | findstr 80,结果啥都没有……按理来说这时候就应该意识到问题所在了,但我不太清醒,就随口说了一句,那你把node杀掉呗。然后他找了半天,也没有node……我意识到不对了,我赶紧问他,你这不是dev模式?他说是在本地启了一个nginx,然后把打包原创 2020-08-19 19:48:45 · 522 阅读 · 0 评论 -
YAML速成个人翻译
学习circle-ci的用法时,无意中在网上看到了这个教程,拜读英文版之后觉得实在不错,就动了翻译的心思。可惜的是,已经有了中文翻译。不过这个翻译让人实在不满意,于是我重新翻译了一遍,希望能像YAML一样,“让人类可写可读”。2020.07.27于家中YAML 是一种数据序列化语言,旨在让人类直接可写可读。它是 JSON 的严格超集,增加了在语法上有意义的(syntactically significant,参见译注1)换行符和缩进,就像Python一样。但和Python的不同之处在于,YAML不翻译 2020-07-27 22:31:02 · 650 阅读 · 0 评论 -
vue-router URL里存在锚点导致不能再次跳转的可能解决办法
有时候我们会碰到这么一个场景:我们可能希望点击页面上的某个按钮,然后就会滚动到页面的某一块上,也就是所谓的“滚动到锚点”的功能。这个其实很好实现,vue-router的官方文档里已经给出了写法:const router = new VueRouter({ routes: [...], scrollBehavior (to, from, savedPosition) { if (to.hash) { return { selector: to.hash原创 2020-07-19 18:12:55 · 2590 阅读 · 5 评论 -
deno报错error trying to connect: invalid dnsname的可能解决办法
最近比较喜欢用deno去运行ts代码,总感觉比ts-node利索。但是deno有个小问题,如果不用代理,因为deno的release是发布在aws上的,而且由于众所周知的原因,国内无法访问aws;而如果使用代理,就会一直报错:error: error sending request for url (https://github.com/denoland/deno/releases/latest): error trying to connect: invalid dnsname查了一下,有老外说把代原创 2020-07-18 19:42:04 · 2181 阅读 · 4 评论 -
在VuePress中添加Gitalk评论
本来博客是没有评论功能的,后来经imwxz提醒,觉得还是搞个评论区比较好,就花了几个小时弄了一下。中间遇到一些小问题,就稍微记录一下。在此之前,要先创建一个GitHub Application。里面Homepage URL和Authorization callback URL写上博客的域名,别的随便写。比如我的是这样:需要注意两点:域名结尾的/要加上,否则在后面使用时可能会出现重定向错误。在这里填的域名是博客的直接域名,否则在后面使用时也可能会出现重定向错误。啥意思呢,比如我的博客是基于原创 2020-06-25 17:43:14 · 1013 阅读 · 2 评论 -
每天一个被拒小技巧——BigInt
LeetCode 67题题解。想必经典的模拟加法大家都会,所以看到这题的时候,我就知道一定会有人用BigInt;果然如此。但是那位并没有解释BigInt的相关内容,只是给出了答案,所以这里主要是介绍一下BigInt的内容。先来看写法:function addBinary(a: string, b: string): string { return (BigInt("0b" + a) + BigInt("0b" + b)).toString(2);}关于这个写法,可能存在三个疑问:为什么.原创 2020-06-23 17:57:45 · 894 阅读 · 0 评论 -
从爬楼梯简单谈谈执行性能
爬楼梯这个问题,其实思路是很明确的:爬到当前楼梯的方法数 = 爬到上一级楼梯(然后再爬一级,只有这一种选择)的方法数 + 爬到上两级楼梯(然后再爬两级,只有这一种选择)的方法数,也就是:f(x)=f(x−1)+f(x−2)f(x)=f(x-1)+f(x-2)f(x)=f(x−1)+f(x−2)这个其实是老生常谈了,它其实就是著名的斐波那契数列,可以循环或者递归求解,也可以用dp来剪枝,然后进一步对dp的数组进行优化(所谓的滚动数组),乃至矩阵快速幂、通项公式,或者更极端的直接打表(如果指定范围的话)原创 2020-06-13 11:13:58 · 277 阅读 · 0 评论 -
VSCode配置Code Runner + Deno直接运行ts代码
最近LeetCode的一些题目开始支持ts了,所以我就开始用ts做一些题目。事实上现在vscode对ts的支持已经相当不错了,包括语法高亮啥的。但是无论是什么编辑器(包括我最爱的WebStorm),都不能直接运行ts代码,这给本地调试带来了很大的不便。应该很多人知道vscode有个叫code runner的插件,可以很方便地去运行代码,然后他给的办法是去装一个ts-node的npm包,但我觉得没啥意思。正好一直听说deno的1.0版本已经发布了,能够直接运行ts代码,就索性装个deno,然后配置一下cod原创 2020-06-12 11:13:42 · 2323 阅读 · 1 评论 -
精读ECMAScript规范:截断
之所以要写这个,是因为之前遇到了一个老生常谈的问题:如何在JS中实现截断,也就是向0取整,也就是保留数字的整数部分?JS使用的是基于IEEE 754的浮点数,这个大家都知道。IEEE 754所带来的浮点数精度问题(比如著名的0.1 + 0.2 != 0.3,==还是===都是一样的,因为都是number),以及大整数的误差问题(比如著名的2**53+1 == 2**53),我们也都很清楚。关于这些问题,ES6以后提供了类似于Number.EPSILON、BigInt等一系列特性去解决这些问题,就不在这里赘原创 2020-05-29 10:26:16 · 464 阅读 · 0 评论 -
ESLint + TypeScript配置全局变量
其实ESLint + TypeScript的组合还是挺香的,代码风格检查 + 类型检查,能省下不少时间。但是还是存在一些问题。比如,有时候为了减小打包大小,我们可能会选择把一些不太关键的依赖放到CDN上,然后再通过<script>来异步加载,这种脚本一般都会采用注入变量的方式来进行加载,这个时候就很麻烦。比如,我通过<script>加载了d3,但是在使用的时候,就会报错:ESLint: 'd3' is not defined.(no-undef)TS2686: 'd3' ref原创 2020-05-17 22:50:33 · 6526 阅读 · 2 评论 -
在nuxt项目中使用keep-alive的两种可能方案
关于Vue中keep-alive的作用,以及在部分场景下由于避免重复请求、重复渲染的性能提升,想必大家都很清楚了,在此不再赘述。但是在nuxt项目中使用keep-alive就有个问题,比如我有一个用到嵌套路由的页面,导航栏(或者标签页)由几个页面共享,然后根据路由切换页面内容。这应该是个很常见的场景,Vue的文档里keep-alive的部分用的也是这个例子。为了直观,放个图好了:在这个场景下使用nuxt,虽然整个页面没有重复渲染(因为被keep-alive缓存了),但是每次都会触发asyncData这原创 2020-05-16 18:33:12 · 5533 阅读 · 1 评论 -
Windows 10环境下V8引擎的编译方法
先说说为什么我要干这个事吧。看起来内核跟我们日常开发没什么关系,但是在做性能优化的时候,性能分析可能会需要深入到汇编指令的层面;可以利用d8做到这一点。比如:./out/x64.debug/d8 --print-opt-code test.js再扯下去就扯远了,这次主要是记录一下编译方法。先说明一下环境,我用的是Windows 10,然后电脑上已经有了之前学C++的时候装的VS 2017 Community,也有一个anaconda的Python 3.7,以及很基础的Git。其中VS还是很重要的原创 2020-05-13 09:37:56 · 3255 阅读 · 0 评论 -
前端可能用到的工具的代理设置方法
因为众所周知的原因,很多国外的资源没法下载,或者速度很慢;最近编译了一次V8,下载过程中再次充分体会到了这一点……所以就稍微记录一下平时用到的一些工具的代理的设置方法。因为我主要用的是Windows,下面的内容也是基于Windows的。提示:本文不是翻墙教程,只是探讨可能的设置代理的方法。此外,这些方法的设置主要是临时性的(npm和yarn除外)。为什么不搞个持久化的方式,因为我不想因为某次忘了关,或者代理的端口变了,导致连不上网,然后花很长时间去排查问题;可以写个脚本啥的。验证方式curl -v原创 2020-05-12 09:27:13 · 893 阅读 · 0 评论 -
pow函数有四样写法,你知道吗
求次幂是个老生常谈的话题了,在任何一门语言里都是最基础的部分。在这里主要以JS为例。首先,最容易想到的是暴力法,也就是连续乘上n个x;但是这个的性能显然很差,我们一般不会考虑这么写。而且,为什么不用内置函数呢?调内置函数没什么难度,随便举个例子吧:var myPow = function(x, n) { return Math.pow(x, n);};确实,这个没什么难度,并且内置函数一般得到了充分的优化,性能也是很有保障的。但是,内置函数一定就快吗?还能进一步优化吗?还有没有别的方法?这原创 2020-05-11 19:20:08 · 2756 阅读 · 0 评论 -
在Vue项目中导入外部字体的几个注意点
因为项目里有需求,要做一个代码展示。既然要做代码展示,高亮可以用highlight.js(当然这里没有这个需求,只是单纯做一个展示),同时字体也是必不可少的,用浏览器的默认字体总觉得差点啥,所以就有此一说。找了半天,我用了Source Code Pro这个开源的字体,用的是Google提供的字体服务。本来应该是没啥需要注意的,大家都知道,只要从网上把字体下下来,然后放在项目里让webpack一起打包就行了,但是字体这种东西,打包在一起有点大,会增加打包的体积。可能有人说,我可以异步加载,可以shake(把原创 2020-05-10 17:16:17 · 918 阅读 · 0 评论 -
element-ui表单验证,value一直为undefined的一种可能解决方案
有很多人遇到过这个问题,但是一般都是因为prop没写对,或者没有在data里声明;但我遇到的情况这两者都不是。代码如下:<template> <el-form :rules="rules"> <el-form-item prop="value"> <el-input v-model="form.value"/> &l...原创 2020-04-18 16:59:39 · 17626 阅读 · 15 评论 -
nvm for Windows切换node版本无效的可能解决方案
最近因为需要接手一个用vue-cli2写的遗留前端项目,现在的node 12.x已经不兼容当时的项目了,所以就打算装一个node 8.x。但是不能因为这个影响平时的工作啊,所以就想着搞一个node版本管理的工具。之前听说过著名的n,但是n不支持Windows,所以就找了这个nvm for Windows。安装过程按照惯例是一直下一步,但是因为C盘空间不是很够,所以就装到D盘了。装完之后,下了两个...原创 2020-04-05 09:19:46 · 3492 阅读 · 2 评论 -
TypeScript按模块引入d3报错div.transition() is not a function的解决方案
一般来说,直接导入整个d3,我们会这么写:import * as d3 from 'd3';这样,我们就可以像在js里一样,使用熟悉的d3.select了。但是因为不想一次性导入整个d3给项目增加大小,所以我就对d3进行了按模块导入:import * as d3 from 'd3-selection';这个其实也不影响select,但是因为我想给一个div增加transition的效...原创 2020-04-02 10:31:01 · 3218 阅读 · 0 评论 -
在Vue单文件组件的template标签上使用v-if不生效的原因
今天晚上,我在某个组件里看到了这样一段代码,简化来讲,大概长这样:// Child.vue<template v-if="false"> <div>Foo</div></template>// Parent.vue<template> <Child /></template>按理来说,这里...原创 2020-03-29 23:03:37 · 12664 阅读 · 0 评论 -
在nuxt中使用路由重定向
我们都知道,在写SPA的时候,我们可以通过配置vue-router来实现路由的重定向。官方文档(以及ts类型)的定义中给出了这一选项:interface RouteConfig = { path: string, redirect?: string | Location | Function,}也就是说,我们可以定义这样一个路由:{ path: "/foo", r...原创 2020-03-22 13:10:08 · 17149 阅读 · 2 评论 -
React + TypeScript实现上传整个文件夹
兼容性还有待测试,刚换了个电脑,环境还没配完……反正在不同的浏览器里是不太一样的,主要是在输入框的显示上,因为原生的实现在这一块不太一样;但是用还是能用的。今天下午突然收到私信,有人问我怎么在React里用TypeScript实现上传整个文件夹。其实这个还算是一个比较常见的场景,但是我并不太熟悉React,平时都是用Vue的,一时间还是有点懵。好在他提供了一个demo,大概长这样,就不写全了,...原创 2020-03-14 20:57:50 · 2698 阅读 · 1 评论 -
使用node-canvas在服务端渲染echarts图表
踩了很长时间的坑,总算是能跑起来了。但是如果要我给echarts的SSR一个评价,那就是不好用……可能是我太菜了。而且,因为我是Windows用户,这个过程对Windows极其不友好。友情提示:入坑请慎重。在服务端渲染图表,绕不开的一个问题就是,没有DOM怎么绘图?这个主要有两种解决方案,一个是用那些headless的浏览器去渲染,然后进行截图;另一个就是在Node环境下模拟DOM元素,比如我...原创 2020-03-12 21:28:50 · 6737 阅读 · 2 评论 -
Vue 2.x TypeScript 按需引入element-ui
在业务中,只要使用组件库,就不可避免的要涉及到按需引入的问题,尤其是element这种重量级的组件库,如果一次性全部引入,对整个项目的大小影响很大。但是,element官方只提供了基于babel的按需引入方案,并没有给出ts应该如何做到按需引入。经过试验,如果不做处理,哪怕是import { Button, Select } from 'element-ui';,在ts中还是会全部引入。本来是...原创 2020-03-03 17:47:26 · 2604 阅读 · 0 评论 -
@vue/cli创建项目报错ERROR Failed to get response from /vue-cli-version-marker的解决方案
致谢:优快云@beeegood提供的问题。今天他们遇到一个很有意思的bug,用@vue/cli创建项目的时候报错了,还是个从来没见过的报错:一开始以为是版本问题,毕竟报错信息上写着update,但是cli的版本是最新的,而且询问之后,node和npm版本也是最新的(12.16.1,截止我写这篇文章的时候是最新的);最要命的是,也没有老版本的vue-cli……这就非常有意思了。按照惯例...原创 2020-02-26 20:31:08 · 20033 阅读 · 19 评论 -
Vue 2.x 子组件删除时使用setTimeout导致splice数组元素后视图没有正确更新的解决方案
在实际业务中,经常会有这样的场景:一堆消息卡片。比如:对于这种情况,在Vue里,我们一般都会封装一个Card组件,然后在父组件中用v-for进行渲染。以下是一个随手写的例子(也可以在https://codesandbox.io/s/great-field-x95lw?fontsize=14&hidenavigation=1&theme=dark查看):// App.vue&...原创 2020-02-22 21:14:18 · 781 阅读 · 0 评论 -
TS2339: Property does not exist on type 'CombinedVueInstance<Vue, unknown, ...>'的解决方案
Vue + TypeScript的项目里,在watch里使用data里定义的数据的时候,发现类型消失了,出现了这个报错:TS2339: Property does not exist on type 'CombinedVueInstance<Vue, unknown, unknown, unknown, Readonly<{ ... }>>'。查了一些资料之后,发现是因...原创 2020-02-08 23:59:58 · 18133 阅读 · 0 评论 -
ElementUI el-select绑定对象报错<transition-group> children must be keyed: <ElTag>的解决方案
症状是选择的时候会同时选取所有的选项,同时控制台报错<transition-group> children must be keyed: <ElTag>。简而言之,是因为没有指定el-select的value-key属性,或者没有正确指定el-select的value-key属性。按照官网的说法:如果 Select 的绑定值为对象类型,请务必指定 value-key ...原创 2020-02-05 18:15:45 · 21956 阅读 · 4 评论 -
关于TypeScript的类型:为什么在Vue中[]被推导为never[],{}被推导为any
为什么[]被推导为never[]可能用Vue 2.x + TS的同学或多或少都遇到过这样的问题。比如,在data()里声明一个数组,赋值的时候会报错 TS2322: Type ‘number’ is not assignable to type ‘never’:data () { return { foo: [] }},mounted () { this...原创 2020-02-04 11:57:15 · 7940 阅读 · 1 评论 -
对ElementUI表单验证的二次封装
ElementUI是我用得很多的一套UI库,而且做前端么,不可避免地要写一些表单;虽然有人说表单会让用户厌烦,但是很多场景就是要让用户填表单。写了表单就要写表单验证,但ElementUI的表单验证并不是特别友好,会出现大量的逻辑冗余。比如,如果我要验证结束时间不能早于开始时间,同时结束日期不能早于开始日期,需要写两遍极其相似的逻辑:var validateTime = (rule, value...原创 2020-01-28 21:46:06 · 1210 阅读 · 0 评论 -
Vue 3.0 function-based API尝鲜(二):配置与启动
关键词:配置、setup()原创 2019-07-10 17:33:45 · 491 阅读 · 0 评论 -
Evaluate之迷思
evaluate这个词到底是什么意思?按照翻译的解释:form an idea of the amount, number, or value of; assess.实在是有点抽象。在应用中,感觉最常见的意思大概就是“评估”了。不过,在数学里,它是“求值”,求出某个表达式的值(区别于solve,solve是解方程的“解”),对应于”value of“;在人机交互里,这个意思有点接近于评估,...原创 2019-07-15 10:30:06 · 1915 阅读 · 2 评论 -
Vue 3.0 function-based API尝鲜(三):包装对象
关键词:value()、computed()原创 2019-07-10 20:23:25 · 472 阅读 · 0 评论 -
从TypeScript视角看HTML DOM(六):Scripting
这一篇可能和TypeScript没太大关系。看到TypeScript实现的script接口(去掉了deprecate的属性),除了我们平时经常用的几个属性之外,还可以添加监听,倒是让人耳目一新。interface HTMLScriptElement extends HTMLElement { async: boolean; defer: boolean; src: ...原创 2019-07-15 11:26:14 · 1284 阅读 · 0 评论