-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
247 lines (132 loc) · 61.1 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Victor 的自留地</title>
<subtitle>If you can't explain it simply, you don't understand it well enough.</subtitle>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/atom.xml" rel="self"/>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/"/>
<updated>2023-09-12T16:36:46.254Z</updated>
<id>https://yyx-the-oracle-github-io-g1lc.vercel.app/</id>
<author>
<name>Victor Ye</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>究竟什么是 Event Loop ?丨总结 Philip Roberts 在 JSConf 的演讲</title>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/post/2a798ab5.html"/>
<id>https://yyx-the-oracle-github-io-g1lc.vercel.app/post/2a798ab5.html</id>
<published>2023-09-11T15:04:15.000Z</published>
<updated>2023-09-12T16:36:46.254Z</updated>
<content type="html"><![CDATA[<p> 26 分钟的视频深入浅出地讲解了什么是 Event Loop 以及它与浏览器渲染的关系。<span id="more"></span></p>]]></content>
<summary type="html"><p> 26 分钟的视频深入浅出地讲解了什么是 Event Loop 以及它与浏览器渲染的关系。</summary>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/categories/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="JavaScript" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/JavaScript/"/>
</entry>
<entry>
<title>发送验证码后的节流倒计时丨刷新 & 重新进入页面,还原倒计时状态</title>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/post/9e1be607.html"/>
<id>https://yyx-the-oracle-github-io-g1lc.vercel.app/post/9e1be607.html</id>
<published>2023-08-13T04:45:38.000Z</published>
<updated>2023-09-10T15:59:51.380Z</updated>
<content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p> 最近在做一个 H5 工具,需要手机号 + 验证码登录,很自然地,点击发送验证码后需要等待一段时间才能重新发送,用于请求节流,避免用户疯狂点击:<span id="more"></span></p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/08/13/34a3ff33a7f0fe76.gif" /></div> <p> 不过这里其实有个隐藏需求——如果<code>仍然在冷却时间内</code>,那么用户无论是刷新或是关闭页面,再次打开登录弹窗,<code>需要直接展示正确的倒计时状态</code>。</p><h1 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h1><blockquote><p>使用经典的 localStorage:<br>· 发送验证码时,将发送时间 (lastSendingTime) 存入 localStorage,并开启 60 秒倒计时。<br>· 倒计时结束后,清除 localStorage 中的 lastSendingTime。<br>· 重新进入页面时,若 localStorage 中存有 lastSendingTime,则说明仍处于冷却时间内,那么计算出剩余的倒计时 N,并开启 N 秒倒计时。</p></blockquote><h1 id="Talk-is-cheap-show-me-the-code"><a href="#Talk-is-cheap-show-me-the-code" class="headerlink" title="Talk is cheap, show me the code!"></a>Talk is cheap, show me the code!</h1><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"> <span class="keyword">const</span> [countdown, setCountdown] = <span class="title function_">useState</span>(<span class="number">60</span>) <span class="comment">// 倒计时</span></span><br><span class="line"> <span class="keyword">const</span> [canSendCode, setCanSendCode] = <span class="title function_">useState</span>(<span class="literal">true</span>) <span class="comment">// 控制按钮文案的状态</span></span><br><span class="line"> <span class="keyword">const</span> [timer, setTimer] = <span class="title function_">useState</span>() <span class="comment">// 定时器 ID</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">sendVerificationCode</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="comment">// network request...</span></span><br><span class="line"> <span class="title class_">Toast</span>.<span class="title function_">show</span>({ <span class="attr">content</span>: <span class="string">'验证码发送成功'</span> })</span><br><span class="line"> <span class="title function_">startCountdown</span>()</span><br><span class="line"> <span class="title function_">setCanSendCode</span>(<span class="literal">false</span>)</span><br><span class="line"> } <span class="keyword">catch</span> (error) {</span><br><span class="line"> <span class="title function_">setCountdown</span>(<span class="number">0</span>)</span><br><span class="line"> <span class="title function_">setCanSendCode</span>(<span class="literal">true</span>)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">function</span> <span class="title function_">startCountdown</span>(<span class="params"></span>) {</span><br><span class="line"> <span class="keyword">const</span> nowTime = <span class="keyword">new</span> <span class="title class_">Date</span>().<span class="title function_">getTime</span>()</span><br><span class="line"> <span class="keyword">const</span> lastSendingTime = <span class="variable language_">localStorage</span>.<span class="title function_">getItem</span>(<span class="string">'lastSendingTime'</span>)</span><br><span class="line"> <span class="keyword">if</span> (lastSendingTime) {</span><br><span class="line"> <span class="comment">// 若 localStorage 中存有 lastSendingTime,则说明仍处于冷却时间内,计算出剩余的 countdown</span></span><br><span class="line"> <span class="keyword">const</span> restCountdown = <span class="number">60</span> - <span class="built_in">parseInt</span>(((nowTime - lastSendingTime) / <span class="number">1000</span>), <span class="number">10</span>)</span><br><span class="line"> <span class="title function_">setCountdown</span>(restCountdown <= <span class="number">0</span> ? <span class="number">0</span> : restCountdown)</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">// 否则说明冷却时间已结束,则 countdown 为 60s,并将发送时间存入 localStorage</span></span><br><span class="line"> <span class="title function_">setCountdown</span>(<span class="number">60</span>)</span><br><span class="line"> <span class="variable language_">localStorage</span>.<span class="title function_">setItem</span>(<span class="string">'lastSendingTime'</span>, nowTime)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="title function_">setTimer</span>(</span><br><span class="line"> <span class="built_in">setInterval</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="title function_">setCountdown</span>(<span class="function"><span class="params">old</span> =></span> old - <span class="number">1</span>)</span><br><span class="line"> }, <span class="number">1000</span>),</span><br><span class="line"> )</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 重新进入页面时,若 localStorage 中存有上次的发送时间,则说明还处于冷却时间内,则调用函数计算剩余倒计时;否则什么也不做</span></span><br><span class="line"> <span class="title function_">useEffect</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="keyword">const</span> lastSendingTime = <span class="variable language_">localStorage</span>.<span class="title function_">getItem</span>(<span class="string">'lastSendingTime'</span>) </span><br><span class="line"> <span class="keyword">if</span> (lastSendingTime) {</span><br><span class="line"> <span class="title function_">setCanSendCode</span>(<span class="literal">false</span>)</span><br><span class="line"> <span class="title function_">startCountdown</span>()</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="function">() =></span> {</span><br><span class="line"> <span class="built_in">clearInterval</span>(timer)</span><br><span class="line"> }</span><br><span class="line"> }, [])</span><br><span class="line"></span><br><span class="line"> </span><br><span class="line"> <span class="comment">/** 监听倒计时,倒计时结束时:</span></span><br><span class="line"><span class="comment"> * - 清空 localStorage 中存储的上次发送时间</span></span><br><span class="line"><span class="comment"> * - 清除定时器</span></span><br><span class="line"><span class="comment"> * - 重置倒计时</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="title function_">useEffect</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="keyword">if</span> (countdown <= <span class="number">0</span>) {</span><br><span class="line"> <span class="title function_">setCanSendCode</span>(<span class="literal">true</span>)</span><br><span class="line"> <span class="variable language_">localStorage</span>.<span class="title function_">removeItem</span>(<span class="string">'lastSendingTime'</span>)</span><br><span class="line"> <span class="built_in">clearInterval</span>(timer)</span><br><span class="line"> <span class="title function_">setCountdown</span>(<span class="number">60</span>)</span><br><span class="line"> }</span><br><span class="line"> }, [countdown])</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> (</span><br><span class="line"> {canSendCode ? (</span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">span</span> <span class="attr">onClick</span>=<span class="string">{sendVerificationCode}</span>></span></span></span><br><span class="line"><span class="language-xml"> 获取验证码</span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">span</span>></span></span></span><br><span class="line"> ) : (</span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">span</span>></span></span></span><br><span class="line"><span class="language-xml"> 获取验证码({`${countdown}`})</span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">span</span>></span></span></span><br><span class="line"> )}</span><br><span class="line">)</span><br></pre></td></tr></table></figure><h1 id="最终效果"><a href="#最终效果" class="headerlink" title="最终效果"></a>最终效果</h1><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/08/13/8218b9d41c0ad738.gif" /></div><h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p> 一开始感觉这是个很简单的小需求,可能 20min 就写完了,但实际花了两个多小时才把逻辑全部 cover 到,还是不能太自信啊~</p>]]></content>
<summary type="html"><h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p> 最近在做一个 H5 工具,需要手机号 + 验证码登录,很自然地,点击发送验证码后需要等待一段时间才能重新发送,用于请求节流,避免用户疯狂点击:</summary>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/categories/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="JavaScript" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/JavaScript/"/>
</entry>
<entry>
<title>一些超级棒的前端技术博客 & 演讲</title>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/post/435e2644.html"/>
<id>https://yyx-the-oracle-github-io-g1lc.vercel.app/post/435e2644.html</id>
<published>2023-06-18T04:22:01.000Z</published>
<updated>2023-09-17T16:08:28.852Z</updated>
<content type="html"><![CDATA[<p> 时常看到一些超级棒的文章或者演讲,在这里留个档,空下来了会去做一下整理和总结,它们真的每一篇都值得反复阅览。<span id="more"></span></p><h1 id="JavaScript"><a href="#JavaScript" class="headerlink" title="JavaScript"></a>JavaScript</h1><p><a href="https://www.youtube.com/watch?v=8aGhZQkoFbQ">Event Loop I</a> </p><p><a href="https://www.youtube.com/watch?v=u1kqx6AenYw">Event Loop II</a></p><h1 id="React"><a href="#React" class="headerlink" title="React"></a>React</h1><p><a href="https://blog.isquaredsoftware.com/2020/05/blogged-answers-a-mostly-complete-guide-to-react-rendering-behavior/">A (Mostly) Complete Guide to React Rendering Behavior</a></p>]]></content>
<summary type="html"><p> 时常看到一些超级棒的文章或者演讲,在这里留个档,空下来了会去做一下整理和总结,它们真的每一篇都值得反复阅览。</summary>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/categories/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="JavaScript" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/JavaScript/"/>
</entry>
<entry>
<title>拼音输入法的神奇 API丨onCompositionStart & onCompositionEnd</title>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/post/11426bbe.html"/>
<id>https://yyx-the-oracle-github-io-g1lc.vercel.app/post/11426bbe.html</id>
<published>2022-12-08T06:17:45.000Z</published>
<updated>2023-09-10T15:59:51.330Z</updated>
<content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p> 最近开发遇到了一个很 tricky 的问题,直接上 gif,看了就明白了:<span id="more"></span></p><p><img src="https://s3.bmp.ovh/imgs/2023/01/01/9815a1854c8bffa4.gif" alt="bug复现"></p><p> 可以明显看到,在搜狗拼音输入法<strong>还没有完成输入的时候</strong>就已经触发搜索了,此时根据拼音内容(一些英文)去搜索,会搜索不到任何结果,导致 Table 内显示空信息。</p><p> 这明显不是我们想要的效果,我们所希望的应该是在<strong>输入法完成输入(按下空格或回车)</strong>后,再去触发搜索框的搜索。</p><h1 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h1><blockquote><p>onCompositionStart & onCompositionEnd</p></blockquote><p> <a href="https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent">这两个事件</a>确实第一次接触,以 <code>compositionstart event</code> 为例:</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/01/577af882fddac58b.jpg" /></div><center style="color:#C0C0C0;">MDN 对 compositionstart event 的解释</center><p> 简单来说,搜狗拼音输入法就是图中所说的 <code>IME(Input Method Editor)</code> ,当开启一段 <code>composition session</code> 的时候就会触发这个事件,至于什么是 <code>composition session</code> 呢~</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/01/a4202af698e488f7.jpg" /></div> <p> 知道有这个 event 之后,一切也就豁然开朗了,我们可以引入一个 <code>lock</code> 变量,通过 <code>onCompositionStart</code> & <code>onCompositionEnd</code> 来维护;当且仅当 <code>lock</code> 为 <code>false</code> 的时候才触发搜索~</p><h1 id="(伪)代码"><a href="#(伪)代码" class="headerlink" title="(伪)代码"></a>(伪)代码</h1><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><<span class="title class_">Input</span></span><br><span class="line"> onChange={<span class="function"><span class="params">e</span> =></span> <span class="title function_">setInputVal</span>(e.<span class="property">target</span>.<span class="property">value</span>)}</span><br><span class="line"> onCompositionStart={<span class="function">() =></span> <span class="title function_">setLock</span>(<span class="literal">true</span>)}</span><br><span class="line"> onCompositionEnd={<span class="function">() =></span> <span class="title function_">setLock</span>(<span class="literal">false</span>)}</span><br><span class="line">/></span><br></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">useEffect</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="comment">// 输入拼音的情况下,选择了文字才搜索,正在输入拼音时不触发搜索</span></span><br><span class="line"> !lock && <span class="title function_">triggerSearch</span>(inputVal);</span><br><span class="line">}, [lock, inputVal]);</span><br></pre></td></tr></table></figure><h1 id="最终效果"><a href="#最终效果" class="headerlink" title="最终效果"></a>最终效果</h1><p><img src="https://s3.bmp.ovh/imgs/2023/01/01/4e3fad241e7bdbe7.gif" alt="最终效果"></p><h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p> 之前我一直以为这不是个前端范畴的问题,是系统层面的,事实证明还是认知局限呀🤣今后还是要多多学习,多多记录。</p>]]></content>
<summary type="html"><h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p> 最近开发遇到了一个很 tricky 的问题,直接上 gif,看了就明白了:</summary>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/categories/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="JavaScript" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/JavaScript/"/>
</entry>
<entry>
<title>提前转正啦😝丨一些回忆与复盘</title>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/post/ba9d0ab6.html"/>
<id>https://yyx-the-oracle-github-io-g1lc.vercel.app/post/ba9d0ab6.html</id>
<published>2022-11-29T12:32:59.000Z</published>
<updated>2023-09-10T15:59:51.335Z</updated>
<content type="html"><![CDATA[<p> 提前转正啦!!!<span id="more"></span></p><p> 这段时间有太多想记录分享的,但随着相册里的照片越积越多却又一直没整理,原本设想的月度复盘最终演变成了这样一篇转正综述😝。</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/01/348a1c73b181211b.jpg" /></div><p> <br> 简单 self review 了一下,相比五个月前的自己,最大的进步来自于四个方面:</p><h2 id="对-Stack-Overflow、GitHub-等社区的使用"><a href="#对-Stack-Overflow、GitHub-等社区的使用" class="headerlink" title="对 Stack Overflow、GitHub 等社区的使用"></a>对 <code>Stack Overflow</code>、<code>GitHub</code> 等社区的使用</h2><p> 本科期间对这些社区的使用仅限于嫖开源项目,现在逐渐能根据业务导向去探索一些解决方案了,也慢慢能够将宽泛的业务需求总结成一个个 one-sentence question 去寻找一些最佳实践。相比从前只能在 CSDN 的屎山里遨游,似乎感觉自己慢慢有 web developer 的感觉了🤣。</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/01/67567e71fe07a63f.jpg" /></div><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/01/81e92460b7d40c20.png" /></div><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/01/950f21c9e2c2ba7e.png" /></div><center style="color:#C0C0C0;">一次完整的提 issue -> 被响应 -> 解决业务问题的经历😁</center><h2 id="面对业务难题的心态"><a href="#面对业务难题的心态" class="headerlink" title="面对业务难题的心态"></a>面对业务难题的心态</h2><p> 如果要选这五个月来最难的一个需求,我觉得是贡献度页面的 PDF 下载——用从未使用过的库(html2canvas & jspdf)去完成一个定制化很高的需求。<br> 拆开看其实就是两个大难点——<code>从未使用过</code> & <code>定制化很高</code>。<br> 前者还好,只需要花时间去读文档试 API;但对于后者,则意味着网上不会有完全可以参照的解决方案。</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/01/d9569f63653b0f6b.png" /></div><center style="color:#C0C0C0;">需要实现的 PDF 下载逻辑</center><p> 官方文档的目的是用最简示例让你明白核心 API 的用法,但如何去组合可用的几十上百个 API 来完成业务需求,这个是官方文档没法 cover 到的。记得刚开始做的时候确实毫无头绪,后来真的是某个瞬间突然有了想法:html2canvas 是基于 DOM node 的,那我结合业务需求去手动控制 DOM node 是不是就可以了呢?后来尝试了一个简单的 case 发现确实可以!<br> 有了大方向,后面去磨逻辑就可以了,细节会非常多,但到了这个阶段,其实已经演变成了和第一个难点同一级别的问题了——花时间就可以解决的问题,俗称体力活🤣。<br> 这个需求完成之后,有种完成进化的感觉。</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/01/9ee08fc73213ee7b.png" /></div><center style="color:#C0C0C0;">完成后提的 PR </center><p> quote 一下关于这件事的微博,记录了我的思考: </p><blockquote><p> 最近刚做完一个比较特殊的导出 PDF 需求,用的两个库都是第一次接触( <code>html2canvas</code> & <code>jspdf</code> ),一路上遇到了不少坑,最后都摸索着解决了。作为一个喜欢复盘的人,本来想着好好复盘一下这两个库的使用流程,但是后来好像就突然醒悟了:为什么要去细抠这两个库呢,在未来十几年开发生涯里用到这两个库的次数大概率屈指可数,真正有价值的其实是那些坑,是那些开发过程中的瓶颈,或者说,是跨过坑和迈过瓶颈的思考过程和处理方法。<br> 其实是一个很简单的道理,相比聚焦于某个具体问题。作为一名工程师,需要培养的其实是解决问题的能力。从而达到一种 mentality:</p><ul><li>任何问题都有解决的方法</li><li>我遇到的问题也是</li><li>我一定可以解决它</li></ul></blockquote><h2 id="bug-的分析-amp-调试"><a href="#bug-的分析-amp-调试" class="headerlink" title="bug 的分析 & 调试"></a>bug 的分析 & 调试</h2><p> 这点或许就是所谓的<code>经验</code>,开发年限久了,见识的场景多了,改 bug 的能力就自然而然提升了。<br> 就我的例子而言,反映在对组件渲染、状态流动、异步有了更深的认识,所以打断点越来越准确,定位问题越来越快了。<br> 此外,也离不开其他前端家人们的 code review 与 comments,我在解决完一些比较 tricky 的 bug 的时候都会尽可能把心路历程和来龙去脉写在 commit message 里,我觉得能把原因-分析-解决的链路描述清楚,才算真正地吃透了这个 bug;此外,一般的 code review 大家只会看代码的风格是否可以优化,没太多时间去细究内部的业务逻辑(大家手头都有活),但有了比较详尽的 description 之后能让 reviewer 更好地理解场景,有时他们会提供一些更好的思路,让我发现其实是我搞复杂了。</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/01/77a43966a42615c8.jpg" /></div><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/01/88a60611ae1fd1c0.jpg" /></div><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/09/52c0372248e27ab5.jpg" /></div><center style="color:#C0C0C0;">解决一些 tricky bug 的 PR </center><h2 id="技术文档的书写"><a href="#技术文档的书写" class="headerlink" title="技术文档的书写"></a>技术文档的书写</h2><p> 像<code>大字版</code>和<code>埋点</code>这两个需求,我算是前端的 owner,从调研技术实现,到这两个模块的基建,再到书写文档和各位前端家人一起维护,有体验到一种 leadership 的感觉,是一种从未有过的体验😁。</p><div align=center> <img src="https://i.niupic.com/images/2022/12/31/aetL.jpg" /></div><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNq.png" /></div><center style="color:#C0C0C0;">埋点的基建 & 文档</center> <div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNp.png" /></div><center style="color:#C0C0C0;">大字版文档</center><p> 包括在做某个功能的时候需要复用一个很复杂的组件,在确定复用方案上我也接受了<a href="https://liriansu.com/">紫月老师</a>的建议,写了篇文档把两种方式做了对比,最终和大家讨论选取了一个更适合的方案。</p><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNr.jpg" /></div><center style="color:#C0C0C0;">关于复用方案的评估文档</center><p> 把零碎的思路形成易于接受的、有条理的文字是一件很浪漫的事情。(顺便感叹一句飞书文档真的好用,国庆去敦煌做了份<a href="https://hzt1zdrg2z.feishu.cn/docx/Kz4rd8NBQopGH4xggircbhuhnqc?from=from_copylink">攻略</a>,一开始用的是 Google Docs,不是很顺手,换飞书文档之后体验大大提升,强烈安利😋)</p><h2 id="End"><a href="#End" class="headerlink" title="End"></a>End</h2><p> 下班之后随手写了点,anyway,保持热爱,继续前进!</p>]]></content>
<summary type="html"><p> 提前转正啦!!!</summary>
<category term="随笔" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/categories/%E9%9A%8F%E7%AC%94/"/>
<category term="随笔" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/%E9%9A%8F%E7%AC%94/"/>
</entry>
<entry>
<title>或许遭遇了人生最大的 setback ?</title>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/post/7709adb1.html"/>
<id>https://yyx-the-oracle-github-io-g1lc.vercel.app/post/7709adb1.html</id>
<published>2022-06-13T15:11:01.000Z</published>
<updated>2023-09-10T15:59:24.043Z</updated>
<content type="html"><![CDATA[<p> 6.7,毕设答辩结束后两个小时,明略告知我要毁约,仿佛当头一棒。<span id="more"></span><br> 其实前两周在脉脉已经听到了些风声,大致是说公司动用 1500 人做了一年半的产品 (EIP) 失败了,疫情和外部环境雪上加霜,公司现金流已极度不健康,要裁员 70%,3500 人的公司只留 800 人。</p><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNt.jpg" width=256 /></div><center style="color:#C0C0C0;">CEO 发的全体邮件</center><p> 即使消息一直在发酵,我还是相对乐观,因为那些爆料人也说了,秒针(我们部门)作为独立的核心部门,是不会有大动作的。</p><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNu.jpg" width=256 /></div><center style="color:#C0C0C0;">看着明略的同事圈热度一路飙升</center><p> 而且,我去提前实习了近四个月,如期完成了布置给我的所有开发任务,出色地融入了团队,就算真的要毁约一批校招生,相比那些没去提前实习的同学,我也有绝对的优势能够留下。<br> 最后,也是一丝侥幸心理,6 月份了,即使公司再没有人性,也做不出在毕业前两个礼拜毁约的举动吧,这不仅是毁人前途,也是断人后路。<br> 但还是发生了,击碎了我最后的幻想。</p><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNv.jpg" /></div><center style="color:#C0C0C0;">甚至在 5.23 还发了入职提示邮件</center><p> 好笑的是,在被毁约的前一天,我都还在为相同遭遇的应届生们抱不平。</p><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNw.jpg" width=300 /></div><center style="color:#C0C0C0;">一语成谶</center><p> 7 号下午我处在崩溃的边缘,我的理性压制着杂乱稀碎的情绪,我努力告诉自己,去消化这个消息,去做对当下最好的决定。<br> 我在找一个可以发泄的点,尝试将这个结果归咎于我的某一个错误决定或举动,但我找不到。<br> 从去年 3 月份开始,我刷了五十多套视频,背了无数的面经八股,从 9.7 第一场面试开始,20 天拿到了 3 份 offer,10.9 明略正式给我开了 30k 的意向书,我觉得秋招圆满收官了,也拒绝了此后的所有笔面试流程。</p><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNx.jpg" /></div><center style="color:#C0C0C0;">结束我秋招的 offer</center><p> 我开始帮朋友们辅导面试、和他们分享学习路线、解决群友们的开发问题。这份 offer 让我保持着学习的热情,让我愿意放弃最后的校园生活去公司提前适应。公司的一切也让我无比满意,顶级的办公环境、前沿的技术栈、扁平的团队氛围、还有知无不言、贴心带着我成长的 mentor。</p><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNy.jpg" width=500 /></div><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNz.jpg" width=500 /></div><center style="color:#C0C0C0;">那时候确实很热爱这里</center><br/><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNA.jpg" width=500 /></div><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNB.jpg" width=500 /></div><center style="color:#C0C0C0;">津铭哥对我真的很好</center> <p> 我曾经跑在前面,但一个解约电话和一份违约金让我回到了起点。<br> 这就是绝境了吧?秋招的另外两份 offer 询问后被告知已经没有 hc 了,形势本就惨淡的春招完全结束,补录也所剩无几,即使还有面试机会,实习之后的我专注于业务,用来应付笔面试的八股文和算法也已淡忘生疏。<br> 更何况,离毕业只有 20 天了,要去公司办离职手续,走毁约流程,要去了解封校期间的就业办政策,处理毕业事宜,要投简历,要去捡起淡忘的八股文和算法,我问自己,这怎么可能办得到呢。<br> 曾经的野心和理想开始反噬我,我从未陷入过这个程度的自我怀疑。<br> 晚上,我收拾了一下情绪,开始检索各个招聘平台,牛客、毕业申、智联、boss,我投递了所有还能投递的公司。<br> 8 号醒的时候天还黑着,看了眼手机 4 点多,但没有了睡意,起床开始看秋招时的面经和笔记。上午开始陆续有 hr 联系我。第一个面试在下午两点半,五位面试官,持续一个多小时,一面过。晚上七点,另一家公司,将近一个小时,一面过。我屏蔽了所有的社交媒体,不让自己的思绪有一丝空闲,我怕那种随之而来的窒息感。<br> 随着 9 号两场面试的通过,我的状态好些了,但更开心的是遇到了心仪的公司:在淮海中路,位置热闹、技术栈前沿,leader 是保送交大的竞赛生,hr 给我分享了他的博客,映入眼帘的第一篇:《那个喊了十三声发物资的邻居》,翻到最下面,看到一篇 2013 年的文章:《妈的,交大》,我的第一感觉:他是个有趣的人。面试的时候他也让我感受到了一种和那些生硬地问一个个技术问题的面试官不同的感觉。腾讯会议里还有另一位女生,他告诉我,这位女生本科也是交大,硕士在密歇根大学,同样是今年的校招生,如果我加入,以后大家就是同一个 team 了,我说,我喜欢和优秀的人在一起。在我一面通过并表达强烈的加入愿景之后,他也承诺会为我加快推进流程。<br> 9 号晚上做完了笔试,10号下午 cto 面 + hr 面,晚上 6 点半等来了 offer call。<br> 放下手机,也许是这几天没怎么休息,有些恍惚。两天前我以为最终的结局或许就是要去国企或者某个小厂冒着野心和技术慢慢被消磨的风险去沉淀(如果消磨太多的话或许是沉沦?)两三年,幸好,现在又有了在互联网泥沼里摸爬滚打的机会。我联系了其他几家的 hr,表示已经接到了合适的 offer,也对他们表达了最诚挚的感谢,在这个时间点给了我面试的机会,让我不至于沉浸在惶恐却什么都做不了的绝望情绪里。<br> 这几天也让我明确了一些事,好像也就两件,第一件就是去搭一个博客,我会把这篇放上去,作为第一篇文章。我突然联想到高中,当时想着要写写日记,但一直没开始,后来第一次下笔是在 2015.11.11,因为那天月考还是期中考成绩出来了,我数学没及格,很伤心,突然就有了下笔的冲动,没想到就坚持了下来,每天晚自修的最后十分钟写个几行,坚持了三年。或许这次也是个开始的契机吧。说到这个就想起来日记本还在上大寝室的架子上,不知道啥时候才能回去搬寝室。<br> 第二件事情就是,应该再也没有过不去的坎了,至少我现在是这样觉得的。<br> 还有很多事情要处理,先写到这吧。</p>]]></content>
<summary type="html"><p> 6.7,毕设答辩结束后两个小时,明略告知我要毁约,仿佛当头一棒。</summary>
<category term="随笔" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/categories/%E9%9A%8F%E7%AC%94/"/>
<category term="随笔" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/%E9%9A%8F%E7%AC%94/"/>
</entry>
<entry>
<title>修改 antd 组件默认样式的坑丨:global 关键字</title>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/post/30ad5bee.html"/>
<id>https://yyx-the-oracle-github-io-g1lc.vercel.app/post/30ad5bee.html</id>
<published>2022-04-25T06:43:55.000Z</published>
<updated>2023-09-10T15:59:51.329Z</updated>
<content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p> 今天做一个 Modal 的时候,需要修改 antd Form 的一些默认样式。一开始感觉没啥问题,用 Chrome DevTools 在页面上找到 antd 组件内相应的元素,修改对应的 class 达到效果后复制到了 VSCode 里,但是,<strong>页面完全没有变化!!!!!!!</strong> <span id="more"></span></p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/02/3b7d499d006810f0.jpg" /></div><center style="color:#C0C0C0;"> less 代码</center><p> 钻了 20 分钟没解决,赶紧去问 mentor, 津铭哥笑着和我说需要在外层加一个 <code>:global</code> 才能生效,试了下还真是!赶紧去补了下这个关键字的知识,在这里做一个记录。</p><h1 id="坑"><a href="#坑" class="headerlink" title="坑"></a>坑</h1><blockquote><p> 在 React 项目中使用 scss/less,如果想让样式仅作用在某个组件,而不影响全局,一般都会把样式文件进行<strong>模块化</strong>,即打包后每个 class 名都会被自动<strong>加上一串唯一的序列号</strong>。</p></blockquote><p>举个例子:</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.main</span> {</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">100px</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p> <br>模块化后打包的结果会是:</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.main__3D0Xe</span>{ <span class="attribute">width</span>: <span class="number">100px</span>; }</span><br></pre></td></tr></table></figure><p> <br> 而我们公司的框架自动做了样式的模块化,因此正是这串序列号导致无法正确选中 antd 组件内部元素的 class🤣。</p><h1 id="解决方法"><a href="#解决方法" class="headerlink" title="解决方法"></a>解决方法</h1><p> 如果不想要这串序列号,那么在最外层套上一层 <code>:global</code> 即可~</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/02/63710433b803b78f.jpg" /></div>]]></content>
<summary type="html"><h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p> 今天做一个 Modal 的时候,需要修改 antd Form 的一些默认样式。一开始感觉没啥问题,用 Chrome DevTools 在页面上找到 antd 组件内相应的元素,修改对应的 class 达到效果后复制到了 VSCode 里,但是,<strong>页面完全没有变化!!!!!!!</strong></summary>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/categories/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="antd" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/antd/"/>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="JavaScript" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/JavaScript/"/>
</entry>
<entry>
<title>回调函数也能主动调用丨antd Table 组件外实现全选 & 取消全选</title>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/post/d87f7e0c.html"/>
<id>https://yyx-the-oracle-github-io-g1lc.vercel.app/post/d87f7e0c.html</id>
<published>2022-04-23T10:54:37.000Z</published>
<updated>2023-09-10T15:59:51.329Z</updated>
<content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p> 最近在做宝马的一个项目,需要实现 Table 的全选 & 取消全选,原型图如下:<span id="more"></span></p><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aevg.jpg" /></div><center style="color:#C0C0C0;">原型图</center><p> 然而,<a href="https://ant.design/components/table-cn?theme=dark#components-table-demo-row-selection-custom">antd 官网给的例子</a>里只有在组件中的实现方法(自定义选择项——通过 <code>rowSelection.selections</code> 配置),如下图:</p><div align=center> <img src="https://i.niupic.com/images/2023/01/01/aeNs.jpg" /></div><center style="color:#C0C0C0;">antd 提供的功能</center><p> 如果想要做到原型图这样在组件外实现全选 & 取消全选,则需要更灵活地运用 <code>rowSelection</code> 这个配置项。</p><h1 id="Talk-is-cheap-show-me-the-code"><a href="#Talk-is-cheap-show-me-the-code" class="headerlink" title="Talk is cheap, show me the code!"></a>Talk is cheap, show me the code!</h1><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> [selectedRowKeys, setSelectedRowKeys] = <span class="title function_">useState</span>([]);</span><br><span class="line"><span class="keyword">const</span> [selectedRows, setSelectedRows] = <span class="title function_">useState</span>([]);</span><br><span class="line"><span class="keyword">const</span> [tableData, setTableData] = <span class="title function_">useState</span>([]);</span><br><span class="line"></span><br><span class="line"><span class="title function_">useEffect</span>(<span class="function">() =></span> {</span><br><span class="line"> <span class="title function_">setTableData</span>(mock); <span class="comment">// 将 tableData 先设为表格内的全部数据</span></span><br><span class="line">}, []); </span><br><span class="line"></span><br><span class="line"><span class="comment">// 关键点:这个函数既作为回调函数,也能手动调用~</span></span><br><span class="line"><span class="keyword">const</span> <span class="title function_">handleChange</span> = (<span class="params">selectedRowKeys, selectedRows</span>) => {</span><br><span class="line"> <span class="title function_">setSelectedRowKeys</span>([...selectedRowKeys]);</span><br><span class="line"> <span class="title function_">setSelectedRows</span>([...selectedRows]);</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">// 点击 选择全部 的回调函数</span></span><br><span class="line"><span class="keyword">const</span> <span class="title function_">selectAll</span> = (<span class="params"></span>) => {</span><br><span class="line"> tableData.<span class="title function_">forEach</span>(<span class="function">(<span class="params">o, i</span>) =></span> {</span><br><span class="line"> <span class="comment">// 遍历,和全部的 tableData 作对比,找到没有勾选的 row, 将它的 key 值保存到 selectedRowKeys 数组</span></span><br><span class="line"> <span class="keyword">if</span> (!selectedRows.<span class="title function_">includes</span>(o)) selectedRowKeys.<span class="title function_">push</span>(tableData[i].<span class="property">account</span>);</span><br><span class="line"> });</span><br><span class="line"> <span class="comment">// 手动修改 selectedRowKeys,和 Table 组件内的 selectedRowKeys 联动</span></span><br><span class="line"> <span class="title function_">handleChange</span>(selectedRowKeys, [...tableData]); </span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">// 点击 取消全部 的回调函数</span></span><br><span class="line"><span class="keyword">const</span> <span class="title function_">selectNone</span> = (<span class="params"></span>) => {</span><br><span class="line"> <span class="comment">// 手动修改 selectedRowKeys 和 selectedRows,全部置为空</span></span><br><span class="line"> <span class="title function_">handleChange</span>([], []);</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> rowSelection = {</span><br><span class="line"> selectedRowKeys, <span class="comment">// 受控</span></span><br><span class="line"> <span class="attr">type</span>: <span class="string">"checkbox"</span>,</span><br><span class="line"> <span class="attr">onChange</span>: handleChange <span class="comment">// 将 handleChange 定义在外面,从而可以手动调用</span></span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">// Table 组件,略去了无关配置</span></span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">Table</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">rowKey</span>=<span class="string">"account"</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">columns</span>=<span class="string">{columns}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">dataSource</span>=<span class="string">{mock}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml"> <span class="attr">rowSelection</span>=<span class="string">{rowSelection}</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">/></span></span></span><br></pre></td></tr></table></figure><h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p> 其实最关键的地方在于 <code>rowSelection</code> 里的 <code>onChange</code> ,通常的回调函数我们不会直接调用,而在这里,如果要实现在表格外全选,则需要手动调用这个 <code>onChange</code> 。</p><h1 id="2023-1-21-更新"><a href="#2023-1-21-更新" class="headerlink" title="2023.1.21 更新"></a>2023.1.21 更新</h1><p> 最近做了个需求,需要在一个 form 中做三个字段间的联动:<br><img src="https://s3.bmp.ovh/imgs/2023/01/21/b2126d6f58801b38.gif" alt="搜索反馈 form 联动"></p><p> 期间遇到了<code>form.setFieldsValue 不会触发控件 onChange</code>的问题,找到了一个<a href="https://www.cnblogs.com/xinyouhunran/p/15578373.html">解决方案</a>,和我这篇文章的思路挺像的,也是需要<code>手动触发一个回调函数</code>,在这里更新记录一下。</p>]]></content>
<summary type="html"><h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p> 最近在做宝马的一个项目,需要实现 Table 的全选 &amp; 取消全选,原型图如下:</summary>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/categories/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="antd" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/antd/"/>
<category term="前端开发" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
<category term="JavaScript" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/JavaScript/"/>
</entry>
<entry>
<title>傻逼上海国拍丨拍到牌照后的操蛋付款经历</title>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/post/47e794c4.html"/>
<id>https://yyx-the-oracle-github-io-g1lc.vercel.app/post/47e794c4.html</id>
<published>2021-07-27T06:48:49.000Z</published>
<updated>2023-09-10T15:59:51.328Z</updated>
<content type="html"><![CDATA[<p> <br> 24 号拍中了牌照,今天早上和我爸去工行兴冲冲地进行一个付款动作,但没想到上海国拍这个线上支付是真的傻逼,搞了三个多小时才弄好,期间更是遇到了无数个坑🤣记录一下踩坑经历,和我一样离<a href="https://www.alltobid.com/">线下付款点(黄浦区福州路 108 号)</a>比较远,懒得特地为付款跑一趟的朋友们可以参考。<span id="more"></span></p><h1 id="TL-DR"><a href="#TL-DR" class="headerlink" title="TL;DR"></a>TL;DR</h1><p> 线上支付的懒人包(工行版):</p><ul><li>前往就近的工行网点。</li><li>手机是无法支付的,带上电脑,下载好<code>旧版的 IE 浏览器</code>。</li><li>打消直接使用银联卡支付的念头,花 70 元购买 <code>U 盾</code>。</li><li>使用 U 盾前需要下载<code>安全证书</code>,如果页面上下载安全证书的链接点击后闪退,请工作人员在工行 app 上下载<code>蓝牙安全证书</code>。</li><li>使用 U 盾前需要下载<code>安全控件</code>,如果页面上的下载弹窗无法下载,前往<a href="https://corporbank-simp.icbc.com.cn/icbc/normalbank/index.jsp">工行网银官网</a>,点击页面最下方<code>网银助手</code>的链接进行下载。</li><li>付款吧!</li></ul><h1 id="设备的坑"><a href="#设备的坑" class="headerlink" title="设备的坑"></a>设备的坑</h1><p> 首先移动端的 app 是支付不了的,意味着手机无法操作,<code>只能通过 PC 端付款</code>;</p><p> 然后,和上大的毕设管理网站一样,<code>只能用老 IE 登录</code>,Edge,Chrome 和火狐等现代浏览器都无法成功进入付款界面。</p><h1 id="付款界面的坑"><a href="#付款界面的坑" class="headerlink" title="付款界面的坑"></a>付款界面的坑</h1><p> 进入付款页面后可以直接忽略页面上的付款流程, 应该是 2015 年以前的版本没更新。2015 年 2 月 15 日之后银联卡有了 <code>5 万元的单日/单笔支付限额</code>,但沪牌价格要 9w+,根本不能直接付款。(和使用哪家银行的银行卡没有关系,三个付款选项除了分期付款,其他两个都是银联,就会存在 5 万的额度上限)</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/02/fe8ccb306eca03a4.jpg" /></div><center style="color:#C0C0C0;">支付页面超额报错</center><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/02/4af49c4dc56478c3.jpg" /></div><center style="color:#C0C0C0;">论坛上关于这个报错的讨论</center><p> 报错之后我去工行网点加了卡的额度,<code>但还是会显示超额</code>,心态第一次炸裂😑。</p><p> 本来已经打算放弃线上支付了,工作人员让我试试 U 盾,没想到又是一条新的踩坑之路。</p><h1 id="使用-U-盾的坑"><a href="#使用-U-盾的坑" class="headerlink" title="使用 U 盾的坑"></a>使用 U 盾的坑</h1><p> 花了 70 搞了个 U 盾,使用之前需要下载安全证书,但估计是 IE 的问题,<code>安全证书的下载链接一点击就会闪退</code>,刚开始尝试就遇到了阻塞性的 bug,心态第二次炸裂😑。</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/02/c7dda2a901e653b2.jpg" /></div><center style="color:#C0C0C0;">U 盾需要下载安全证书</center><p> 但又出现了转机,一个年轻小哥和我说工行 app 也能下载安全证书,经过他的操作,15 分钟后我拥有了一个<code>蓝牙安全证书</code>,从而能够继续尝试下去。</p><p> 接下来跳出了一个弹窗,提示我安装一个安全控件,点了确定之后会出来一个另一个弹窗,此时<code>不管你点重试还是取消选项都会自动退出网银登录</code>,而每次重登都要输身份证手机号验证码,来回搞了七八次还是没有装成功,心态第三次炸裂😑。</p><p> 我问工作人员官网能不能下这玩意,工作人员说好像可以,于是我上官网寻找,首先没有任何提示性的信息,其次在搜索框搜关键词也没有任何结果,找了大概有十几分钟<code>才发现在他妈的页面最下面</code>,这到底是哪个反人类的 UX 设计的,这么关键的东西是真的一点指引都没有啊!!</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/02/35bf0d7239ff4d69.jpg" /></div><center style="color:#C0C0C0;">页面没有任何提示,藏在最下面</center><p> 这个下完之后总算成功支付了,我安慰自己,不断折腾也是人生的意义😑。</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/02/1de2f2f521d4862b.jpg" /></div><center style="color:#C0C0C0;">终于付款成功</center><h1 id="End"><a href="#End" class="headerlink" title="End"></a>End</h1><p> 拍牌已经够难的了,没想到付个款也能这么 disgusting🤣。</p>]]></content>
<summary type="html"><p> <br> 24 号拍中了牌照,今天早上和我爸去工行兴冲冲地进行一个付款动作,但没想到上海国拍这个线上支付是真的傻逼,搞了三个多小时才弄好,期间更是遇到了无数个坑🤣记录一下踩坑经历,和我一样离<a href="https://www.alltobid.com/">线下付款点(黄浦区福州路 108 号)</a>比较远,懒得特地为付款跑一趟的朋友们可以参考。</summary>
<category term="随笔" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/categories/%E9%9A%8F%E7%AC%94/"/>
<category term="随笔" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/%E9%9A%8F%E7%AC%94/"/>
</entry>
<entry>
<title>东决 G6 和西部半决 G6丨东詹和西詹的不同命运</title>
<link href="https://yyx-the-oracle-github-io-g1lc.vercel.app/post/6308cf93.html"/>
<id>https://yyx-the-oracle-github-io-g1lc.vercel.app/post/6308cf93.html</id>
<published>2019-05-11T08:16:35.000Z</published>
<updated>2023-09-10T15:59:51.328Z</updated>
<content type="html"><![CDATA[<p> 比赛结束之后才刷到杨毅老师在 G6 赛前发的这篇微博,突然就很感慨。<span id="more"></span></p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/02/55e26e1943cdfb9c.jpg" /></div><p> 我第一时间就联想到了 12 年东决 G6 ,因为这两场比赛的结果都不只是停留在那一场或是那一轮系列赛,而是会影响一个巨星二三十年后的定义。</p><p> 况且,两场比赛的主角名字里都带詹姆斯,也算是个奇妙的联结。</p><p> 毋庸置疑的是勒布朗詹姆斯当时的处境比现在的詹姆斯哈登还要艰难的多,在 10 年休赛期与韦德、波什组成三巨头后,那支热火成为了真正意义上的全民公敌:除了迈阿密的球迷,其余 29 队的球迷都希望热火一败涂地,希望詹姆斯终身无冠。</p><p> 也真的如大家所愿,11 年总决赛,那支热火被老司机带着一群暮年球员击溃。随着诺维斯基彻底摆脱了软蛋的骂名,詹姆斯成为了全联盟的笑柄。</p><p> 无法想象那个休赛季詹姆斯是如何承受漫天的质疑和嘲讽的,很明显,下个赛季如果再不夺冠,三巨头必将解散,詹姆斯将万劫不复。</p><p> 11-12 赛季,热火东部第二,东决将对阵曾经多次淘汰詹姆斯的凯尔特人队。尽管热火先下两城,但却被老辣的绿军连扳三场,濒临淘汰。</p><p> G6,在绿军的死亡主场,漫天嘘声。</p><p> 结局我们都知道,詹姆斯砍下 45+15+5,还有那个著名的死亡之瞳。热火将比赛拖入抢七并击败绿军,又势如破竹地在总决赛轻取年轻的雷霆,詹姆斯拿到了生涯第一个冠军戒指,从那时开始了逐神之路。</p><div align=center> <img src="https://s3.bmp.ovh/imgs/2023/01/02/ff936035a83250ad.jpg" /></div><center style="color:#C0C0C0;">死亡之瞳</center><p> 今天的 G6,火箭主场,全场助威。印象深刻的是一个球迷举的牌子: “The best gift for Mother’s Day is G7.”</p><p> 但结果我们也知道了,在考辛斯和杜兰特伤退,库里受手指影响上半场 0 分的情况下,火箭仍然被击败,可能丧失了哈登核心时代最后的夺冠希望。</p><p> 并非要黑哈登,只是这场 G6 和哈登前几年的季后赛表现很可能会被反复拿出来衡量哈登的历史地位。而且如果,我说如果,在今天如此天时地利人和的情况下火箭击败了勇士,那大概率很多事情就不一样了。就像詹姆斯如果输掉了 12 年的那场东决,那么也不会有如今坐二望一的评价了。</p><p> 这场比赛很可能让哈登在命运的十字路口迈向了一条不那么美好的路。</p>]]></content>
<summary type="html"><p> 比赛结束之后才刷到杨毅老师在 G6 赛前发的这篇微博,突然就很感慨。</summary>
<category term="随笔" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/categories/%E9%9A%8F%E7%AC%94/"/>
<category term="随笔" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/%E9%9A%8F%E7%AC%94/"/>
<category term="NBA" scheme="https://yyx-the-oracle-github-io-g1lc.vercel.app/tags/NBA/"/>
</entry>
</feed>