当前位置: 首页 > Web前端 > HTML5

第七期:前端九大灵感分享

时间:2023-04-05 17:34:31 HTML5

第七期:前端九大灵感分享1.ts数组类型的推导莫名其妙被打乱了事情是这样的,周五需要做一个小优化,某某原本导出的文件3对于一个“json对象”,我需要改成导出三个函数,根据传入的参数改变导出内容。这时,出现了一种奇怪的错误。假设当前存在如下代码:????以下代码不会报错,导出接口可以正常运行Dog{name:string;年龄?:1|2|3;}exportconsta=():Dog=>({name:"GoldenRetriever",});exportconstb=()=>({name:"Bichon",age:2,});exportconstc=()=>({name:"Labrador",});constcc:Dog[]=[a(),b(),c()];但是奇怪的是,下面的代码会报错exportinterfaceDog{name:string;年龄?:1|2|3;}exportconsta=():Dog=>({name:"GoldenRetriever",});exportconstb=()=>({name:"BichonFrise",age:2,});exportconstc=():Dog=>({name:"Labrador",});constcc:Dog[]=[a(),b(),c()];我只是给第三个方法指定了返回值,但是第二个方法居然报错了,我不关心第三个方法方法指定了返回值,但是第三个方法不会报错,还有一个奇怪的现象,但是当我指定第三个方法为返回任意类型时,第二个方法不报错:研究后发现,当数组中的一个值指定为any时,数组类型会变成any[],所以c()指定返回any而不报错。当a和c这两个方法都指定为Dog类型时,ts发现b方法的返回值不一定符合Dog的推导,因为Dog类型中的age只能包含1|2|3,所以报错了,但是如果你abc根本不指定返回值类型的话,是不会报错的,ts会自动推导出2在范围内,很神奇!二、如何设计结构为undefined|的组件bl例如,假设tip提示框组件有一个是否显示参数showTip是一个布尔值。当值为true时,即使用户没有悬停鼠标,也会出现弹框。如果为false,则无法显示。目前有一个需求,这个框在进入页面后弹出并停留3秒后消失。其实我们很容易想到,给showTip3秒为true,然后改成undefined,因为只有两种情况,要么是true,要么是undefined,那么比如下面的代码写成:constobj={};if(isFirstOpenPage){obj.showTip=true;}return但是我在使用组件库的时候,好像只要定义了showTip属性就不能设置为undefined,导致到我弹出提示后,无法恢复让用户控制显示和隐藏。这其实是设计代码时要考虑的问题。我们在设计取值为Boolean的属性时,也要考虑到undefined也可能是传值的情况。3.react如何刷新组件自身的我遇到的情况是有a,b,c三个组件,这三个组件对应三种不同的特殊情况,每一种都可能发生,但是这三个组件只有一个可以同时出现,比如组件a当前出现,而组件b只有在用户点击关闭后才会出现,这就导致我在用户每次点击关闭的时候判断另外两个组件是否需要渲染。问题是,比如在移除组件a时,组件库的方法是直接移除a的dom结构,导致react无法监听到。const[_,forceUpdate]=useReducer(x=>x+1,0);如果(showA){返回;}elseif(showB){return;}elseif(showC){return;}else{返回空值;}在每个组件中onClose={()=>{if(forceUpdate){forceUpdate();}}}上述方法的关键在于useReducer的改变会导致组件重新渲染。4、为字符串插入jsx元素事情是这样的。例如,我们目前有一个最高价{max}-最低价{min}的i18n文案。现有的方法可以替换{max}和{min},但是只能替换成字符串,不能插入dom结构,比如我想替换成蓝色的字。假设intl方法可以替换字符串中的{max},我们将intl扩展为intlPlus,下面是通常的方法。intl.format("最高价{max}-最低价{min}"["99","33"])writingofintlPlusimportintlfrom'./intl';constpix='--------------';导出默认函数intlPlus(i18n:string,arg:any[]){constlen=arg.length;constbox=Array(len).fill(pix);consttext=intl.format(i18n,box);consttextArr=text.split(pix);constres:任何[]=[];for(leti=0;i33])5.如何防止测试环境地址泄露比如我们通常不会让外界看到我们测试环境的地址例如下面的代码就是会泄露测试域名的代码:constpathObj={prod:'www.xxxxxx.com',开发:'www.xxxxxxx-dev.com',测试:'www.xxxxxx-test.com'}//....if(location.host==='localhost:3000'){window.open(pathObj.dev)}插件webpack.DefinePlugin登场?,这个插件允许我们设置一些“全局”(引用)变量,这些变量可以在官方打包之前使用:plugins:[newwebpack.DefinePlugin({isDev:process.env.NODE_ENV==="production"?JSON.stringify("false"):JSON.stringify("true")}),]上面使用JSON.stringify很奇怪,因为只有这样才能webpack把它当作一个字符串,否则它将被视为一个语句。下面举个用法例子:我们观察包文件:可以看到包文件中已经不存在'oooooooo'了。它的原理是做全局替换,比如上面的代码//打包前:if(isDev){console.log("tttttttttt");}else{console.log("oooooooooooo");}//打包时:if(false){console.log("tttttttttt");}else{console.log("oooooooooooo");}显然,tree-shaking不会放过这种代码,所以下面的'oooooooo'逻辑将被删除。这个插件有点难懂。它不是在运行时执行的,而是在tree-shaking之前的全局替换。之所以可以直接写在globalisDev中,而不能写在window.isDev中,是因为它没有挂载到widnow对象上,这样的变量是不会在用户端运行的。6、导出为{}后,i18n翻译没有实时生效有很多配置需要实时更改。改的还是英文,这些地方的特点是所有导出的json都是类似下面这样:exportUserName={title:{i18n(USER_NAME_TITLE)}}Usageimport{UserName}from'./userName'//...上面方法写的表头在切换语言时不会改变文本。7.item2的划分使用方便命令行工具可以大大缓解我们多项目启动的问题。如果你在vscode提供的shell上启动多个项目,来回切换会感觉有点吃力,更糟糕的情况是同时开发两个或多个微前端项目,所以这个item2一定要安好,因为这个真的很好用,没玩过这个的朋友可以赶紧玩:每点一下都会加一个小窗口,我们看把控制台分成'6个部分':为了防止混淆,我们可以nameeachwindow:设置过程如下:我做的一个弹出框里面有个表格,这个表格的一列表头默认是弹出状态,但是我遇到的bug是弹出状态有时会闪过,然后又变回非弹出状态。看了组件库的源码,确定不是组件本身的问题。经过多方测试,发现这个bug与点击弹框按钮的位置有关,这让我很想了解bug的原因,因为这个弹框有弹出动画,左边是从小到大出现的,而这个变大的过程中实际上已经预渲染了弹框里面的组件,导致鼠标在出现的过程中穿过了弹框,从而导致了组件认为用户已将鼠标悬停在其上,导致提示隐藏...解决方案是在禁用300ms鼠标事件时使弹框出现。9、使用Whistle设置在线域名开发本地代码防止csrf防御由于服务器经常会加一些安全策略,比如只有referer的网站才能调用API,其他的url会报403。这时候,我们的前端可怜的http://localhost:3000遭遇了灾难,每次都需要和相关人员沟通本地调试问题。我们可以简单的使用测试环境的域名进行开发,而不是使用http://localhost:(类似windows修改本地host文件)就可以了...第一步:安装Whistlenpminstall-gwhistlew2start-p8899//启动服务直接打开域名可以看到运行界面:http://localhost:8899第二步:安装proxy由于我们要将所有浏览器请求都代理到Whistle,所以需要使用Google插件-inofproxy,搜索:ProxySwitchyOmega这一步是将浏览器的请求代理到这个地址。第3步:配置口哨。证书由于Whistle会帮我们处理所有的请求,难免会有https请求,所以我们必须导入Whistle的证书:大功告成,愉快的使用测试环境的域名进行本地开发。end???????这次就到此为止吧,希望和大家一起进步。