lumingkunn

lumingkunn 查看完整档案

北京编辑  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

lumingkunn 发布了文章 · 11月13日

antdv坑 - table组件 slot无效

仿照官方文档第一个例子写了一下,发现没有生效,排查了半天,发现是:
column各属性如果同时定义了属性本身和其对应的slot属性的话,则优先生效属性本身,因此slot属性无效

<a-table :columns="columns">
    <template slot="titleFill"> - a名称 - </template>
</a-table>

const columns = [{
    title: '名称',
    key: 'name',
    dataIndex: 'name',
    slots: { title: 'titleFill' }, // 此时titleFill不生效,表头还是会展示“名称”,而不是"- a名称 -"
    scopedSlots: { customRender: 'nameFill' }
}]
查看原文

赞 0 收藏 0 评论 0

lumingkunn 收藏了问题 · 11月5日

TS对filter结果类型推断似乎不正确?

如下:数组filter推断的结果依赖带上number,对比了下map是没有问题的

大家看看为啥这样?

image.png

code:

// 
const arr: string[] = ['0', 1, 2].filter(item => {
    return typeof item === 'string'
})
const arr1: string[] = ['0', 1, 2].map(item => {
    return item.toString()
})

lumingkunn 赞了回答 · 11月5日

解决TS对filter结果类型推断似乎不正确?

因为实际上是:

['0', 1, 2].filter((item: string | number) => {
    return typeof item === 'string'; // 并不改变 item 的类型,只决定是否过滤掉
})

所以返回类型也是 Array<string | number>

你可以类型断言一下:

const arr = ['0', 1, 2].filter(item: string => {
    return typeof item === 'string';
}) as string[];

关注 1 回答 1

lumingkunn 赞了问题 · 11月5日

解决TS对filter结果类型推断似乎不正确?

如下:数组filter推断的结果依赖带上number,对比了下map是没有问题的

大家看看为啥这样?

image.png

code:

// 
const arr: string[] = ['0', 1, 2].filter(item => {
    return typeof item === 'string'
})
const arr1: string[] = ['0', 1, 2].map(item => {
    return item.toString()
})

关注 1 回答 1

lumingkunn 发布了文章 · 8月31日

【科普】学习和区分常见的技术标准:RFC、W3C、ECMA

RFC

RFC 全称 Request For Comments,通常译为请求注解,是有关 Internet 的一系列注解和文件,涉及计算机网络的概念、协议、过程、程序、会议纪要、观点看法甚至幽默等诸多方面的内容
RFC 由 因特网工程师任务组 Internet Engineering Task Force (IETF) 进行起草和编辑
四个阶段:因特网草案、建议标准、草案标准、因特网标准
最常见的TCP、HTTP、TLS等等,都为RFC标准
https://www.rfc-editor.org/rfc-index.html

W3C

World Wide Web Consortium,万维网联盟
Web技术领域最具权威和影响力的国际中立性技术标准机构
W3C 最重要的工作是发展 Web 规范,比如 HTML、XHTML、CSS、DOM 等world wide web是建立在internet之上的,主要侧重于超文本(HTML)、HTTP等web技术
https://www.w3.org/TR/

ECMA

Ecma国际(Ecma International)是一家国际性会员制度的信息和电信标准组织
五个阶段:

  • Stage 0 - Strawman(展示阶段)
  • Stage 1 - Proposal(征求意见阶段)
  • Stage 2 - Draft(草案阶段)
  • Stage 3 - Candidate(候选人阶段)
  • Stage 4 - Finished(定案阶段)

ps:ECMAScript是一种标准,即ECMA-262,javascript是该标准的一种实现,其他实现还有 JScript 和 ActionScript 等
https://www.ecma-international.org/publications/standards/Standard.htm

查看原文

赞 1 收藏 1 评论 0

lumingkunn 赞了文章 · 8月17日

Umi Hooks - 助力拥抱 React Hooks

这是蚂蚁金服内部技术分享的文字稿,本次分享主要介绍了为什么要用 Hooks?以及如何使用 Umi Hooks 提效?

Umi Hooks http://github.com/umijs/hooks

开场

image-20200116191741370

大家好,我叫尽龙,来自体验技术部。社区名称叫 brickspert,砖家的意思。

自从 React 推出 React Hooks 后,就开始尝试使用 Hooks,并逐渐喜欢上了它。目前,几乎 100% 的组件都是使用 Hooks 开发。经过大半年的实践,在 Hooks 使用方面沉淀了一些经验,很高兴今天有机会能分享给大家。

