关于什么是 includes 这件事?
🙄 当然是面向MDN编程
Array.prototype.includes()、String.prototype.includes()、TypedArray.prototype.includes()
【第三个我真不知道,mdn了一下才知道--->咦?我不知道我不知道】
文案性质:工作里的日常总结~
写作小目标:用极简单的代码,描述尽可能多的使用场景~
我不知道之-includes 在日常业务中的使用
好了,一个一个来,先上 Array.prototype.includes()
curd-场景值筛选
增删改查表单数据时,通常会看到如下情况
操作情景可能会是
编辑、查看、发布、提审、下架、上架、下载、上传、删除、屏蔽、加入黑名单、移除、邀请、配置、升舱、归档、回收、清零、重置、灰度处理等等;
针对如上可操作性,一般的做法就是后端返回一个字段比如:state/type/editType/xxxxxx,来给定当前数据的可操作状态,此时,具体的业务场景就来了。某某产品【我希望XXXX(此处省略1w字)】
总结一下就是
- 当前数据处理A状态时,1,2,3,4可操作,5,6,7不可操作;
- 当前数据处于B状态时,1,2,3,4不可操作,5,6,7可操作;
- 当...【当个der~🎃】
祖传代码【N手货】写法
if (state === 'A状态' || state === 'C状态' || state === 'D状态') {
// 设置1,2,3,4可操作,5,6,7不可操作;
}
if (state === 'B状态' || state === 'M状态' || state === 'N状态') {
// 设置1,2,3,4不可操作,5,6,7可操作;
}
if (state === 'X状态' || state === 'O状态' || state === 'P状态') {
// 设置1,2,3,4不显示,5,6,7显示;
}
当接手这段代码时,第一感觉是:【还行、还好、T喵的能看懂👻】,之后为了更好的维护这段代码在最前方添加了注释: A:代表xx状态,B:代表xx状态,C...
由于是多人维护,过了一段时间再来看这段代码时,虽然看上去没什么问题,但总感觉哪里怪怪的:
if (state === 'A状态' || state === 'C状态' || state === 'D状态' || || state === 'xx状态' || state === 'xy状态' || state === 'yx状态' || state === 'yy状态') {
// 设置1,2,3,4可操作,5,6,7不可操作;
}
// ...【不可描述的迭代内容】
真正去读这段代码的时候,才发觉绕的难受...【此后一段时间内,就这样处置,其实就是当时不知道这里可以去优化,去简化读的步骤】,直到看到别人的代码中这样写:
if ([0,1,2].includes(type)) {
// a展示,bc不展示
}
第一感觉【我T喵的怎么没想到,这方法我知道啊,我居然不知道我知道😩】,果断优化祖传代码
// 优化前
if (state === 'A状态' || state === 'C状态' || state === 'D状态' || || state === 'xx状态' || state === 'xy状态' || state === 'yx状态' || state === 'yy状态') {
// 设置1,2,3,4可操作,5,6,7不可操作;
}
// ...【不可描述的迭代内容】
-------------------------------------------------------------------------------------------
// 优化后
if ([A,C,D,xx,xy,yx,yy].includes(state)) {
// 设置1,2,3,4可操作,5,6,7不可操作;
}
// ...【优化后的迭代内容】
感觉der一下就上来了,不过觉得还可以再搞点事【此后就是个人尝试了,未添置进实际项目中,不要问,问就是时间、工时各种因素成本】so:
// 抽一个js文件,存放对应文件各种情况列表的汇总
// 例如:
/**
normalList(正常情况下按钮状态列表):[A,C,D,xx,xy,yx,yy]
specialList(正常情况下按钮状态列表):[A,C]
*/
/**
- 此处也可以封装成对象,感觉凭借个人喜好吧
- AfileStateObj(A文件的状态队形): {normalList: [...], specialList: [...]}
- 接下来的描述看不明白也没关系,我自己胡思乱想的内容:
- 对象的话就可以进一步组装全局的<状态属性>管理
- 每个子文件的各种状态对应一个对象即可
- 可以从接口获取那就更好,直接动态配置
- 在对应的管理后台搭建可视化页面,对不同页面状态值进行动态管理,就更好不过了
- 目前能想到的就到这一层了,如果有其他见解欢迎评论区指出~
- ...扒拉扒拉,各种优化😂
*/
const editTypeList = [A,C,D,xx,xy,yx,yy];
const updateTypeList = [B,M,N];
const showTypeList = [X,O,P];
// 此时的判断更新为
if (editTypeList.includes(state)) {
// 设置1,2,3,4可操作,5,6,7不可操作;
}
// ...【抽取常量后的迭代内容】
关卡、校验、检索
最常用的,莫过于图片、视频、音频上传的格式校验,下面看下antDesign示例的部分代码: 参考地址---> 用户头像
// ant 官方代码base3.26.19
function beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('You can only upload JPG/PNG file!');
}
...
}
-------------------------------------------------------------------------------------------
// 到实际项目中时,可能就长这样了【仅做示例说明,不代表真实代码】
function beforeUpload(file) {
// 常见视频类型 MP4/WebM/Ogg
const isVideo = file.type === 'video/mp4' || file.type === 'video/webm' || file.type === 'video/ogg';
if (!isVideo) {
message.error('You can only upload MP4/WebM/Ogg file!');
}
...
}
-------------------------------------------------------------------------------------------
// 优化思路同上,迭代后
function beforeUpload(file) {
const allowTypeList = [ 'video/mp4', 'video/webm', 'video/ogg' ];
if (!allowTypeList.includes(file.type)) {
message.error('You can only upload MP4/WebM/Ogg file!');
}
...
}
-------------------------------------------------------------------------------------------
// em...if中的代码有点长,再精简一下
function beforeUpload(file) {
const allowTypeList = [ 'video/mp4', 'video/webm', 'video/ogg' ];
// file 解构了一下,布尔值在if外拿一下
const { type } = file;
const falg = allowTypeList.some(t => type.includes(t))
if (!falg) return message.error('You can only upload MP4/WebM/Ogg file!');
...
}
这里稍加修改,就可以实现文件和图片的切换校验
// typeName 枚举为: 'images'-[代表图片类型]、'files'-[代表文件类型]
function beforeUpload(file, typeName) {
// 文件列表
const fileList = ['.doc', '.docx', '.xls', '.txt', '.html', '.pdf'];
// 图片列表
const imagesList = [ '.jpg', '.png' ];
// 获取传入类型关联列表
const fileType = typeName === 'files' ? fileList : imagesList;
const { type } = file;
const falg = fileType.some(t => type.includes(t))
if (!falg) {
// notification 为ant的通知提醒框
notification.error({
message: `不可上传文件的类型为${
fileList.join(',')
}以外的格式${typeName === 'file' ? '文件' : '图片'}`,
});
return false;
}
...
}
若遇到其他新的使用场景后,此处补充~
下面是String.prototype.includes() 的场景总结:
字符串匹配
这里的 "字符串" 在业务中可能就变成了:
- 路由地址,如:/login、/detail等
- 方法名称:如:getMD5,getUserName等
- 模块名称或文件名称:如:XX.scss/xx.less/xx.html/xx_modules等
- 对象属性名称:如:state、flag、isTrue等
- 具体的网络状态:如:404,502,'error','Not xxxx'等
- 特殊符号...
x钉、x宝、XX会议,登陆选项中大部分存在三方登陆入口,比如:微信一键登陆等等;然而登陆完依旧要绑定手机号才能正常使用。即:用户登陆后,却检测到其未绑定手机号,直接拦截后,跳去手机号绑定页面【中间一系列的校验操作此处不做讨论】
// 代码可能长这样【也可能长其他样~🧐】
// 假设当前页面为一键登陆页面【可能为某软件,某运营后台,某Sass平台等等】
const loginUrl = 'xxx/yyy/login'; // 绑定手机号页面
const mobile = apiInfo.mobile; // 点击一键登陆时,通过接口获取的手机号
const currentPath = location.pathname;
// 木有手机号 && 当前路径不是绑定手机号页面
if (mobile === '' && !loginUrl.includes(currentPath)) {
// ...
// 跳转到绑定手机号页面
}
遇到有趣的例子,此处会再做补充,欢迎留言交流讨论~😋