image-20200116191759286

在分享开始之前,我想了解下:“有多少同学目前已经在项目中大量使用 Hooks 了?”

嗯嗯,谢谢。看举手的同学,大概一半一半吧。没关系,听完今天的分享,我相信你一定有兴趣尝试下 Hooks 的。

React Hooks 是 react v16.8 的一个新特性,很佩服这么重磅的功能,在一个小版本中发布,说明 React 团队有足够的信心向上兼容。

Why Hooks?

image-20200116191817331

为什么要放弃 Class,转用 Hooks 呢?在内部外部有很多争论,包括知乎也有类似提问。我们也不免俗套的要对比下 Class 和 Hooks 了。当然为了保证今天的分享效果,我肯定会偏向 Hooks 的(哈哈哈哈)。

image-20200116192324872

Class 学习成本高

Class 学习成本很高。首当其中的就是生命周期,多,太多了。不仅多,还会变!React v15 和 v16 就不一样。下面是我在网上随便找的一张图。

image-a5b927b35025

这个是 React v15 的生命周期,你都掌握了吗?你知道 v16 有什么变化吗?

之前无论你去哪里面试,基本都会有几个必问问题:

  • 讲讲 React 生命周期?React v15 和 React v16 生命周期有啥变化?
  • 如何优化 Class 组件?shouldComponentUpdate 是做什么的?如何用?
  • 一般在哪个生命周期发送网络请求?为什么?
  • ......

生命周期最重要,但是有很高的学习成本,需要大量实践才能积累足够的经验。当然,这几个问题回答不好,百分之八十以上的几率会挂掉。

当然不止是生命周期,this 也是一个很大的问题。你有没有在组件写很多 bind?或者所有的函数都用箭头函数定义?

this.someFunction = this.someFunction.bind(this);

// 或
someFunction = ()=>{}

为什么要这样写呢?如果不写会有什么问题?哎呦,又多了一个面试题,你会吗?

Hooks 学习成本低

对比 Class,Hooks 的学习成本可就太低了!掌握了 useState 和 useEffect,80% 的事情就搞定了。

image-7cbf7879e7cf

Class 业务逻辑分散

Class 业务逻辑分散,实现一个功能,我要写在不同的生命周期里面,不聚合~

比如,如果你有个定时器,你一定要在 componentWillUnMount 去卸载。

image-67b7d915f6af

再比如,我们要写一个请求用户信息的组件,当userId 变化时,要重新发起请求。我们就要在两个生命中期中写请求的逻辑。

image-4059e72aa129

相信上面的逻辑,大家也是经常会写的吧。

奥奥,sorry,上面的 componentWillReceiveProps 已经被废弃了,我们应该用 componentDidUpdate 来代替。

“咦,这是为啥呢?好好的为什么要废弃,不让这么用了?”

又来一个面试题!你知道答案吗?

Hooks 业务逻辑聚合

而 Hooks 的业务逻辑就非常聚合了。上面的两个例子,改成 Hooks 你会写吗?

image-3780dc60b735

image-88e9ba8a7add

简直不要太简单!香啊!我可以提前下班了。

Class 逻辑复用困难

说到逻辑复用,很多同学会说 Class 的 Render Props 和 HOC(高阶组件)可以做逻辑复用!那我们看看 Class 的逻辑复用有多么的惨不忍睹。

首先我们看看 Render Props。

首先我们想复用监听 window size 变化的逻辑,开开心心的写了下面的代码。

image-f9273eefa2ef

然后,我又想复用监听鼠标位置的逻辑,我只能这么写了。

image-d60b6492b570

到这里你应该看到了问题所在。这简直就是地狱!我不忍心复用其它逻辑了。

我们放过 Render Props,来看看 HOC 吧。

如果你要问什么是 HOC,那我不得不推荐我的另外一篇文章《助你完全理解React高阶组件(Higher-Order Components)》。

哪怕你不知道 HOC 是啥,你也一定用过。比如 redux 的 connect。

image-20200116200932301

上面的代码,我用了三个 HOC,分别是 redux 的 connect,react-intl 的 injectIntl,以及 AntD 的 Form.create()。

这是一个非常常见的用法。如果你光看代码,大概已经懵圈了。“我是谁?我在哪?我要干什么?”

这会我仿佛听见 HOC 在说:“我不仅让你看不懂我,我还很容易出各种问题。”

是的,HOC 很容易出问题。大家都往组件的 props 上面挂属性,万一有个重名的,那就只能说一句“不好意思,GG思密达”!

Hooks 逻辑复用简单

Hooks 来了,它表示,我要一个打五个!Render Props 和 HOC 联合起来也被我秒杀!

image-5a6f5d648ca9

Hooks 表示,来十个,来一百个我也能打。

Hooks 最强的能力就是逻辑复用了,这是我最最最爱的能力了。

Hooks 会产生很多闭包问题

是的,我也不偏袒 Hooks,由于 React Hooks 的机制,如果用法不正确,会导致各种奇怪的闭包问题。

如果你要问 React Hooks 的机制是什么的话,我又要给你推荐一篇我之前写的文章了:《React Hooks 原理》。

那面对这个问题,怎么解呢?说实话,我也没有很好的解决办法。

但是,这可能也有好处。如果碰到想不明白的问题,那 99% 是由于闭包导致的,我们有很确定的方向去排查问题。

image-4636b47be14f

记住这句话,你可以少走很多弯路。

Show Case

image-20200116203233594

当然,说再多,吹再好,也没多大用。我上面讲的 Class 和 Hooks 的优缺点,网上的也有很多人讲,大家也肯定都看过。

用程序员的交流方式,就是“Talk is cheap,Show me the code.”。

亮剑吧!

接下来,我会用一个例子,让你折服,拜倒在 Hooks 的石榴裙下。如果你不服,咱们单独撕~

网络请求组件实现

image-20200116214124140

接下来,我们来实现一个最最最常见的组件。该组件接收 userId,然后发起网络请求,获得用户信息。

说白了,就是最简单的发起网络请求的组件。我们先用 Class 来实现看看。

image-20200116214639300

这段代码,是最简单的网络请求。

  • 定义一个 username 状态。
  • componentDidMount 的时候发起网络请求。
  • 网络请求结束,更新 username。

美滋滋。但是少了点东西。网络请求,我们肯定要维护一个 loading 状态,保证用户体验比较好。

那我们加上吧。

image-20200116214918755

这张图,我们增加了 loading 状态,在网络请求发起前,置为 true,在网络请求结束后,置为 false。

美滋滋。但是还是少点东西。userId 变化后,我要重新发起网络请求吧。

我们再加点代码吧。

image-20200116215101730

我们增加了对 userId 变化的监听,如果 userId 变化后,重新发起请求。

这次稳了吧?

不不不,还不够。如果 userId 连续变化了 5 次,发送了 5 个网络请求,我们要保证总是最后一次网络请求有效。也就是经常说的的“竞态处理”或者“时序控制”。

我加!加还不行吗!

image-20200116215409524

其实到这里,有些同学已经懵了。“你说的时序控制,听着很有道理,但我平时都没处理过这个问题,我看下你怎么实现的。”

确实,时序控制不算一个简单的问题,很多新手都不会解决这个问题。

稳了!到这里你觉得稳了吧。

还是年轻啊,小伙子。

image-20200116220003295

如果用上面的代码来玩,你可能会偶尔碰到上面的警告。这个警告是怎么造成的呢?我说一下你就明白了。下面四个步骤执行,必会报警告:

  1. 组件加载
  2. 发起网络请求
  3. 组件卸载
  4. 网络请求请求成功,触发 setState

看出问题了吗?组件已经卸载了,还去 setState,造成了内存溢出。

怎么解决呢?

image-20200116220311200

在组件卸载的时候,放弃最后一次请求。

到这里为止,我们就完成了一个完美的网络请求。这次真结束了!

看下写了多少行代码。

image-20200116220531399

除去空格,我们写了 38 行代码。实话说,38 行代码我能忍,但是这些逻辑我忍不了!回想下我们处理了多少逻辑:

  • 网络请求
  • loading
  • userId 变化重新发起请求
  • 竞态处理
  • 组件卸载放弃网络请求

关键这些逻辑是没办法复用的!每个项目可能有数十上百个组件会发网络请求,我就要写几十,几百遍这样的逻辑。想想我都难受。

说实话,我在写项目的时候经常会偷懒。要不就不写 loading,要不就不管竞态,要不就不管最后的内存溢出警告。

你有没有和我一样呢?嘿嘿。

言归正传,接下来就邀请 Hooks 登场了。

image-20200116221123031

三下五除二,我们用 Hooks 实现了刚才所有的逻辑。

image-20200116221212124

17 行!代码量减少了 50% 以上。好像还行!

但是,别忘了,Hooks 最重要的能力就是逻辑复用!这些逻辑我们完全可以封装起来!我们把刚才的逻辑全部封装起来!

image-20200116221359407

useAsync 封装了刚才我们说的所有功能,一行代码完成了网络请求。

最后整个组件会长这样。

image-20200116221605411

哇!我自己都佩服自己!简直了!美呆了,帅毙了,感觉自己无敌了!提前完成工作,下班回家!

image-20200116221755193

通过这个例子,我想证明一个论点:“使用 Hooks 封装逻辑的能力,可以极大提高开发效率”。

Umi Hooks

这时候你肯定要问,useAsync 在哪里?给我瞧瞧?

image-20200116221941442

useAsync

useAsync 在这里,快来瞧,快来看啦!

useAsync 是 Umi Hooks 库的核心 Hooks 之一,Umi Hooks 提供了大量提炼自业务的 Hooks。一行代码真的可以实现很多功能!

Umi Hooks 在这里在这里!你懂的~~

image-20200116222352082

当然,useAsync 不止包含上面说的功能,还支持“手动触发”执行,还支持“轮询”!

只要简单的配置一个 pollingInterval ,就能轮询发送请求了。快去试试啦

接下来我们会介绍几个更牛的 Hooks 给大家认识!

useAntdTable

image-cc2f4b087aca

AntD 的 Table 组件,想必大家在项目中经常用到吧!除了刚才异步请求的所有逻辑外,你还得处理其它的逻辑。

image-20200116232857059

比如维护 page、pageSize、sorter、filter 的状态,还得考虑搜索条件变化后,重置 page 到第一页。这些逻辑光想想就头疼了,别说写了。

现在一行代码就可以实现了!useAntdTable,封装了所有的逻辑,只要一行代码!如图上所示,你只要 ...tableProps,就可以了。这也许就是幸福的味道吧~

useLoadMore

加载更多的场景,比如下面动图的场景,想必大家在工作中都写过。

image-22fa47992b6f

这样一个加载更多的场景,我们要维护多少状态?写多少行逻辑?本来我打算写个 Class 实现的例子贴出来的,但是我放弃了,因为太难了~~

随便想想要处理的逻辑:

  • 第一次加载时候的 loading
  • 加载更多时候的 loading
  • 维护 page 和 pageSize
  • 网络请求
  • 是不是加载全了
  • 搜索条件变化后,重置到第一页。
  • .....

脑壳疼,真的脑壳疼。我会写,但是写起来真的好累。

还没完,一般产品同学还会要求,上拉加载更多......

image-cf629db68ebc

这时候我们还得监听滚动位置,如果快到底了,触发加载更多。脑壳更疼了!

image-20200116235013101

Umi Hooks 听到了你的求救,派出 useLoadMore 来拯救你了。一行代码就可以实现所有的功能!一个小时变一分钟,又可以早点下班了。

useDynamicList

image-20200116235455431

还有更好用的,比如 useDynamicList,下面的动态列表,一行代码搞定。

image-16556dfcf0e8

useBoolean

不仅是上面讲到的各种复杂逻辑可以封装。简单的逻辑封装起来也是极其好用的,比如 Boolean 值的管理。

我们一般控制 Modal,Popover 等显示隐藏的时候,都要维护一个 visible 状态。大概会是这样。

image-20200116235651552

这样的逻辑,你写过多少遍?没有几千也有几百吧!

image-20200116235850057

以后你就可以用 useBoolean 咯!

More

image-20200116235957789

不仅是上面讲到的这些,我们还有很多很多的 Hooks。

比如 useSearch,就封装了通常异步搜索场景的逻辑,比如 debounce。

比如 useVirtualList,就封装了虚拟列表的逻辑。

image-20200117000249183

比如 useMouse,封装了监听鼠标位置的逻辑。

比如 useKeyPress,封装了监听键盘按键的逻辑。

image-20200117000412951

30+ Hooks 供您选择,并且我们仍然处于婴儿期,快速发展中。我们的愿景就是:封装别人的逻辑,让别人无逻辑可写。

未来规划

image-20200117001130397

更多的 Hooks 开发

如上面所述,我们现在还处于婴儿期,需要不断汲取能量,更多的 Hooks 正在路上!要实现“让别人无逻辑可写”的目标,还需继续奋斗。

更强大的 useRequest

image-20200117001209280

大家应该都听过 useSWR 吧?是 zeit 公司开发的一个专门做网络请求的 Hooks,提供了很多新颖的思路,给了我们非常大的启发,github star 就像坐火箭一样。但在实际项目使用中,还是会有很多地方不符合蚂蚁内部的体系。但是它给我们非常大的启发,基于 swr 的思路,我们可以实现更强大的 useRequest!图上的能力,我们都要!

useRequest 目前已经处于内测期了,下个版本将会与大家见面!我们的目标是:所有的网络请求,只用 useRequest 就够了!

Hooks 生态

目前社区上 Hooks 相关的基础教程、进阶教程、原理深入、常见问题等文档都比较分散,我们准备向 Hooks 生态发展,提供各式各样的文章。以后学习 Hooks,使用 Hooks,找 Umi Hooks 就对了。

当然,生态方面目前正在规划中,预计年后启动。

总结

image-20200117001711649

Umi Hooks,你值得拥有。

我们目前处于发展阶段,欢迎大家一起共建。

你可以提 idea,我们负责实现。

你可以提 issue,我们负责改 bug。

你可以提 PR,将你封装的 Hooks 分享给大家,让更多人收益。

❤️期待您的参与。

查看原文

赞 37 收藏 21 评论 3

lumingkunn 发布了文章 · 4月10日

Mac 访达里找不到常用目录了怎么办

有的时候发现访达左侧的主要目录不见了,比如常用的:桌面、文稿、图片、下载、Home目录等等

image.png

这时只需要将鼠标放在左上角的个人收藏,即可出现“显示”按钮,点击即可恢复啦

image.png

查看原文

赞 0 收藏 0 评论 0

lumingkunn 赞了回答 · 1月19日

解决如何清空input file中的文件

在input的change事件回调中把input的value清空即可

typeof $ === "function" && $("#" + id).change(function () {
            var reader = new FileReader();
            //读取文件以数据URI的形式保存在reader的result属性中
            reader.readAsDataURL(this.files[0]);
            //获取图片大小,以M为单位
            var fileSize = Math.round(this.files[0].size / 1024 / 1024);
            //获取图片大小,以KB为单位
            var fileSizeKB = Math.round(this.files[0].size / 1024);
            //获取到图片后把input框内的图片删除,这样选同一张图片上传时才会触发change事件
            $(this).val("");
            //上传图片的尺寸必需大于200KB
//          if (fileSizeKB < 200) {
//              return that.alert("请上传尺寸大于200KB的图片!");
//          }
            //在图片读取完之前显示loading,因为手机上图片读取和压缩可能会比较耗时
            that.loading("show");
            reader.onload = function () {
                ....         
            };
        })

关注 9 回答 5

lumingkunn 赞了问题 · 1月19日

解决如何清空input file中的文件

如何清空input file中的文件

<div class="pic-box">
    <input type="file" id="upload" accept="image" @change="upload">
    <label for="upload"></label>
    <span class="add icon-plus"></span>
</div>

需要每上传一张图片将图片放在一个数组里面,但是原来的值中有文件。现在需要清空file中的文件以后上传第二章(暂不考虑多文件添加)

关注 9 回答 5

lumingkunn 发布了文章 · 2019-12-08

VSCode 隐藏 右上角 工具栏

背景

VSCode编辑时的右上角,即tab标签右边,有几个工具icon,在插件装的比较多的时候就会有很多icon,占用了大量空间,如图:

multi-root hero

所以,就会有隐藏掉它们的想法,教程如下:

步骤

首先安装VSCode拓展程序:Custom CSS and JS Loader

安装完成后在settings.json添加两行代码

"vscode_custom_css.imports": [""],
"vscode_custom_css.policy": true,

自己编写一个css文件,内容是:

.tabs-and-actions-container .editor-actions {
    display: none !important;
}

将文件保存,文件路径填写到上一步编辑的 vscode_custom_css.imports 字段中,注意在mac下是类似 file:///Users/MyUserName/Documents/custom.css 的格式
不同系统的文件路径规则具体可参考:https://marketplace.visualstudio.com/items?itemName=be5invis.vscode-custom-css

之后重启VSCode,注意启动时必须有足够高的权限,大概是:

sudo chown -R $(whoami) <Path to Code>

配置权限具体可以参考上一步的链接

下一步,使用Shift + Command + P,调出命令面板,执行

Reload Custom CSS and JS

之后重启VSCode,即可发现右上角工具栏已经隐藏了

可以参考:https://stackoverflow.com/questions/47266613/vscode-hide-top-right-icons?r=SearchResults

这个回答中还提供了hover时显示工具栏的花式操作,如果有需要可以去浏览

查看原文

赞 0 收藏 0 评论 0

认证与成就

  • 获得 7 次点赞
  • 获得 5 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 5 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2017-08-15
个人主页被 227 人浏览