-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
505 lines (328 loc) · 398 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
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>时光的涂鸦墙</title>
<subtitle>code is poetry</subtitle>
<link href="/blog/atom.xml" rel="self"/>
<link href="https://lingmissing.github.io/"/>
<updated>2019-01-08T02:40:44.050Z</updated>
<id>https://lingmissing.github.io/</id>
<author>
<name>elaine</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>MutationObserver 监听 DOM 树变化</title>
<link href="https://lingmissing.github.io/2019/01/08/mutation-observer/"/>
<id>https://lingmissing.github.io/2019/01/08/mutation-observer/</id>
<published>2019-01-08T02:32:07.000Z</published>
<updated>2019-01-08T02:40:44.050Z</updated>
<content type="html"><![CDATA[<p><code>MutationObserver</code> 是用于代替 <code>MutationEvents</code> 作为观察 <code>DOM</code> 树结构发生变化时,做出相应处理的 <code>API</code> 。为什么要使用 <code>MutationObserver</code> 去代替 <code>MutationEvents</code> 呢,我们先了解一下 <code>MutationEvents</code></p><a id="more"></a><h2 id="MutationEvents"><a href="#MutationEvents" class="headerlink" title="MutationEvents"></a>MutationEvents</h2><p>它简单的用法如下:</p><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><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">document</span>.getElementById(<span class="string">'list'</span>).addEventListener(</span><br><span class="line"> <span class="string">'DOMSubtreeModified'</span>,</span><br><span class="line"> () => {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'列表中子元素被修改'</span>)</span><br><span class="line"> },</span><br><span class="line"> <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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// Mutation 事件列表</span></span><br><span class="line">DOMAttrModified <span class="comment">// 监听元素的修改</span></span><br><span class="line">DOMAttributeNameChanged</span><br><span class="line">DOMCharacterDataModified</span><br><span class="line">DOMElementNameChanged</span><br><span class="line">DOMNodeInserted <span class="comment">// 监听新增</span></span><br><span class="line">DOMNodeRemoved <span class="comment">// 监听删除</span></span><br><span class="line">DOMNodeInsertedIntoDocument</span><br><span class="line">DOMSubtreeModified <span class="comment">// 监听子元素的修改</span></span><br></pre></td></tr></table></figure><p>其中 <code>DOMNodeRemoved</code> ,<code>DOMNodeInserted</code> 和 <code>DOMSubtreeModified</code>分别用于监听元素子项的删除,新增,修改(包括删除和新增),<code>DOMAttrModified</code> 是监听元素属性的修改,并且能够提供具体的修改动作。</p><p><strong>Mutation Events 遇到的问题</strong></p><ul><li>IE9 不支持 <code>MutationEvents</code>。Webkit 内核不支持 <code>DOMAttrModified</code> 特性,<code>DOMElementNameChanged</code> 和 <code>DOMAttributeNameChanged</code> 在 Firefox 上不被支持。</li><li>性能问题 1. <code>MutationEvents</code> 是同步执行的,它的每次调用,都需要从事件队列中取出事件,执行,然后事件队列中移除,期间需要移动队列元素。如果事件触发的较为频繁的话,每一次都需要执行上面的这些步骤,那么浏览器会被拖慢。 2. <code>MutationEvents</code> 本身是事件,所以捕获是采用的是事件冒泡的形式,如果冒泡捕获期间又触发了其他的 <code>MutationEvents</code> 的话,很有可能就会导致阻塞 Javascript 线程,甚至导致浏览器崩溃。</li></ul><h2 id="Mutation-Observer"><a href="#Mutation-Observer" class="headerlink" title="Mutation Observer"></a>Mutation Observer</h2><p><code>MutationObserver</code> 是在 <code>DOM4</code> 中定义的,用于替代 <code>MutationEvents</code> 的新 API,它的不同于 events 的是,所有监听操作以及相应处理都是在其他脚本执行完成之后异步执行的,并且是所以变动触发之后,将变得记录在数组中,统一进行回调的,也就是说,当你使用 <code>observer</code> 监听多个 DOM 变化时,并且这若干个 DOM 发生了变化,那么 <code>observer</code> 会将变化记录到变化数组中,等待一起都结束了,然后一次性的从变化数组中执行其对应的回调函数。</p><p><strong>特点</strong></p><ul><li>所有脚本任务完成后,才会运行,即采用异步方式</li><li>DOM 变动记录封装成一个数组进行处理,而不是一条条地个别处理 DOM 变动。</li><li>可以观察发生在 DOM 节点的所有变动,也可以观察某一类变动</li></ul><p>目前,Firefox(14+)、Chrome(26+)、Opera(15+)、IE(11+) 和 Safari(6.1+) 支持这个 API。 Safari 6.0 和 Chrome 18-25 使用这个 API 的时候,需要加上 WebKit 前缀(WebKitMutationObserver)。可以使用下面的表达式检查浏览器是否支持这个 API。</p><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><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> MutationObserver =</span><br><span class="line"> <span class="built_in">window</span>.MutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.WebKitMutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.MozMutationObserver</span><br><span class="line"><span class="comment">// 监测浏览器是否支持</span></span><br><span class="line"><span class="keyword">var</span> observeMutationSupport = !!MutationObserver</span><br></pre></td></tr></table></figure><h2 id="如何使用-MutationObserver"><a href="#如何使用-MutationObserver" class="headerlink" title="如何使用 MutationObserver"></a>如何使用 MutationObserver</h2><p>在应用中集成 <code>MutationObserver</code> 是相当简单的。通过往构造函数 <code>MutationObserver</code> 中传入一个函数作为参数来初始化一个 <code>MutationObserver</code> 实例,该函数会在每次发生 DOM 发生变化的时候调用。<code>MutationObserver</code> 的函数的第一个参数即为单个批处理中的 DOM 变化集。每个变化包含了变化的类型和所发生的更改。</p><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><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> mutationObserver = <span class="keyword">new</span> MutationObserver(<span class="function"><span class="keyword">function</span>(<span class="params">mutations</span>) </span>{</span><br><span class="line"> mutations.forEach(<span class="function"><span class="keyword">function</span>(<span class="params">mutation</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(mutation)</span><br><span class="line"> })</span><br><span class="line">})</span><br></pre></td></tr></table></figure><p>创建的实例对象拥有三个方法:</p><ul><li><code>observe</code> -开始进行监听。接收两个参数-要观察的 DOM 节点以及一个配置对象。</li><li><code>disconnect</code> -停止监听变化。</li><li><code>takeRecords</code> -触发回调前返回最新的批量 DOM 变化。</li></ul><h3 id="observer-方法"><a href="#observer-方法" class="headerlink" title="observer 方法"></a>observer 方法</h3><p>observer 方法指定所要观察的 DOM 元素,以及要观察的特定变动。</p><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><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> article = <span class="built_in">document</span>.querySelector(<span class="string">'article'</span>)</span><br><span class="line">observer.observer(article, {</span><br><span class="line"> childList: <span class="literal">true</span>,</span><br><span class="line"> arrtibutes: <span class="literal">true</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure><p>上面代码分析:</p><ol><li>指定所要观察的 DOM 元素 article</li><li>指定所要观察的变动是子元素的变动和属性变动。</li><li>将这两个限定条件作为参数,传入<code>observer</code> 对象 <code>observer</code>方法。</li></ol><h3 id="disconnect-方法"><a href="#disconnect-方法" class="headerlink" title="disconnect 方法"></a>disconnect 方法</h3><ul><li>disconnect 方法用来停止观察。发生相应变动时,不再调用回调函数。</li></ul><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> MutationObserver =</span><br><span class="line"> <span class="built_in">window</span>.MutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.WebKitMutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.MozMutationObserver</span><br><span class="line"><span class="comment">// 选择目标节点</span></span><br><span class="line"><span class="keyword">var</span> target = <span class="built_in">document</span>.querySelector(<span class="string">'#some-id'</span>)</span><br><span class="line"><span class="comment">// 创建观察者对象</span></span><br><span class="line"><span class="keyword">var</span> observer = <span class="keyword">new</span> MutationObserver(<span class="function"><span class="keyword">function</span>(<span class="params">mutations</span>) </span>{</span><br><span class="line"> mutations.forEach(<span class="function"><span class="keyword">function</span>(<span class="params">mutation</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(mutation.type)</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">var</span> config = { <span class="attr">attributes</span>: <span class="literal">true</span>, <span class="attr">childList</span>: <span class="literal">true</span>, <span class="attr">characterData</span>: <span class="literal">true</span> }</span><br><span class="line"><span class="comment">// 传入目标节点和观察选项</span></span><br><span class="line">observer.observe(target, config)</span><br><span class="line"><span class="comment">// 随后,你还可以停止观察</span></span><br><span class="line">observer.disconnect()</span><br></pre></td></tr></table></figure><h3 id="takeRecord-方法"><a href="#takeRecord-方法" class="headerlink" title="takeRecord 方法"></a>takeRecord 方法</h3><p>takeRecord 方法用来清除变动记录,即不再处理未处理的变动。</p><p>在观察者对象上调用 <code>takeRecords</code> 会返回 其观察节点上的变化记录(MutationRecord)数组。其中 <code>MutationRecord</code> 数组也会作为,观察者初始化时的回调函数的第一个参数。</p><p>其包含的属性如下:</p><ul><li>type 如果是属性发生变化,则返回 <code>attributes</code>.如果是一个<code>CharacterData</code> 节点发生变化,则返回 <code>characterData</code> ,如果是目标节点的某个子节点发生了变化,则返回 <code>childList</code> .</li><li>target 返回此次变化影响到的节点,具体返回那种节点类型是根据 type 值的不同而不同的,如果 type 为 <code>attributes</code> ,则返回发生变化的属性节点所在的元素节点,如果 type 值为 <code>characterData</code> ,则返回发生变化的这个 characterData 节点.如果 type 为 <code>childList</code> ,则返回发生变化的子节点的父节点.</li><li>addedNodes 返回被添加的节点</li><li>removedNodes 返回被删除的节点</li><li>previousSibling 返回被添加或被删除的节点的前一个兄弟节点</li><li>nextSibling 返回被添加或被删除的节点的后一个兄弟节点</li><li>attributeName 返回变更属性的本地名称</li><li>oldValue 根据 type 值的不同,返回的值也会不同.如果 type 为 attributes,则返回该属性变化之前的属性值.如果 type 为 characterData,则返回该节点变化之前的文本数据.如果 type 为 childList,则返回 null</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">observer.takeRecord()</span><br></pre></td></tr></table></figure><h2 id="MutationObserver-类型"><a href="#MutationObserver-类型" class="headerlink" title="MutationObserver 类型"></a>MutationObserver 类型</h2><p><code>MutationObserver</code> 所观察的 DOM 变动(即上面代码的 option 对象),包含以下类型:</p><ul><li>childList:子元素的变动</li><li>attributes:属性的变动</li><li>characterData:节点内容或节点文本的变动</li><li>subtree:所有下属节点(包括子节点和子节点的子节点)的变动</li></ul><blockquote><p>想要观察哪一种变动类型,就在 option 对象中指定它的值为 true。<br>需要注意的是,不能单独观察 subtree 变动,必须同时指定 childList、attributes 和 characterData 中的一种或多种。</p></blockquote><p>除了变动类型,option 对象还可以设定以下属性:</p><ul><li>attributeOldValue:值为 true 或者为 false。如果为 true,则表示需要记录变动前的属性值。</li><li>characterDataOldValue:值为 true 或者为 false。如果为 true,则表示需要记录变动前的数据值。</li><li>attributesFilter:值为一个数组,表示需要观察的特定属性(比如[‘class’, ‘str’])。</li></ul><p>创建 <code>MutationObserver</code> 并 获取 dom 元素,定义回调数据。</p><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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 获取MutationObserver,兼容低版本的浏览器</span></span><br><span class="line"><span class="keyword">var</span> MutationObserver =</span><br><span class="line"> <span class="built_in">window</span>.MutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.WebKitMutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.MozMutationObserver</span><br><span class="line"><span class="comment">// 获取dom元素</span></span><br><span class="line"><span class="keyword">var</span> list = <span class="built_in">document</span>.querySelector(<span class="string">'ol'</span>)</span><br><span class="line"><span class="comment">// 创建Observer</span></span><br><span class="line"><span class="keyword">var</span> Observer = <span class="keyword">new</span> MutationObserver(<span class="function"><span class="keyword">function</span>(<span class="params">mutations, instance</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(mutations)</span><br><span class="line"> <span class="built_in">console</span>.log(instance)</span><br><span class="line"> mutations.forEach(<span class="function"><span class="keyword">function</span>(<span class="params">mutation</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(mutation)</span><br><span class="line"> })</span><br><span class="line">})</span><br></pre></td></tr></table></figure><ul><li>子元素的变动</li></ul><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><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></pre></td><td class="code"><pre><span class="line">Observer.observe(list, {</span><br><span class="line"> childList: <span class="literal">true</span>,</span><br><span class="line"> subtree: <span class="literal">true</span></span><br><span class="line">})</span><br><span class="line"><span class="comment">// 追加div标签</span></span><br><span class="line">list.appendChild(<span class="built_in">document</span>.createElement(<span class="string">'div'</span>))</span><br><span class="line"><span class="comment">// 追加文本</span></span><br><span class="line">list.appendChild(<span class="built_in">document</span>.createTextNode(<span class="string">'foo'</span>))</span><br><span class="line"><span class="comment">// 移除第一个节点</span></span><br><span class="line">list.removeChild(list.childNodes[<span class="number">0</span>])</span><br><span class="line"><span class="comment">// 子节点移除创建的div</span></span><br><span class="line">list.childNodes[<span class="number">0</span>].appendChild(<span class="built_in">document</span>.createElement(<span class="string">'div'</span>))</span><br></pre></td></tr></table></figure><ul><li>监测 characterData 的变动</li></ul><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><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Observer.observe(list, {</span><br><span class="line"> childList: <span class="literal">true</span>,</span><br><span class="line"> characterData: <span class="literal">true</span>,</span><br><span class="line"> subtree: <span class="literal">true</span></span><br><span class="line">})</span><br><span class="line"><span class="comment">// 将第一个子节点的数据改为cha</span></span><br><span class="line">list.childNodes[<span class="number">0</span>].data = <span class="string">'cha'</span></span><br></pre></td></tr></table></figure><ul><li>监测属性的变动</li></ul><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><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></pre></td><td class="code"><pre><span class="line">Observer.observe(list, {</span><br><span class="line"> attributes: <span class="literal">true</span></span><br><span class="line">})</span><br><span class="line"><span class="comment">// 设置节点的属性 会触发回调函数</span></span><br><span class="line">list.setAttribute(<span class="string">'data-value'</span>, <span class="string">'111'</span>)</span><br><span class="line"><span class="comment">// 重新设置属性 会触发回调</span></span><br><span class="line">list.setAttribute(<span class="string">'data-value'</span>, <span class="string">'2222'</span>)</span><br><span class="line"><span class="comment">// 删除属性 也会触发回调</span></span><br><span class="line">list.removeAttribute(<span class="string">'data-value'</span>)</span><br></pre></td></tr></table></figure><ul><li>属性变动前,记录变动之前的值</li></ul><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><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Observer.observe(list, {</span><br><span class="line"> attributes: <span class="literal">true</span>,</span><br><span class="line"> attributeOldValue: <span class="literal">true</span></span><br><span class="line">})</span><br><span class="line"><span class="comment">// 设置节点的属性 会触发回调函数</span></span><br><span class="line">list.setAttribute(<span class="string">'data-value'</span>, <span class="string">'111'</span>)</span><br><span class="line"><span class="comment">// 删除属性</span></span><br><span class="line">list.setAttribute(<span class="string">'data-value'</span>, <span class="string">'2222'</span>)</span><br></pre></td></tr></table></figure><ul><li>characterData 变动时,记录变动前的值。</li></ul><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><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></pre></td><td class="code"><pre><span class="line">Observer.observe(list, {</span><br><span class="line"> childList: <span class="literal">true</span>,</span><br><span class="line"> characterData: <span class="literal">true</span>,</span><br><span class="line"> subtree: <span class="literal">true</span>,</span><br><span class="line"> characterDataOldValue: <span class="literal">true</span></span><br><span class="line">})</span><br><span class="line"><span class="comment">// 设置数据 触发回调</span></span><br><span class="line">list.childNodes[<span class="number">0</span>].data = <span class="string">'aaa'</span></span><br><span class="line"><span class="comment">// 重新设置数据 重新触发回调</span></span><br><span class="line">list.childNodes[<span class="number">0</span>].data = <span class="string">'bbbb'</span></span><br></pre></td></tr></table></figure><ul><li>attributeFilter {Array} 表示需要观察的特定属性 比如 [‘class’, ‘src’];</li></ul><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><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Observer.observe(list, {</span><br><span class="line"> attributes: <span class="literal">true</span>,</span><br><span class="line"> attributeFilter: [<span class="string">'data-value'</span>]</span><br><span class="line">})</span><br><span class="line"><span class="comment">// 第一次设置属性 data-key 不会触发的,因为data-value 不存在</span></span><br><span class="line">list.setAttribute(<span class="string">'data-key'</span>, <span class="number">1</span>)</span><br><span class="line"><span class="comment">// 第二次会触发</span></span><br><span class="line">list.setAttribute(<span class="string">'data-value'</span>, <span class="number">1</span>)</span><br></pre></td></tr></table></figure><h2 id="案例分析—demo-编辑器"><a href="#案例分析—demo-编辑器" class="headerlink" title="案例分析—demo 编辑器"></a>案例分析—demo 编辑器</h2><p>下面我们做一个简单的 demo 编辑器:</p><ol><li>首先给父级元素 <code>ol</code> 设置 <code>contenteditable</code> 让容器可编辑;</li><li>然后构造一个 <code>observer</code> 监听子元素的变化;</li><li>每次回车的时候,控制台输出它的内容;</li></ol><figure class="highlight html"><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="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">ol</span> <span class="attr">contenteditable</span> <span class="attr">style</span>=<span class="string">"border: 1px solid red"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span>></span>111111<span class="tag"></<span class="name">li</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">ol</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> MutationObserver =</span><br><span class="line"> <span class="built_in">window</span>.MutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.WebKitMutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.MozMutationObserver</span><br><span class="line"><span class="keyword">const</span> list = <span class="built_in">document</span>.querySelector(<span class="string">'ol'</span>)</span><br><span class="line"><span class="keyword">const</span> Observer = <span class="keyword">new</span> MutationObserver(<span class="function">(<span class="params">mutations, instance</span>) =></span> {</span><br><span class="line"> mutations.forEach(<span class="function"><span class="params">mutation</span> =></span> {</span><br><span class="line"> <span class="keyword">if</span> (mutation.type === <span class="string">'childList'</span>) {</span><br><span class="line"> <span class="keyword">const</span> list_values = [].slice</span><br><span class="line"> .call(list.children)</span><br><span class="line"> .map(<span class="function"><span class="params">node</span> =></span> node.innerHTML)</span><br><span class="line"> .filter(<span class="function"><span class="params">s</span> =></span> s !== <span class="string">'<br>'</span>)</span><br><span class="line"> <span class="built_in">console</span>.log(list_values)</span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line">})</span><br><span class="line">Observer.observe(list, {</span><br><span class="line"> childList: <span class="literal">true</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure><p>现在我们继续可以做一个类似于 input 和 textarea 中的 <code>valueChange</code> 的事件一样的,监听值变化,之前的值和之后的值,如下代码:</p><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> MutationObserver =</span><br><span class="line"> <span class="built_in">window</span>.MutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.WebKitMutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.MozMutationObserver</span><br><span class="line"><span class="keyword">const</span> list = <span class="built_in">document</span>.querySelector(<span class="string">'ol'</span>)</span><br><span class="line"><span class="keyword">const</span> Observer = <span class="keyword">new</span> MutationObserver(<span class="function">(<span class="params">mutations, instance</span>) =></span> {</span><br><span class="line"> mutations.forEach(<span class="function"><span class="params">mutation</span> =></span> {</span><br><span class="line"> <span class="keyword">const</span> enter = {</span><br><span class="line"> mutation: mutation,</span><br><span class="line"> el: mutation.target,</span><br><span class="line"> newValue: mutation.target.textContent,</span><br><span class="line"> oldValue: mutation.oldValue</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">console</span>.log(enter)</span><br><span class="line"> })</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line">Observer.observe(list, {</span><br><span class="line"> childList: <span class="literal">true</span>,</span><br><span class="line"> attributes: <span class="literal">true</span>,</span><br><span class="line"> characterData: <span class="literal">true</span>,</span><br><span class="line"> subtree: <span class="literal">true</span>,</span><br><span class="line"> characterDataOldValue: <span class="literal">true</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure><blockquote><p>注意: 对 input 和 textarea 不起作用的。</p></blockquote><h2 id="案例分析—编辑器统计字数"><a href="#案例分析—编辑器统计字数" class="headerlink" title="案例分析—编辑器统计字数"></a>案例分析—编辑器统计字数</h2><figure class="highlight html"><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></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span></span></span><br><span class="line"><span class="tag"> <span class="attr">id</span>=<span class="string">"editor"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">contenteditable</span></span></span><br><span class="line"><span class="tag"> <span class="attr">style</span>=<span class="string">"width: 240px; height: 80px; border: 1px solid red;"</span></span></span><br><span class="line"><span class="tag">></span><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"><<span class="name">p</span> <span class="attr">id</span>=<span class="string">"textInput"</span>></span>还可以输入100字<span class="tag"></<span class="name">p</span>></span></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> MutationObserver =</span><br><span class="line"> <span class="built_in">window</span>.MutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.WebKitMutationObserver ||</span><br><span class="line"> <span class="built_in">window</span>.MozMutationObserver</span><br><span class="line"><span class="keyword">const</span> editor = <span class="built_in">document</span>.querySelector(<span class="string">'#editor'</span>)</span><br><span class="line"><span class="keyword">const</span> textInput = <span class="built_in">document</span>.querySelector(<span class="string">'#textInput'</span>)</span><br><span class="line"><span class="keyword">const</span> observer = <span class="keyword">new</span> MutationObserver(<span class="function"><span class="params">mutations</span> =></span> {</span><br><span class="line"> mutations.forEach(<span class="function"><span class="keyword">function</span>(<span class="params">mutation</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (mutation.type === <span class="string">'characterData'</span>) {</span><br><span class="line"> <span class="keyword">const</span> newValue = mutation.target.textContent</span><br><span class="line"> textInput.innerHTML = <span class="string">`还可以输入<span class="subst">${<span class="number">1000</span> - newValue.length}</span>字`</span></span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line">})</span><br><span class="line">observer.observe(editor, {</span><br><span class="line"> childList: <span class="literal">true</span>,</span><br><span class="line"> attributes: <span class="literal">true</span>,</span><br><span class="line"> characterData: <span class="literal">true</span>,</span><br><span class="line"> subtree: <span class="literal">true</span>,</span><br><span class="line"> characterDataOldValue: <span class="literal">true</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p><code>MutationObserver</code> 是用于代替 <code>MutationEvents</code> 作为观察 <code>DOM</code> 树结构发生变化时,做出相应处理的 <code>API</code> 。为什么要使用 <code>MutationObserver</code> 去代替 <code>MutationEvents</code> 呢,我们先了解一下 <code>MutationEvents</code></p>
</summary>
<category term="javascript" scheme="https://lingmissing.github.io/tags/javascript/"/>
</entry>
<entry>
<title>javascript闭包</title>
<link href="https://lingmissing.github.io/2016/12/12/javascript%E9%97%AD%E5%8C%85/"/>
<id>https://lingmissing.github.io/2016/12/12/javascript闭包/</id>
<published>2016-12-12T07:20:15.000Z</published>
<updated>2019-01-04T03:39:41.959Z</updated>
<content type="html"><![CDATA[<blockquote><p>闭包是指那些能够访问独立(自由)变量的函数 (变量在本地使用,但定义在一个封闭的作用域中)。换句话说,这些函数可以“记忆”它被创建时候的环境。</p></blockquote>]]></content>
<summary type="html">
<blockquote>
<p>闭包是指那些能够访问独立(自由)变量的函数 (变量在本地使用,但定义在一个封闭的作用域中)。换句话说,这些函数可以“记忆”它被创建时候的环境。</p>
</blockquote>
</summary>
<category term="javascript" scheme="https://lingmissing.github.io/tags/javascript/"/>
</entry>
<entry>
<title>javascript递归</title>
<link href="https://lingmissing.github.io/2016/12/12/javascript%E9%80%92%E5%BD%92/"/>
<id>https://lingmissing.github.io/2016/12/12/javascript递归/</id>
<published>2016-12-12T06:18:17.000Z</published>
<updated>2019-01-04T03:39:39.089Z</updated>
<content type="html"><![CDATA[<blockquote><p>调用自身的函数称为递归函数</p></blockquote><ul><li>缺点:递归占用的内存和资源比较多,同时难以实现和维护。</li><li>优点:在处理 DOM 之类的树形结构数据时,非常适合用递归。</li></ul><a id="more"></a><h1 id="案例"><a href="#案例" class="headerlink" title="案例"></a>案例</h1><h4 id="数字-n-的阶乘通过乘以-1-2-3-…-n-进行计算"><a href="#数字-n-的阶乘通过乘以-1-2-3-…-n-进行计算" class="headerlink" title="数字 n 的阶乘通过乘以 1 _ 2 _ 3 *… n 进行计算"></a>数字 n 的阶乘通过乘以 1 _ 2 _ 3 *… n 进行计算</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> f = <span class="function"><span class="keyword">function</span>(<span class="params">x</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (x === <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> x * f(x - <span class="number">1</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> result = f(n)</span><br></pre></td></tr></table></figure><h4 id="获取存在某个字段的节点"><a href="#获取存在某个字段的节点" class="headerlink" title="获取存在某个字段的节点"></a>获取存在某个字段的节点</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> new_array = []</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">_getChilds</span>(<span class="params">data</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (data.ObjType == <span class="string">'某个数'</span>) {</span><br><span class="line"> new_array.push(data)</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (data.Childs && data.Childs.length > <span class="number">0</span>) {</span><br><span class="line"> getChilds(data.Childs)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getChilds</span>(<span class="params">childData</span>) </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i < childData.length; i++) {</span><br><span class="line"> _getChilds(childData[i])</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 或者</span></span><br><span class="line"> <span class="comment">// childData.map(item => _getChilds(item))</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="js-递归实现数组转树结构"><a href="#js-递归实现数组转树结构" class="headerlink" title="js 递归实现数组转树结构"></a>js 递归实现数组转树结构</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> jsonArr = [</span><br><span class="line"> { <span class="attr">name</span>: <span class="string">'a'</span>, <span class="attr">id</span>: <span class="number">1</span>, <span class="attr">pid</span>: <span class="number">0</span> },</span><br><span class="line"> { <span class="attr">name</span>: <span class="string">'b'</span>, <span class="attr">id</span>: <span class="number">2</span>, <span class="attr">pid</span>: <span class="number">1</span> },</span><br><span class="line"> { <span class="attr">name</span>: <span class="string">'c'</span>, <span class="attr">id</span>: <span class="number">3</span>, <span class="attr">pid</span>: <span class="number">1</span> },</span><br><span class="line"> { <span class="attr">name</span>: <span class="string">'d'</span>, <span class="attr">id</span>: <span class="number">4</span>, <span class="attr">pid</span>: <span class="number">2</span> },</span><br><span class="line"> { <span class="attr">name</span>: <span class="string">'e'</span>, <span class="attr">id</span>: <span class="number">5</span>, <span class="attr">pid</span>: <span class="number">2</span> }</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params">data, pid</span>) </span>{</span><br><span class="line"> <span class="keyword">let</span> result = []</span><br><span class="line"> <span class="keyword">let</span> temp</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i < data.length; i++) {</span><br><span class="line"> <span class="keyword">if</span> (data[i].pid == pid) {</span><br><span class="line"> <span class="keyword">let</span> obj = {</span><br><span class="line"> name: data[i].name,</span><br><span class="line"> id: data[i].id</span><br><span class="line"> }</span><br><span class="line"> temp = fn(data, data[i].id)</span><br><span class="line"> <span class="keyword">if</span> (temp.length > <span class="number">0</span>) {</span><br><span class="line"> obj.children = temp</span><br><span class="line"> }</span><br><span class="line"> result.push(obj)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> result</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> result = fn(jsonArr, <span class="number">0</span>)</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<blockquote>
<p>调用自身的函数称为递归函数</p>
</blockquote>
<ul>
<li>缺点:递归占用的内存和资源比较多,同时难以实现和维护。</li>
<li>优点:在处理 DOM 之类的树形结构数据时,非常适合用递归。</li>
</ul>
</summary>
<category term="javascript" scheme="https://lingmissing.github.io/tags/javascript/"/>
</entry>
<entry>
<title>基于react的audio组件</title>
<link href="https://lingmissing.github.io/2016/12/12/audio-style/"/>
<id>https://lingmissing.github.io/2016/12/12/audio-style/</id>
<published>2016-12-12T03:30:32.000Z</published>
<updated>2019-01-04T03:36:30.988Z</updated>
<content type="html"><![CDATA[<blockquote><p>由于 mac 和 window 的样式不一致导致~~</p></blockquote><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">// 组件调用 <span class="tag"><<span class="name">audio</span> <span class="attr">src</span>=<span class="string">"{src地址}"</span> <span class="attr">id</span>=<span class="string">"{srcID}"</span> /></span></span><br></pre></td></tr></table></figure><a id="more"></a><h1 id="audio-属性"><a href="#audio-属性" class="headerlink" title="audio 属性"></a>audio 属性</h1><ul><li><code>src</code> 歌曲的路径</li><li><code>preload</code> 是否在页面加载后立即加载(设置 autoplay 后无效)</li><li><code>controls</code> 显示 audio 自带的播放控件</li><li><code>loop</code> 音频循环</li><li><code>autoplay</code> 音频加载后自动播放</li><li><code>currentTime</code> 音频当前播放时间</li><li><code>duration</code> 音频总长度</li><li><code>ended</code> 音频是否结束</li><li><code>muted</code> 音频静音为 true</li><li><code>volume</code> 当前音频音量</li><li><code>readyState</code> 音频当前的就绪状态</li></ul><h1 id="audio-事件"><a href="#audio-事件" class="headerlink" title="audio 事件"></a>audio 事件</h1><ul><li><code>abort</code> 当音频/视频的加载已放弃时</li><li><code>canplay</code> 当浏览器可以播放音频/视频时</li><li><code>canplaythrough</code> 当浏览器可在不因缓冲而停顿的情况下进行播放时</li><li><code>durationchange</code> 当音频/视频的时长已更改时</li><li><code>emptied</code> 当目前的播放列表为空时</li><li><code>ended</code> 当目前的播放列表已结束时</li><li><code>error</code> 当在音频/视频加载期间发生错误时</li><li><code>loadeddata</code> 当浏览器已加载音频/视频的当前帧时</li><li><code>loadedmetadata</code> 当浏览器已加载音频/视频的元数据时</li><li><code>loadstart</code> 当浏览器开始查找音频/视频时</li><li><code>pause</code> 当音频/视频已暂停时</li><li><code>play</code> 当音频/视频已开始或不再暂停时</li><li><code>playing</code> 当音频/视频在已因缓冲而暂停或停止后已就绪时</li><li><code>progress</code> 当浏览器正在下载音频/视频时</li><li><code>ratechange</code> 当音频/视频的播放速度已更改时</li><li><code>seeked</code> 当用户已移动/跳跃到音频/视频中的新位置时</li><li><code>seeking</code> 当用户开始移动/跳跃到音频/视频中的新位置时</li><li><code>stalled</code> 当浏览器尝试获取媒体数据,但数据不可用时</li><li><code>suspend</code> 当浏览器刻意不获取媒体数据时</li><li><code>timeupdate</code> 当目前的播放位置已更改时</li><li><code>volumechange</code> 当音量已更改时</li><li><code>waiting</code> 当视频由于需要缓冲下一帧而停止</li></ul><h1 id="组件结构"><a href="#组件结构" class="headerlink" title="组件结构"></a>组件结构</h1><figure class="highlight html"><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></pre></td><td class="code"><pre><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">className</span>=<span class="string">"audioBox"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">audio</span></span></span><br><span class="line"><span class="tag"> <span class="attr">id</span>=<span class="string">{</span>`<span class="attr">audio</span>${<span class="attr">id</span>}`}</span></span><br><span class="line"><span class="tag"> <span class="attr">src</span>=<span class="string">{src}</span></span></span><br><span class="line"><span class="tag"> <span class="attr">preload</span>=<span class="string">{true}</span></span></span><br><span class="line"><span class="tag"> <span class="attr">onCanPlay</span>=<span class="string">{()</span> =></span> this.controlAudio('allTime')}</span><br><span class="line"> onTimeUpdate={(e) => this.controlAudio('getCurrentTime')}</span><br><span class="line"> ></span><br><span class="line"> 您的浏览器不支持 audio 标签。</span><br><span class="line"> <span class="tag"></<span class="name">audio</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span></span></span><br><span class="line"><span class="tag"> <span class="attr">className</span>=<span class="string">{isPlay</span> ? '<span class="attr">pause</span>' <span class="attr">:</span> '<span class="attr">play</span>'}</span></span><br><span class="line"><span class="tag"> <span class="attr">onClick</span>=<span class="string">{()</span> =></span> this.controlAudio(isPlay ? 'pause' : 'play')}</span><br><span class="line"> /></span><br><span class="line"> <span class="tag"><<span class="name">span</span> <span class="attr">className</span>=<span class="string">"current"</span>></span></span><br><span class="line"> {this.millisecondToDate(currentTime)+'/'+this.millisecondToDate(allTime)}</span><br><span class="line"> <span class="tag"></<span class="name">span</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span></span></span><br><span class="line"><span class="tag"> <span class="attr">type</span>=<span class="string">"range"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">className</span>=<span class="string">"time"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">step</span>=<span class="string">"0.01"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">max</span>=<span class="string">{allTime}</span></span></span><br><span class="line"><span class="tag"> <span class="attr">value</span>=<span class="string">{currentTime}</span></span></span><br><span class="line"><span class="tag"> <span class="attr">onChange</span>=<span class="string">{(value)</span> =></span> this.controlAudio('changeCurrentTime',value)}</span><br><span class="line"> /></span><br><span class="line"> <span class="tag"><<span class="name">i</span></span></span><br><span class="line"><span class="tag"> <span class="attr">className</span>=<span class="string">{isMuted</span> ? '<span class="attr">mute</span>' <span class="attr">:</span> '<span class="attr">nomute</span>'}</span></span><br><span class="line"><span class="tag"> <span class="attr">onClick</span>=<span class="string">{()</span> =></span> this.controlAudio('muted')}</span><br><span class="line"> /></span><br><span class="line"> <span class="tag"><<span class="name">input</span></span></span><br><span class="line"><span class="tag"> <span class="attr">type</span>=<span class="string">"range"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">className</span>=<span class="string">"volume"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">onChange</span>=<span class="string">{(value)</span> =></span> this.controlAudio('changeVolume',value)}</span><br><span class="line"> value={isMuted ? 0 : volume}</span><br><span class="line"> /></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure><h1 id="组件-javascript"><a href="#组件-javascript" class="headerlink" title="组件 javascript"></a>组件 javascript</h1><figure class="highlight javascript"><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><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">constructor</span>(props) {</span><br><span class="line"> <span class="keyword">super</span>(props)</span><br><span class="line"> <span class="keyword">this</span>.state = {</span><br><span class="line"> isPlay: <span class="literal">false</span>,</span><br><span class="line"> isMuted: <span class="literal">false</span>,</span><br><span class="line"> volume: <span class="number">100</span>,</span><br><span class="line"> allTime: <span class="number">0</span>,</span><br><span class="line"> currentTime: <span class="number">0</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">millisecondToDate(time) {</span><br><span class="line"> <span class="keyword">const</span> second = <span class="built_in">Math</span>.floor(time % <span class="number">60</span>)</span><br><span class="line"> <span class="keyword">let</span> minite = <span class="built_in">Math</span>.floor(time / <span class="number">60</span>)</span><br><span class="line"> <span class="comment">// let hour</span></span><br><span class="line"> <span class="comment">// if(minite > 60) {</span></span><br><span class="line"> <span class="comment">// hour = minite / 60</span></span><br><span class="line"> <span class="comment">// minite = minite % 60</span></span><br><span class="line"> <span class="comment">// return `${Math.floor(hour)}:${Math.floor(minite)}:${Math.floor(second)}`</span></span><br><span class="line"> <span class="comment">// }</span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">`<span class="subst">${minite}</span>:<span class="subst">${second >= <span class="number">10</span> ? second : <span class="string">`0<span class="subst">${second}</span>`</span>}</span>`</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">controlAudio(type,value) {</span><br><span class="line"> <span class="keyword">const</span> { id,src } = <span class="keyword">this</span>.props</span><br><span class="line"> <span class="keyword">const</span> audio = <span class="built_in">document</span>.getElementById(<span class="string">`audio<span class="subst">${id}</span>`</span>)</span><br><span class="line"> <span class="keyword">switch</span>(type) {</span><br><span class="line"> <span class="keyword">case</span> <span class="string">'allTime'</span>:</span><br><span class="line"> <span class="keyword">this</span>.setState({</span><br><span class="line"> allTime: audio.duration</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">case</span> <span class="string">'play'</span>:</span><br><span class="line"> audio.play()</span><br><span class="line"> <span class="keyword">this</span>.setState({</span><br><span class="line"> isPlay: <span class="literal">true</span></span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">case</span> <span class="string">'pause'</span>:</span><br><span class="line"> audio.pause()</span><br><span class="line"> <span class="keyword">this</span>.setState({</span><br><span class="line"> isPlay: <span class="literal">false</span></span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">case</span> <span class="string">'muted'</span>:</span><br><span class="line"> <span class="keyword">this</span>.setState({</span><br><span class="line"> isMuted: !audio.muted</span><br><span class="line"> })</span><br><span class="line"> audio.muted = !audio.muted</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">case</span> <span class="string">'changeCurrentTime'</span>:</span><br><span class="line"> <span class="keyword">this</span>.setState({</span><br><span class="line"> currentTime: value</span><br><span class="line"> })</span><br><span class="line"> audio.currentTime = value</span><br><span class="line"> <span class="keyword">if</span>(value == audio.duration) {</span><br><span class="line"> <span class="keyword">this</span>.setState({</span><br><span class="line"> isPlay: <span class="literal">false</span></span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">case</span> <span class="string">'getCurrentTime'</span>:</span><br><span class="line"> <span class="keyword">this</span>.setState({</span><br><span class="line"> currentTime: audio.currentTime</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">if</span>(audio.currentTime == audio.duration) {</span><br><span class="line"> <span class="keyword">this</span>.setState({</span><br><span class="line"> isPlay: <span class="literal">false</span></span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">case</span> <span class="string">'changeVolume'</span>:</span><br><span class="line"> audio.volume = value / <span class="number">100</span></span><br><span class="line"> <span class="keyword">this</span>.setState({</span><br><span class="line"> volume: value,</span><br><span class="line"> isMuted: !value</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<blockquote>
<p>由于 mac 和 window 的样式不一致导致~~</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">// 组件调用 <span class="tag">&lt;<span class="name">audio</span> <span class="attr">src</span>=<span class="string">"&#123;src地址&#125;"</span> <span class="attr">id</span>=<span class="string">"&#123;srcID&#125;"</span> /&gt;</span></span><br></pre></td></tr></table></figure>
</summary>
<category term="react" scheme="https://lingmissing.github.io/tags/react/"/>
<category term="html5" scheme="https://lingmissing.github.io/tags/html5/"/>
</entry>
<entry>
<title>【译】 Vue 2.0 的变化(二)</title>
<link href="https://lingmissing.github.io/2016/12/09/vue-2/"/>
<id>https://lingmissing.github.io/2016/12/09/vue-2/</id>
<published>2016-12-09T09:19:21.000Z</published>
<updated>2019-01-04T03:42:11.393Z</updated>
<content type="html"><![CDATA[<h3 id="v-for迭代语法变化"><a href="#v-for迭代语法变化" class="headerlink" title="v-for迭代语法变化"></a><code>v-for</code>迭代语法变化</h3><ul><li>丢弃<del><code>$index</code></del>和<del><code>$key</code></del></li><li>新数组语法<ul><li>value in arr</li><li>(value, index) in arr</li></ul></li><li>新对象语法<ul><li>value in obj</li><li>(value, key) in obj</li><li>(value, key, index) in obj</li></ul></li></ul><a id="more"></a><h3 id="指令接口的改变"><a href="#指令接口的改变" class="headerlink" title="指令接口的改变"></a>指令接口的改变</h3><p>大体来说,2.0 版本中指令大范围的降低功能,它们仅用于低层次的直接 dom 操作。在多数情况下,你更应该使用组件作为主要的代码重构抽象。</p><p>指令不再有实例,这意味着指令中将不存在<code>this</code>,并且<code>bind</code>, <code>update</code>和<code>unbind</code>目前将接受任何数据作为参数。</p><p>请注意,绑定对象是不可变的。设置<code>binding.value</code>没有任何效果。并且在它上面添加属性不会持久,如果你真的非常需要可以在<code>el</code>配置上添加指令状态。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">v-example:arg.modifier</span>=<span class="string">"a.b"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// example directive</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> bind (el, binding, vnode) {</span><br><span class="line"> <span class="comment">// the binding object exposes value, oldValue, expression, arg and modifiers.</span></span><br><span class="line"> binding.expression <span class="comment">// "a.b"</span></span><br><span class="line"> binding.arg <span class="comment">// "arg"</span></span><br><span class="line"> binding.modifiers <span class="comment">// { modifier: true }</span></span><br><span class="line"> <span class="comment">// the context Vue instance can be accessed as vnode.context.</span></span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line"> <span class="comment">// update has a few changes, see below</span></span><br><span class="line"> update (el, binding, vnode, oldVnode) { ... },</span><br><span class="line"></span><br><span class="line"> <span class="comment">// componentUpdated is a new hook that is called AFTER the entire component</span></span><br><span class="line"> <span class="comment">// has completed the current update cycle. This means all the DOM would</span></span><br><span class="line"> <span class="comment">// be in updated state when this hook is called. Also, this hook is always</span></span><br><span class="line"> <span class="comment">// called regardless of whether this directive's value has changed or not.</span></span><br><span class="line"> componentUpdated (el, binding, vnode, oldVNode) { ... },</span><br><span class="line"></span><br><span class="line"> unbind (el, binding, vnode) { ... }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>如果你只关心值可以使用解构:</p><figure class="highlight javascript"><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="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> bind(el, { value }) {</span><br><span class="line"> <span class="comment">// ...</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>除此之外,<code>update</code>钩子有一些变化:</p><ul><li>在<code>bind</code>之后将不再自动调用</li><li>当组件重新渲染时总能响应,无论被绑定的值是否发生改变。你可以通过<code>binding.value === binding.oldValue</code>比较跳过不必要的更新,但也会有情况下,你希望应用始终更新。例如,当指令绑定到对象那可能希望是变化而不是替代。</li></ul><p><code>elementDirective</code>, 指令参数和指令配置,例如<code>acceptStatement</code>, <code>deep</code>等等<br>均被删除。</p><h3 id="过滤器用法和语法变化"><a href="#过滤器用法和语法变化" class="headerlink" title="过滤器用法和语法变化"></a>过滤器用法和语法变化</h3><p>在 vue 2.0,filter 有了一系列的变化:</p><ul><li>filter 现在只能用于文本插入(双花括号标签)。在之前我们在指令中使用 filter,例如<code>v-model</code>,<code>v-on</code>等等,导致使用的复杂性,并且在<code>v-for</code>上的列表过滤,它更适合迁移到计算性能的 js 中。</li><li>vue 2.0 不提供任何内置过滤器。建议使用独立的方法解决特定域的问题,例如<a href="http://momentjs.com/" target="_blank" rel="noopener">moment.js</a>用于格式化时间,<a href="http://openexchangerates.github.io/accounting.js/" target="_blank" rel="noopener">accounting.js</a>用于格式化金融货币。也欢迎你来创建自己的过滤器,并与社区分享吧!</li><li><p>filter 语法更改为内嵌的 js 函数调用,而不是采取空格分割的参数。</p><figure class="highlight javascript"><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><br><span class="line"> {</span><br><span class="line"> date | formatDate(<span class="string">'YY-MM-DD'</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul><h3 id="过渡组件"><a href="#过渡组件" class="headerlink" title="过渡组件"></a>过渡组件</h3><h4 id="过渡-CSS-的变化"><a href="#过渡-CSS-的变化" class="headerlink" title="过渡 CSS 的变化"></a>过渡 CSS 的变化</h4><ul><li><code>v-enter</code>:在元素插入前应用,1 秒后删除。(开始于进入状态)</li><li><code>v-enter-active</code>:在元素插入前应用,当<code>transition</code>/<code>animation</code>结束时移除。</li><li><code>v-leave</code>:当离开的<code>transition</code>触发时正确应用,一秒后删除。(开始于离开状态)</li><li><code>v-leave-active</code>:当离开的<code>transition</code>触发时正确应用,当<code>transition</code>/<code>animation</code>结束时移除。</li></ul><p><code>v-enter-active</code>和<code>v-leave-active</code>帮助你指定不同的曲线用于进入/离开动画。在多数情况下,升级只需将当前的<code>v-leave</code>替换为<code>v-leave-active</code>。(对于 css 动画,使用<code>v-enter-active</code>和<code>v-leave-active</code>)</p><h4 id="过渡-API-的变化"><a href="#过渡-API-的变化" class="headerlink" title="过渡 API 的变化"></a>过渡 API 的变化</h4><ul><li><code><transition></code>组件</li></ul><p>所有单元素的过度效果通过使用<code><transition></code>这个内置组件包装目标元素或组件得到相应的效果。这是一个抽象组件,意味着它不会渲染额外的 DOM 元素,也不会在组件层次结构中展示。它仅仅用于过渡行为里面的包裹内容。</p><p>最简单的用法示例:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">transition</span>></span> <span class="tag"><<span class="name">div</span> <span class="attr">v-if</span>=<span class="string">"ok"</span>></span>toggled content<span class="tag"></<span class="name">div</span>></span> <span class="tag"></<span class="name">transition</span>></span></span><br></pre></td></tr></table></figure><p>该组件定义了一些属性和事件,直接映射到旧版的过渡定义选项。</p><h5 id="属性"><a href="#属性" class="headerlink" title="属性"></a>属性</h5><ul><li>name: String<ul><li>用于自动生成过渡 CSS 类名。例如,<code>name: 'fade'</code>将会自动生成 <code>.fade-enter</code>、<code>.fade-enter-active</code>等等。默认是<code>v</code>。</li></ul></li><li>appear: Boolean<ul><li>是否在最初的渲染应用的过渡。(默认值<code>false</code>)</li></ul></li><li>css: Boolean<ul><li>是否应用 css 过度类,默认值<code>true</code>。如果设置为<code>false</code>,只能通过触发组件事件注册的 JavaScript 钩子。</li></ul></li><li>type: String<ul><li>指定等待确定过渡结束时转变的事件类型。可用的值是<code>transition</code>和<code>animation</code>。默认情况下,它会自动检测一个持续时间较长的类型。</li></ul></li><li>mode: String<ul><li>控制离开/进入转换的时序。可用的模式是<code>in-out</code>和<code>out-in</code>,默认为同步。</li></ul></li><li>enterClass, leaveClass, enterActiveClass, leaveActiveClass, appearClass, appearActiveClass: String<ul><li>单独配置的过渡 css 类</li></ul></li></ul><p>过渡到动态组件的示例:</p><figure class="highlight html"><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="tag"><<span class="name">transition</span> <span class="attr">name</span>=<span class="string">"fade"</span> <span class="attr">mode</span>=<span class="string">"out-in"</span> <span class="attr">appear</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">component</span> <span class="attr">:is</span>=<span class="string">"view"</span>></span><span class="tag"></<span class="name">component</span>></span></span><br><span class="line"><span class="tag"></<span class="name">transition</span>></span></span><br></pre></td></tr></table></figure><h5 id="事件"><a href="#事件" class="headerlink" title="事件"></a>事件</h5><p>对应的在 1.x API 中可用的 js 钩子:</p><ul><li>before-enter</li><li>enter</li><li>after-enter</li><li>before-leave</li><li>leave</li><li>after-leave</li><li>before-appear</li><li>appear</li><li>after-appear</li></ul><p>例子:</p><figure class="highlight html"><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="tag"><<span class="name">transition</span> @<span class="attr">after-enter</span>=<span class="string">"transitionComplete"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">v-show</span>=<span class="string">"ok"</span>></span>toggled content<span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">transition</span>></span></span><br></pre></td></tr></table></figure><p>当进入的过渡效果完成时,组件的<code>transitionComplete</code>方法将会在过渡 DOM 元素作为参数被调用。</p><p>一些注意事项:</p><ul><li><code>leave-cancelled</code>在插入删除中不可用。一旦离开的过渡效果开始,将不能被取消。但是仍然可用于<code>v-show</code>。</li><li>和 1.0 类似,对于<code>enter</code>和<code>leave</code>钩子,在<code>cb</code>作为第二个参数的存在下表示使用者想要过渡结束时间的明确控制。</li></ul><h5 id="lt-transition-group-gt-组件"><a href="#lt-transition-group-gt-组件" class="headerlink" title="<transition-group>组件"></a><code><transition-group></code>组件</h5><p>所有的多元素过渡效果通过使用<code><transition-group></code>内置组件包装元素应用。它暴露了和<code><transition></code>一样的属性和事件。不同之处在于:</p><ol><li>不同于<code><transition></code>,<code><transition-group></code>渲染一个真实的 DOM 元素。默认是渲染一个<code><span></code>标签,并且你可以配置哪些元素应该通过标记的属性呈现。你也可以使用<code>is</code>特性,例如<code><ul is="transition-group"></code>。</li><li><code><transition-group></code>不支持<code>mode</code>属性。</li><li><code><transition-group></code>下的子组件必须有唯一的 key。</li></ol><p>例子:</p><figure class="highlight html"><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="tag"><<span class="name">transition-group</span> <span class="attr">tag</span>=<span class="string">"ul"</span> <span class="attr">name</span>=<span class="string">"slide"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">"item in items"</span> <span class="attr">:key</span>=<span class="string">"item.id"</span>></span>{{ item.text }}<span class="tag"></<span class="name">li</span>></span></span><br><span class="line"><span class="tag"></<span class="name">transition-group</span>></span></span><br></pre></td></tr></table></figure><h4 id="创建可重用的转换"><a href="#创建可重用的转换" class="headerlink" title="创建可重用的转换"></a>创建可重用的转换</h4><p>现在<code>transitions</code>能够通过组件应用,它们补在被视为一种单独类型,因此全局的<code>Vue.transition()</code>方法和<code>transition</code>配置都被丢弃。你可以通过组件的属性和方法配置内嵌的过渡。但是,我们现在怎么创建可重复使用的过渡效果,尤其是那些自定义的 js 钩子?答案是创建自己的过渡组件(它们特别适合作为功能组件):</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">Vue.component(<span class="string">'fade'</span>, {</span><br><span class="line"> functional: <span class="literal">true</span>,</span><br><span class="line"> render(createElement, { children }) {</span><br><span class="line"> <span class="keyword">const</span> data = {</span><br><span class="line"> props: {</span><br><span class="line"> name: <span class="string">'fade'</span></span><br><span class="line"> },</span><br><span class="line"> on: {</span><br><span class="line"> beforeEnter() {</span><br><span class="line"> <span class="comment">/* ... */</span></span><br><span class="line"> }, <span class="comment">// <-- Note hooks use camelCase in JavaScript (same as 1.x)</span></span><br><span class="line"> afterEnter() {</span><br><span class="line"> <span class="comment">/* ... */</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> createElement(<span class="string">'transition'</span>, data, children)</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure><p>你可以这么使用:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">fade</span>></span> <span class="tag"><<span class="name">div</span> <span class="attr">v-if</span>=<span class="string">"ok"</span>></span>toggled content<span class="tag"></<span class="name">div</span>></span> <span class="tag"></<span class="name">fade</span>></span></span><br></pre></td></tr></table></figure><h3 id="v-model的变化"><a href="#v-model的变化" class="headerlink" title="v-model的变化"></a><code>v-model</code>的变化</h3><ul><li><p><code>lazy</code>和<code>number</code>参数现在是修饰符。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">input</span> <span class="attr">v-model.lazy</span>=<span class="string">"text"</span> /></span></span><br></pre></td></tr></table></figure></li><li><p>新的修饰符:<code>.trim</code>-修整输入,顾名思义</p></li><li><code>debounce</code>参数被丢弃</li><li><p><code>v-model</code>不再关心初始值。它始终将 data 的数据作为资源。这意味着数据将是以 1 呈现而不是 2.</p><pre><code><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">data: {</span><br><span class="line">val: <span class="number">1</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="string">`</span></span><br></pre></td></tr></table></figure><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">input</span> <span class="attr">v-model</span>=<span class="string">"val"</span> <span class="attr">value</span>=<span class="string">"2"</span>></span></span><br></pre></td></tr></table></figure></code></pre><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">- 当使用`v-for`时,`v-model`不再生效。</span><br><span class="line"> ```html</span><br><span class="line"> <input v-for="str in strings" v-model="str" /></span><br><span class="line"> ```</span><br><span class="line"></span><br><span class="line">### Refs</span><br><span class="line"></span><br><span class="line">- `v-ref`现在不再是一个指令,而是一个类似于`key`的属性</span><br><span class="line"></span><br><span class="line"> ```html</span><br><span class="line"></span><br><span class="line"> <!-- before --></span><br><span class="line"></span><br><span class="line"> <comp v-ref:foo></comp></span><br><span class="line"></span><br><span class="line"><!-- after --></span><br><span class="line"></span><br><span class="line"><comp ref="foo"></comp></span><br></pre></td></tr></table></figure></li></ul><p>依然支持动态绑定:</p><pre><code><figure class="highlight html"><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><br><span class="line"><span class="tag"><<span class="name">comp</span> <span class="attr">:ref</span>=<span class="string">"dynamicRef"</span>></span><span class="tag"></<span class="name">comp</span>></span></span><br><span class="line">`</span><br></pre></td></tr></table></figure></code></pre><ul><li><code>vm.$els</code>和<code>vm.$refs</code>合并了。在正常元素上使用是 DOM 元素,在组件上使用是组件实例。</li></ul><h3 id="杂项"><a href="#杂项" class="headerlink" title="杂项"></a>杂项</h3><ul><li><code>track-by</code>已经被<code>key</code>替代。对于绑定属性它遵守相同的规则,没有<code>v-bind:</code>或者<code>:</code>字头,它被视为普通字符串。大多数情况下需要动态绑定,如下:<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!-- 1.x --></span></span><br><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">v-for</span>=<span class="string">"item in items"</span> <span class="attr">track-by</span>=<span class="string">"id"</span>></span><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure></li></ul><!-- 2.0 --><p><div v-for="item in items" :key="item.id"><br> <figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">- 内插值属性已被弃用。</span><br><span class="line"> ```html</span><br><span class="line"><!-- 1.x --></span><br><span class="line"><div id="{{ id }}"></span><br><span class="line"></span><br><span class="line"><!-- 2.0 --></span><br><span class="line"><div :id="id"></span><br></pre></td></tr></table></figure></div></p><ul><li>属性绑定行为变化:当绑定属性时,只有<code>null</code>、<code>undefine</code>和<code>false</code>被认为是<code>false</code>。这意味着 0 和空字符串依旧呈现出原来的样子。对于枚举属性,<code>:draggable="''"</code>将被渲染为<code>draggable="true"</code>。<br>另外,对于枚举属性,除了上述<code>false</code>的值,<code>false</code>字符串也会被渲染为<code>attr="false"</code>。</li><li>当使用一个自定义组件,<code>v-on</code>只听自定义事件<code>$emitted</code>挂载在组件上。(不再监听 DOM 事件)</li><li><code>v-else</code>不再适用于<code>v-show</code>,请使用其他的否定表达式。</li><li>单次绑定只能使用<code>v-once</code>。</li><li><code>Array.prototype.$set</code>/<code>$remove</code>被丢弃(使用<code>Vue.set</code>或者<code>Array.prototype.splice</code>)。</li><li><code>:style</code>不再支持<code>!import</code>。</li><li><code>root</code>实例不能使用<code>props</code>(请使用<code>propsData</code>)</li><li>在<code>Vue.extend</code>中<code>el</code>配置项不能被使用,它现在只能被用作一个实例创建选项。</li><li>在 vue 的实例中不能使用<code>Vue.set</code>和<code>Vue.delete</code></li></ul><h3 id="升级小提示"><a href="#升级小提示" class="headerlink" title="升级小提示"></a>升级小提示</h3><h4 id="如何处理丢弃的-dispatch和-broadcast?"><a href="#如何处理丢弃的-dispatch和-broadcast?" class="headerlink" title="如何处理丢弃的$dispatch和$broadcast?"></a>如何处理丢弃的<code>$dispatch</code>和<code>$broadcast</code>?</h4><p>我们弃用<code>$dispatch</code>和<code>$broadcast</code>的原因在于依赖组件树结构的事件流,当组件树变得很大时很难推理(简单地说:它不能在大型应用很好地扩展,我们不希望以后给你设置痛点)。<code>$dispatch</code>和<code>$broadcast</code>不能解决同级组件之间的通信。从而,你可以使用和 node 中的<code>EventEmitter</code>类似的模式:一个允许组件通信的集中事件枢纽,无论他们在组件树的任何地方。因为 vue 的实例实现了事件发射接口,你可以使用空的 vue 实例达到目的:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> bus = <span class="keyword">new</span> Vue()</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// in component A's method</span></span><br><span class="line">bus.$emit(<span class="string">'id-selected'</span>, <span class="number">1</span>)</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// in component B's created hook</span></span><br><span class="line">bus.$on(<span class="string">'id-selected'</span>, <span class="keyword">this</span>.someMethod)</span><br></pre></td></tr></table></figure><p>并且不要忘记使用<code>$off</code>解绑事件:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// in component B's destroyed hook</span></span><br><span class="line">bus.$off(<span class="string">'id-selected'</span>, <span class="keyword">this</span>.someMethod)</span><br></pre></td></tr></table></figure><p>这种模式在简单的场景中可以作为<code>$dispatch</code>和<code>$broadcast</code>的替代。但是在复杂的场景中,建议使用<code>vuex</code>建立一个专门的状态管理层。</p><h4 id="如何处理数组中-filter-的弃用?"><a href="#如何处理数组中-filter-的弃用?" class="headerlink" title="如何处理数组中 filter 的弃用?"></a>如何处理数组中 filter 的弃用?</h4><p>对于使用<code>v-for</code>进行列表过滤-过滤器常见用法之一-现在建议使用<code>computed</code>属性返回原始数组的一个副本(查阅<a href="https://github.com/vuejs/vue/blob/next/examples/grid/grid.js#L21-L41" target="_blank" rel="noopener">更新数据例子</a>)。好处在于你不再受到<code>filter</code>语法的限制,现在它只是普通的 javascript,并且你可以正常访问过滤结果,因为它只是一个计算的属性。</p><h4 id="如何处理在v-model中debounce的丢弃?"><a href="#如何处理在v-model中debounce的丢弃?" class="headerlink" title="如何处理在v-model中debounce的丢弃?"></a>如何处理在<code>v-model</code>中<code>debounce</code>的丢弃?</h4><p><code>debounce</code>用于我们多久执行异步请求和其他操作,在<code>v-model</code>中使用十分容易,但这样也延迟了状态更新带来了限制。<br>当在设计一个搜索功能时这个限制变得很明显,看看这个<a href="https://jsbin.com/zefawu/3/edit?html,output" target="_blank" rel="noopener">例子</a>,使用<code>debounce</code>属性,在搜索之前没法检测脏数据,因为我们不能访问输入的实时状态。</p><blockquote><p>未完待续….</p></blockquote><hr><blockquote><p>翻译自<a href="https://github.com/vuejs/vue/issues/2873" target="_blank" rel="noopener">2.0 Changes</a></p></blockquote>]]></content>
<summary type="html">
<h3 id="v-for迭代语法变化"><a href="#v-for迭代语法变化" class="headerlink" title="v-for迭代语法变化"></a><code>v-for</code>迭代语法变化</h3><ul>
<li>丢弃<del><code>$index</code></del>和<del><code>$key</code></del></li>
<li>新数组语法<ul>
<li>value in arr</li>
<li>(value, index) in arr</li>
</ul>
</li>
<li>新对象语法<ul>
<li>value in obj</li>
<li>(value, key) in obj</li>
<li>(value, key, index) in obj</li>
</ul>
</li>
</ul>
</summary>
<category term="vue" scheme="https://lingmissing.github.io/tags/vue/"/>
</entry>
<entry>
<title>weinre调试手机端</title>
<link href="https://lingmissing.github.io/2016/10/09/user-weinre/"/>
<id>https://lingmissing.github.io/2016/10/09/user-weinre/</id>
<published>2016-10-09T04:04:51.000Z</published>
<updated>2019-01-04T03:41:58.790Z</updated>
<content type="html"><![CDATA[<blockquote><p>安装前提:安装 node</p></blockquote><hr><h3 id="全局安装"><a href="#全局安装" class="headerlink" title="全局安装"></a>全局安装</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm -g install weinre</span><br></pre></td></tr></table></figure><a id="more"></a><h3 id="启动-weinre"><a href="#启动-weinre" class="headerlink" title="启动 weinre"></a>启动 weinre</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">weinre --boundHost -all- --httpPort 8081</span><br></pre></td></tr></table></figure><h3 id="访问页面获取-js"><a href="#访问页面获取-js" class="headerlink" title="访问页面获取 js"></a>访问页面获取 js</h3><p>在浏览器中访问生成的页面获取 js,地址为<code>ip</code>加端口号,如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://[ip]:8081</span><br></pre></td></tr></table></figure><h3 id="粘贴-js"><a href="#粘贴-js" class="headerlink" title="粘贴 js"></a>粘贴 js</h3><p>在上个步骤中的页面找到如下类型的代码,将该 js 引入项目:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><script type="text/javascript">http://[ip]:8081/target/target-script-min.js#{app标识}</script></span><br></pre></td></tr></table></figure><h3 id="启动-webapp"><a href="#启动-webapp" class="headerlink" title="启动 webapp"></a>启动 webapp</h3><h3 id="电脑端访问"><a href="#电脑端访问" class="headerlink" title="电脑端访问"></a>电脑端访问</h3><p>新开标签页输入如下地址并在手机上刷新 app,将会看到数据结构。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://[ip]:8081/client/#{app标识}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<blockquote>
<p>安装前提:安装 node</p>
</blockquote>
<hr>
<h3 id="全局安装"><a href="#全局安装" class="headerlink" title="全局安装"></a>全局安装</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm -g install weinre</span><br></pre></td></tr></table></figure>
</summary>
<category term="weinre" scheme="https://lingmissing.github.io/tags/weinre/"/>
</entry>
<entry>
<title>如何在mac上使用homebrew安装mysql</title>
<link href="https://lingmissing.github.io/2016/10/09/install-mysql-for-mac/"/>
<id>https://lingmissing.github.io/2016/10/09/install-mysql-for-mac/</id>
<published>2016-10-09T03:43:49.000Z</published>
<updated>2019-01-04T03:39:23.400Z</updated>
<content type="html"><![CDATA[<ul><li>安装命令</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install mysql</span><br></pre></td></tr></table></figure><a id="more"></a><ul><li>安装完成之后,本地命令行输入 mysql 命令,发现无此命令</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">command not found</span><br></pre></td></tr></table></figure><ul><li>首先,检查是否是安装了</li></ul><p>重新执行一遍</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install mysql</span><br></pre></td></tr></table></figure><p>命令行提示:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Warning: mysql-5.7.10 already installed, it's just not linked</span><br></pre></td></tr></table></figure><ul><li>然后网上查找解决方法,最后解决方法是执行:</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew link --overwrite mysql</span><br></pre></td></tr></table></figure><ul><li>但是执行,却报错</li></ul><figure class="highlight plain"><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">Linking /usr/local/Cellar/mysql/5.7.10...</span><br><span class="line">Error: Could not symlink share/man/man8/mysqld.8</span><br><span class="line">/usr/local/share/man/man8 is not writable.</span><br></pre></td></tr></table></figure><ul><li>又在网上各种查找解决方法,最后本地实验以下语句执行成功</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo chown -R 'yin' /usr/local</span><br><span class="line">注意: yin是你电脑的用户名</span><br></pre></td></tr></table></figure><ul><li>解决了问题后,重新执行:</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew link --overwrite mysql</span><br></pre></td></tr></table></figure><p>提示:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Linking /usr/local/Cellar/mysql/5.7.10... 92 symlinks created</span><br></pre></td></tr></table></figure><p>心想着,这下算是成功了吧。重新执行:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql -u root -p</span><br></pre></td></tr></table></figure><p>但是又报错:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)</span><br></pre></td></tr></table></figure><p>依次执行:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">unset TMPDIR</span><br><span class="line">bash mysql_install_db --verbose --user=root --basedir="$(brew --prefix mysql)"--datadir=/usr/local/var/mysql --tmpdir=/tmp</span><br></pre></td></tr></table></figure><p>接下来启动 mysql:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bash mysql.server start</span><br></pre></td></tr></table></figure><p>到这里,mysql 的安装就结束了~</p>]]></content>
<summary type="html">
<ul>
<li>安装命令</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install mysql</span><br></pre></td></tr></table></figure>
</summary>
<category term="mysql" scheme="https://lingmissing.github.io/tags/mysql/"/>
</entry>
<entry>
<title>typescript</title>
<link href="https://lingmissing.github.io/2016/09/30/typescript/"/>
<id>https://lingmissing.github.io/2016/09/30/typescript/</id>
<published>2016-09-30T05:30:47.000Z</published>
<updated>2019-01-04T03:41:53.742Z</updated>
<content type="html"><![CDATA[<h2 id="基础类型"><a href="#基础类型" class="headerlink" title="基础类型"></a>基础类型</h2><p>为了让程序有价值,我们需要能够处理最简单的数据单元:数字,字符串,结构体,布尔值等。</p><h3 id="boolean"><a href="#boolean" class="headerlink" title="boolean"></a>boolean</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> isDone: boolean = <span class="literal">false</span></span><br></pre></td></tr></table></figure><a id="more"></a><h3 id="number"><a href="#number" class="headerlink" title="number"></a>number</h3><figure class="highlight javascript"><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="keyword">let</span> decLiteral: number = <span class="number">6</span></span><br><span class="line"><span class="keyword">let</span> hexLiteral: number = <span class="number">0xf00d</span></span><br><span class="line"><span class="keyword">let</span> binaryLiteral: number = <span class="number">0b1010</span></span><br><span class="line"><span class="keyword">let</span> octalLiteral: number = <span class="number">0o744</span></span><br></pre></td></tr></table></figure><h3 id="string"><a href="#string" class="headerlink" title="string"></a>string</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> name: string = <span class="string">'bob'</span></span><br><span class="line">name = <span class="string">'smith'</span></span><br></pre></td></tr></table></figure><p>当然也可以用模板字符串:</p><figure class="highlight javascript"><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="keyword">let</span> name: string = <span class="string">`Gene`</span></span><br><span class="line"><span class="keyword">let</span> age: number = <span class="number">37</span></span><br><span class="line"><span class="keyword">let</span> sentence: string = <span class="string">`Hello, my name is <span class="subst">${name}</span>.I'll be <span class="subst">${age +</span></span></span><br><span class="line"><span class="string"><span class="subst"> <span class="number">1</span>}</span> years old next month.`</span></span><br></pre></td></tr></table></figure><h3 id="array"><a href="#array" class="headerlink" title="array"></a>array</h3><ul><li><p>在元素类型后面接上 [],表示由此类型元素组成的一个数组:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> list: number[] = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br></pre></td></tr></table></figure></li><li><p>使用数组泛型,Array<元素类型>:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> list: <span class="built_in">Array</span><number> = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br></pre></td></tr></table></figure></li></ul><h3 id="元组-Tuple"><a href="#元组-Tuple" class="headerlink" title="元组 Tuple"></a>元组 Tuple</h3><p>元组类型允许表示一个<strong>已知</strong>元素<strong>数量</strong>和<strong>类型</strong>的数组,各元素的类型不必相同。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// Declare a tuple type</span></span><br><span class="line"><span class="keyword">let</span> x: [string, number]</span><br><span class="line"><span class="comment">// Initialize it</span></span><br><span class="line">x = [<span class="string">'hello'</span>, <span class="number">10</span>] <span class="comment">// OK</span></span><br><span class="line"><span class="comment">// Initialize it incorrectly</span></span><br><span class="line">x = [<span class="number">10</span>, <span class="string">'hello'</span>] <span class="comment">// Error</span></span><br></pre></td></tr></table></figure><p>打印出来的结果:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(x[<span class="number">0</span>].substr(<span class="number">1</span>)) <span class="comment">// OK</span></span><br><span class="line"><span class="built_in">console</span>.log(x[<span class="number">1</span>].substr(<span class="number">1</span>)) <span class="comment">// Error, 'number' does not have 'substr'</span></span><br></pre></td></tr></table></figure><h3 id="枚举"><a href="#枚举" class="headerlink" title="枚举"></a>枚举</h3><p>像 C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">enum Color {Red, Green, Blue};</span><br><span class="line"><span class="keyword">let</span> c: Color = Color.Green;</span><br></pre></td></tr></table></figure><p>默认情况下,从 0 开始为元素编号。 你也可以手动的指定成员的数值。 例如,我们将上面的例子改成从 1 开始编号:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">enum Color {Red = <span class="number">1</span>, Green, Blue};</span><br><span class="line"><span class="keyword">let</span> c: Color = Color.Green;</span><br></pre></td></tr></table></figure><p>或者全部手动赋值:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">enum Color {Red = <span class="number">1</span>, Green = <span class="number">2</span>, Blue = <span class="number">4</span>};</span><br><span class="line"><span class="keyword">let</span> c: Color = Color.Green;</span><br></pre></td></tr></table></figure><p>枚举类型提供的一个便利是你可以由枚举的值得到它的名字。 例如,我们知道数值为 2,但是不确定它映射到 Color 里的哪个名字,我们可以查找相应的名字:</p><figure class="highlight javascript"><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">enum Color {Red = <span class="number">1</span>, Green, Blue};</span><br><span class="line"><span class="keyword">let</span> colorName: string = Color[<span class="number">2</span>];</span><br><span class="line"></span><br><span class="line">alert(colorName);</span><br></pre></td></tr></table></figure><h3 id="任意值"><a href="#任意值" class="headerlink" title="任意值"></a>任意值</h3><figure class="highlight javascript"><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="keyword">let</span> notSure: any = <span class="number">4</span></span><br><span class="line">notSure = <span class="string">'maybe a string instead'</span></span><br><span class="line">notSure = <span class="literal">false</span> <span class="comment">// okay, definitely a boolean</span></span><br></pre></td></tr></table></figure><h3 id="空值"><a href="#空值" class="headerlink" title="空值"></a>空值</h3><p>某种程度上来说,void 类型像是与 any 类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void:</p><figure class="highlight javascript"><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="function"><span class="keyword">function</span> <span class="title">warnUser</span>(<span class="params"></span>): <span class="title">void</span> </span>{</span><br><span class="line"> alert(<span class="string">'This is my warning message'</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="Null-和-Undefined"><a href="#Null-和-Undefined" class="headerlink" title="Null 和 Undefined"></a>Null 和 Undefined</h3><figure class="highlight javascript"><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="comment">// Not much else we can assign to these variables!</span></span><br><span class="line"><span class="keyword">let</span> u: <span class="literal">undefined</span> = <span class="literal">undefined</span></span><br><span class="line"><span class="keyword">let</span> n: <span class="literal">null</span> = <span class="literal">null</span></span><br></pre></td></tr></table></figure><h3 id="类型断言"><a href="#类型断言" class="headerlink" title="类型断言"></a>类型断言</h3><p>类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。</p><ul><li><p>“尖括号”语法:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> someValue: any = <span class="string">"this is a string"</span>;</span><br><span class="line"><span class="keyword">let</span> strLength: number = (<span class="xml"><span class="tag"><<span class="name">string</span>></span>someValue).length;</span></span><br></pre></td></tr></table></figure></li><li><p>as 语法</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> someValue: any = <span class="string">"this is a string"</span>;</span><br><span class="line"><span class="keyword">let</span> strLength: number = (someValue <span class="keyword">as</span> string).length;</span><br></pre></td></tr></table></figure></li></ul><h2 id="变量声明"><a href="#变量声明" class="headerlink" title="变量声明"></a>变量声明</h2><h3 id="var-声明"><a href="#var-声明" class="headerlink" title="var 声明"></a>var 声明</h3><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">f</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> a = <span class="number">10</span></span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> <span class="title">g</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> b = a + <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> b</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> g = f()</span><br><span class="line">g() <span class="comment">// returns 11;</span></span><br></pre></td></tr></table></figure><h3 id="let-声明"><a href="#let-声明" class="headerlink" title="let 声明"></a>let 声明</h3><h3 id="const-声明"><a href="#const-声明" class="headerlink" title="const 声明"></a>const 声明</h3><p>const 拥有与 let 相同的作用域规则,但是不能对它们重新赋值。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> numLivesForCat = <span class="number">9</span></span><br><span class="line"><span class="keyword">const</span> kitty = {</span><br><span class="line"> name: <span class="string">'Aurora'</span>,</span><br><span class="line"> numLives: numLivesForCat</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Error</span></span><br><span class="line">kitty = {</span><br><span class="line"> name: <span class="string">'Danielle'</span>,</span><br><span class="line"> numLives: numLivesForCat</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// all "okay"</span></span><br><span class="line">kitty.name = <span class="string">'Rory'</span></span><br><span class="line">kitty.name = <span class="string">'Kitty'</span></span><br><span class="line">kitty.name = <span class="string">'Cat'</span></span><br><span class="line">kitty.numLives--</span><br></pre></td></tr></table></figure><h3 id="let-vs-const"><a href="#let-vs-const" class="headerlink" title="let vs. const"></a>let vs. const</h3><p>使用最小特权原则,所有变量除了你计划去修改的都应该使用 const。 基本原则就是如果一个变量不需要对它写入,那么其它使用这些代码的人也不能够写入它们,并且要思考为什么会需要对这些变量重新赋值。 使用 const 也可以让我们更容易的推测数据的流动。</p><h2 id="接口"><a href="#接口" class="headerlink" title="接口"></a>接口</h2><h3 id="接口初探"><a href="#接口初探" class="headerlink" title="接口初探"></a>接口初探</h3><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">printLabel</span>(<span class="params">labelledObj: { label: string }</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(labelledObj.label)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> myObj = { <span class="attr">size</span>: <span class="number">10</span>, <span class="attr">label</span>: <span class="string">'Size 10 Object'</span> }</span><br><span class="line">printLabel(myObj)</span><br></pre></td></tr></table></figure><p>类型检查器会查看 printLabel 的调用。 printLabel 有一个参数,并要求这个对象参数有一个名为 label 类型为 string 的属性。<br>下面我们重写上面的例子,这次使用接口来描述:必须包含一个 label 属性且类型为 string:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 定义接口</span></span><br><span class="line">interface LabelledValue {</span><br><span class="line"> label: string;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">printLabel</span>(<span class="params">labelledObj: LabelledValue</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(labelledObj.label)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> myObj = { <span class="attr">size</span>: <span class="number">10</span>, <span class="attr">label</span>: <span class="string">'Size 10 Object'</span> }</span><br><span class="line">printLabel(myObj)</span><br></pre></td></tr></table></figure><p>LabelledValue 接口就好比一个名字,用来描述上面例子里的要求。 它代表了有一个 label 属性且类型为 string 的对象。</p><h3 id="可选属性"><a href="#可选属性" class="headerlink" title="可选属性"></a>可选属性</h3><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">interface SquareConfig {</span><br><span class="line"> color?: string;</span><br><span class="line"> width?: number;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">createSquare</span>(<span class="params">config: SquareConfig</span>): </span>{ color: string, <span class="attr">area</span>: number } {</span><br><span class="line"> <span class="keyword">let</span> newSquare = { <span class="attr">color</span>: <span class="string">'white'</span>, <span class="attr">area</span>: <span class="number">100</span> }</span><br><span class="line"> <span class="keyword">if</span> (config.color) {</span><br><span class="line"> newSquare.color = config.color</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (config.width) {</span><br><span class="line"> newSquare.area = config.width * config.width</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> newSquare</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> mySquare = createSquare({ <span class="attr">color</span>: <span class="string">'black'</span> })</span><br></pre></td></tr></table></figure><p>带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号。</p><h3 id="只读属性"><a href="#只读属性" class="headerlink" title="只读属性"></a>只读属性</h3><p>一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 readonly 来指定只读属性:</p><figure class="highlight javascript"><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">interface Point {</span><br><span class="line"> readonly x: number;</span><br><span class="line"> readonly y: number;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>你可以通过赋值一个对象字面量来构造一个 Point。 赋值后, x 和 y 再也不能被改变了。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> p1: Point = { <span class="attr">x</span>: <span class="number">10</span>, <span class="attr">y</span>: <span class="number">20</span> }</span><br><span class="line">p1.x = <span class="number">5</span> <span class="comment">// error!</span></span><br></pre></td></tr></table></figure><p>TypeScript 具有 ReadonlyArray<t>类型,它与 Array<t>相似,只是把怕有可变方法去掉了,因此可以确保数组创建后再也不能被修改:</t></t></p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> a: number[] = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line"><span class="keyword">let</span> ro: ReadonlyArray<number> = a</span><br><span class="line">ro[<span class="number">0</span>] = <span class="number">12</span> <span class="comment">// error!</span></span><br><span class="line">ro.push(<span class="number">5</span>) <span class="comment">// error!</span></span><br><span class="line">ro.length = <span class="number">100</span> <span class="comment">// error!</span></span><br><span class="line">a = ro <span class="comment">// error!</span></span><br></pre></td></tr></table></figure><p>就算使用赋值也不可以,除非使用类型断言重写:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">a = ro <span class="keyword">as</span> number[];</span><br></pre></td></tr></table></figure><h4 id="readonly-vs-const"><a href="#readonly-vs-const" class="headerlink" title="readonly vs const"></a>readonly vs const</h4><p>最简单判断该用 readonly 还是 const 的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用 const,若做为属性则使用 readonly。</p><h3 id="函数类型"><a href="#函数类型" class="headerlink" title="函数类型"></a>函数类型</h3><h2 id="类"><a href="#类" class="headerlink" title="类"></a>类</h2>]]></content>
<summary type="html">
<h2 id="基础类型"><a href="#基础类型" class="headerlink" title="基础类型"></a>基础类型</h2><p>为了让程序有价值,我们需要能够处理最简单的数据单元:数字,字符串,结构体,布尔值等。</p>
<h3 id="boolean"><a href="#boolean" class="headerlink" title="boolean"></a>boolean</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> isDone: boolean = <span class="literal">false</span></span><br></pre></td></tr></table></figure>
</summary>
<category term="javascript" scheme="https://lingmissing.github.io/tags/javascript/"/>
<category term="typescript" scheme="https://lingmissing.github.io/tags/typescript/"/>
</entry>
<entry>
<title>Action构建工具(redux-act)</title>
<link href="https://lingmissing.github.io/2016/09/29/redux-act/"/>
<id>https://lingmissing.github.io/2016/09/29/redux-act/</id>
<published>2016-09-29T02:58:40.000Z</published>
<updated>2019-01-04T03:41:01.033Z</updated>
<content type="html"><![CDATA[<p>github 路径:<a href="https://github.com/pauldijou/redux-act" target="_blank" rel="noopener">https://github.com/pauldijou/redux-act</a></p><p>这是一个自用的工具用于创建<code>actions</code>和<code>reducers</code>用于<code>redux</code>。主要的目标是使用<code>action</code>本身作为<code>reducer</code>的引用而不是变量。</p><a id="more"></a><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><pre><code>npm install redux-act --save</code></pre><h2 id="用法"><a href="#用法" class="headerlink" title="用法"></a>用法</h2><p>这里有一个名叫<code>createAction</code>的函数,它用于创建一个<code>action</code>,和名叫<code>createActionCreator</code>的方法有点接近。如果你不能确定是否是<code>action</code>或<code>action</code>创造者,那么记住当<code>action</code>创造者是方法时,<code>action</code>是对象。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// Import functions</span></span><br><span class="line"><span class="keyword">import</span> { createStore } <span class="keyword">from</span> <span class="string">'redux'</span></span><br><span class="line"><span class="keyword">import</span> { createAction, createReducer } <span class="keyword">from</span> <span class="string">'redux-act'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Create an action creator (description is optional)</span></span><br><span class="line"><span class="keyword">const</span> add = createAction(<span class="string">'add some stuff'</span>)</span><br><span class="line"><span class="keyword">const</span> increment = createAction(<span class="string">'increment the state'</span>)</span><br><span class="line"><span class="keyword">const</span> decrement = createAction(<span class="string">'decrement the state'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Create a reducer</span></span><br><span class="line"><span class="comment">// (ES6 syntax, see Advanced usage below for an alternative for ES5)</span></span><br><span class="line"><span class="keyword">const</span> counterReducer = createReducer(</span><br><span class="line"> {</span><br><span class="line"> [increment]: <span class="function"><span class="params">state</span> =></span> state + <span class="number">1</span>,</span><br><span class="line"> [decrement]: <span class="function"><span class="params">state</span> =></span> state - <span class="number">1</span>,</span><br><span class="line"> [add]: <span class="function">(<span class="params">state, payload</span>) =></span> state + payload</span><br><span class="line"> },</span><br><span class="line"> <span class="number">0</span></span><br><span class="line">) <span class="comment">// <-- This is the default state</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Create the store</span></span><br><span class="line"><span class="keyword">const</span> counterStore = createStore(counterReducer)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Dispatch actions</span></span><br><span class="line">counterStore.dispatch(increment()) <span class="comment">// counterStore.getState() === 1</span></span><br><span class="line">counterStore.dispatch(increment()) <span class="comment">// counterStore.getState() === 2</span></span><br><span class="line">counterStore.dispatch(decrement()) <span class="comment">// counterStore.getState() === 1</span></span><br><span class="line">counterStore.dispatch(add(<span class="number">5</span>)) <span class="comment">// counterStore.getState() === 6</span></span><br></pre></td></tr></table></figure><h2 id="高级用法"><a href="#高级用法" class="headerlink" title="高级用法"></a>高级用法</h2><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { createStore } <span class="keyword">from</span> <span class="string">'redux'</span></span><br><span class="line"><span class="keyword">import</span> { createAction, createReducer } <span class="keyword">from</span> <span class="string">'redux-act'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// You can create several action creators at once</span></span><br><span class="line"><span class="comment">// (but that's probably not the best way to do it)</span></span><br><span class="line"><span class="keyword">const</span> [increment, decrement] = [<span class="string">'inc'</span>, <span class="string">'dec'</span>].map(createAction)</span><br><span class="line"></span><br><span class="line"><span class="comment">// When creating action creators, the description is optional</span></span><br><span class="line"><span class="comment">// it will only be used for devtools and logging stuff.</span></span><br><span class="line"><span class="comment">// It's better to put something but feel free to leave it empty if you want to.</span></span><br><span class="line"><span class="keyword">const</span> replace = createAction()</span><br><span class="line"></span><br><span class="line"><span class="comment">// By default, the payload of the action is the first argument</span></span><br><span class="line"><span class="comment">// when you call the action. If you need to support several arguments,</span></span><br><span class="line"><span class="comment">// you can specify a function on how to merge all arguments into</span></span><br><span class="line"><span class="comment">// an unique payload.</span></span><br><span class="line"><span class="keyword">let</span> append = createAction(<span class="string">'optional description'</span>, (...args) => args.join(<span class="string">''</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment">// There is another pattern to create reducers</span></span><br><span class="line"><span class="comment">// and it works fine with ES5! (maybe even ES3 \o/)</span></span><br><span class="line"><span class="keyword">const</span> stringReducer = createReducer(<span class="function"><span class="keyword">function</span>(<span class="params">on</span>) </span>{</span><br><span class="line"> on(replace, (state, payload) => payload)</span><br><span class="line"> on(append, (state, payload) => (state += payload))</span><br><span class="line"> <span class="comment">// Warning! If you use the same action twice,</span></span><br><span class="line"> <span class="comment">// the second one will override the previous one.</span></span><br><span class="line">}, <span class="string">'missing a lette'</span>) <span class="comment">// <-- Default state</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Rather than binding the action creators each time you want to use them,</span></span><br><span class="line"><span class="comment">// you can do it once and for all as soon as you have the targeted store</span></span><br><span class="line"><span class="comment">// assignTo: mutates the action creator itself</span></span><br><span class="line"><span class="comment">// bindTo: returns a new action creator assigned to the store</span></span><br><span class="line"><span class="keyword">const</span> stringStore = createStore(stringReducer)</span><br><span class="line">replace.assignTo(stringStore)</span><br><span class="line">append = append.bindTo(stringStore)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Now, when calling actions, they will be automatically dispatched</span></span><br><span class="line">append(<span class="string">'r'</span>) <span class="comment">// stringStore.getState() === 'missing a letter'</span></span><br><span class="line">replace(<span class="string">'a'</span>) <span class="comment">// stringStore.getState() === 'a'</span></span><br><span class="line">append(<span class="string">'b'</span>, <span class="string">'c'</span>, <span class="string">'d'</span>) <span class="comment">// stringStore.getState() === 'abcd'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// If you really need serializable actions, using string constant rather</span></span><br><span class="line"><span class="comment">// than runtime generated id, just use a uppercase description (with eventually some underscores)</span></span><br><span class="line"><span class="comment">// and it will be use as the id of the action</span></span><br><span class="line"><span class="keyword">const</span> doSomething = createAction(<span class="string">'STRING_CONSTANT'</span>)</span><br><span class="line">doSomething(<span class="number">1</span>) <span class="comment">// { type: 'STRING_CONSTANT', payload: 1}</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Little bonus, if you need to support metadata around your action,</span></span><br><span class="line"><span class="comment">// like needed data but not really part of the payload, you add a second function</span></span><br><span class="line"><span class="keyword">const</span> metaAction = createAction(</span><br><span class="line"> <span class="string">'desc'</span>,</span><br><span class="line"> arg => arg,</span><br><span class="line"> arg => ({ <span class="attr">meta</span>: <span class="string">'so meta!'</span> })</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Metadata will be the third argument of the reduce function</span></span><br><span class="line">createReducer({</span><br><span class="line"> [metaAction]: <span class="function">(<span class="params">state, payload, meta</span>) =></span> payload</span><br><span class="line">})</span><br></pre></td></tr></table></figure><h2 id="API-说明"><a href="#API-说明" class="headerlink" title="API 说明"></a>API 说明</h2><h3 id="createAction-description-payloadReducer-metaReducer"><a href="#createAction-description-payloadReducer-metaReducer" class="headerlink" title="createAction([description], [payloadReducer], [metaReducer])"></a>createAction([description], [payloadReducer], [metaReducer])</h3><h4 id="参数"><a href="#参数" class="headerlink" title="参数"></a>参数</h4><ul><li>description(字符串,可选) 当显示的时候用于注册 action 名称和在开发者工具中使用。如果这个参数只是大写,它可以在不用生成任何 id 的情况下被用作<code>action</code>类型。你可以使用这个特性在服务端和客户端中有序整理<code>action</code>。</li><li>payloadReducer(方法,可选) 转变多个参数作为唯一的<code>payload</code>。</li><li>metaReducer(方法,可选) 转变多个参数作为唯一的元数据对象。</li></ul><h4 id="用法-1"><a href="#用法-1" class="headerlink" title="用法"></a>用法</h4><p>返回一个新的<code>action</code>构造器。如果你指定了<code>description</code>,它将被开发者工具使用。默认情况下,<code>createAction</code>返回一个方法,并且触发它的时候第一个参数被作为<code>payload</code>。如果你想支持多个参数,你需要指定一个<code>payloadReducer</code>来把所有的参数合并到<code>payload</code>中。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// Super simple action</span></span><br><span class="line"><span class="keyword">const</span> simpleAction = createAction()</span><br><span class="line"><span class="comment">// Better to add a description</span></span><br><span class="line"><span class="keyword">const</span> betterAction = createAction(<span class="string">'This is better!'</span>)</span><br><span class="line"><span class="comment">// Support multiple arguments by merging them</span></span><br><span class="line"><span class="keyword">const</span> multipleAction = createAction(<span class="function">(<span class="params">text, checked</span>) =></span> ({ text, checked }))</span><br><span class="line"><span class="comment">// Again, better to add a description</span></span><br><span class="line"><span class="keyword">const</span> bestAction = createAction(<span class="string">'Best. Action. Ever.'</span>, (text, checked) => ({</span><br><span class="line"> text,</span><br><span class="line"> checked</span><br><span class="line">}))</span><br><span class="line"><span class="comment">// Serializable action (the description will be used as the unique identifier)</span></span><br><span class="line"><span class="keyword">const</span> serializableAction = createAction(<span class="string">'SERIALIZABLE_ACTION'</span>)</span><br></pre></td></tr></table></figure><h3 id="action-creator"><a href="#action-creator" class="headerlink" title="action creator"></a>action creator</h3><p><code>action</code>创造器基本上是一个携带参数并且返回<code>action</code>的方法,它具有以下格式:</p><ul><li>type:通过参数<code>description</code>生成 id</li><li>payload:当调用<code>action creator</code>时进行数据传递,传递的是第一个参数除非在创建<code>action</code>时指定了<code>payloadReducer</code>.</li><li>meta:如果你提供了<code>metaReducer</code>,它将创建一个<code>metadata</code>对象分配给这个<code>key</code>,否则它是<code>undefined</code></li></ul><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> addTodo = createAction(<span class="string">'Add todo'</span>)</span><br><span class="line">addTodo(<span class="string">'content'</span>)</span><br><span class="line"><span class="comment">// return { type: '[1] Add todo', payload: 'content' }</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> editTodo = createAction(<span class="string">'Edit todo'</span>, (id, content) => ({ id, content }))</span><br><span class="line">editTodo(<span class="number">42</span>, <span class="string">'the answer'</span>)</span><br><span class="line"><span class="comment">// return { type: '[2] Edit todo', payload: {id: 42, content: 'the answer'} }</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> serializeTodo = createAction(<span class="string">'SERIALIZE_TODO'</span>)</span><br><span class="line">serializeTodo(<span class="number">1</span>)</span><br><span class="line"><span class="comment">// return { type: 'SERIALIZE_TODO', payload: 1 }</span></span><br></pre></td></tr></table></figure><p><code>action creator</code>有以下方法:</p><h5 id="getType"><a href="#getType" class="headerlink" title="getType()"></a>getType()</h5><p>返回生成的类型并被用于这个<code>action creator</code>的所有<code>action</code>。</p><h5 id="assignTo-store-dispatch"><a href="#assignTo-store-dispatch" class="headerlink" title="assignTo(store | dispatch)"></a>assignTo(store | dispatch)</h5><p>记住你要触发这些<code>actions</code>,如果你有一个或多个<code>stores</code>,可以通过<code>assignTo</code>分配这些<code>action</code>。这会改变<code>action creator</code>本身,你可以传递一个<code>store</code>或者<code>dispatch</code>方法或者数组。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> action = createAction()</span><br><span class="line"><span class="keyword">let</span> action2 = createAction()</span><br><span class="line"><span class="keyword">const</span> reducer = createReducer({</span><br><span class="line"> [action]: <span class="function"><span class="params">state</span> =></span> state * <span class="number">2</span>,</span><br><span class="line"> [action2]: <span class="function"><span class="params">state</span> =></span> state / <span class="number">2</span></span><br><span class="line">})</span><br><span class="line"><span class="keyword">const</span> store = createStore(reducer, <span class="number">1</span>)</span><br><span class="line"><span class="keyword">const</span> store2 = createStore(reducer, <span class="number">-1</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Automatically dispatch the action to the store when called</span></span><br><span class="line">action.assignTo(store)</span><br><span class="line">action() <span class="comment">// store.getState() === 2</span></span><br><span class="line">action() <span class="comment">// store.getState() === 4</span></span><br><span class="line">action() <span class="comment">// store.getState() === 8</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// You can assign the action to several stores using an array</span></span><br><span class="line">action.assignTo([store, store2])</span><br><span class="line">action()</span><br><span class="line"><span class="comment">// store.getState() === 16</span></span><br><span class="line"><span class="comment">// store2.getState() === -2</span></span><br></pre></td></tr></table></figure><h5 id="bindTo-store-dispatch"><a href="#bindTo-store-dispatch" class="headerlink" title="bindTo(store | dispatch)"></a>bindTo(store | dispatch)</h5><p>如果你需要不可变,你可以使用该方法。它将生成一个新的<code>action creator</code>并且能够自动触发<code>action</code>。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// If you need more immutability, you can bind them, creating a new action creator</span></span><br><span class="line"><span class="keyword">const</span> boundAction = action2.bindTo(store)</span><br><span class="line">action2() <span class="comment">// Not doing anything since not assigned nor bound</span></span><br><span class="line"><span class="comment">// store.getState() === 16</span></span><br><span class="line"><span class="comment">// store2.getState() === -2</span></span><br><span class="line">boundAction() <span class="comment">// store.getState() === 8</span></span><br></pre></td></tr></table></figure><h5 id="assigned-bound-dispatched"><a href="#assigned-bound-dispatched" class="headerlink" title="assigned() / bound() / dispatched()"></a>assigned() / bound() / dispatched()</h5><p>测试<code>action creator</code>的当前状态。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> action = createAction()</span><br><span class="line">action.assigned() <span class="comment">// false, not assigned</span></span><br><span class="line">action.bound() <span class="comment">// false, not bound</span></span><br><span class="line">action.dispatched() <span class="comment">// false, test if either assigned or bound</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> boundAction = action.bindTo(store)</span><br><span class="line">boundAction.assigned() <span class="comment">// false</span></span><br><span class="line">boundAction.bound() <span class="comment">// true</span></span><br><span class="line">boundAction.dispatched() <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line">action.assignTo(store)</span><br><span class="line">action.assigned() <span class="comment">// true</span></span><br><span class="line">action.bound() <span class="comment">// false</span></span><br><span class="line">action.dispatched() <span class="comment">// true</span></span><br></pre></td></tr></table></figure><h5 id="raw-…args"><a href="#raw-…args" class="headerlink" title="raw(…args)"></a>raw(…args)</h5><p>当<code>action creator</code>无论是分配还是绑定,将不再返回<code>action</code>对象而是触发它。有些情况下,你需要没有触发的<code>action</code>。为了达到这个目的,你可以使用<code>raw</code>方法返回纯粹的<code>action</code>。</p><figure class="highlight javascript"><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="keyword">const</span> action = createAction().bindTo(store)</span><br><span class="line">action(<span class="number">1</span>) <span class="comment">// store has been updated</span></span><br><span class="line">action.raw(<span class="number">1</span>) <span class="comment">// return the action, store hasn't been updated</span></span><br></pre></td></tr></table></figure><h3 id="createReducer-handlers-defaultState"><a href="#createReducer-handlers-defaultState" class="headerlink" title="createReducer(handlers, [defaultState])"></a>createReducer(handlers, [defaultState])</h3><h4 id="参数-1"><a href="#参数-1" class="headerlink" title="参数"></a>参数</h4><ul><li>handlers(对象或方法):如果是方法则携带两个属性,一是注册<code>action</code>,二是取消注册,如下。</li><li>defaultState(任意,可选):<code>reducer</code>的初始状态,如果要在<code>combineReducers</code>使用千万不能为空。</li></ul><h4 id="用法-2"><a href="#用法-2" class="headerlink" title="用法"></a>用法</h4><p>返回一个新的<code>reducer</code>。和<code>Array.prototype.reduce</code>的语法类似,你可以指定如何累加,比如第一个参数并累加,或者默认的状态。默认的状态是可选的,因为创建时可以在<code>store</code>中获取,但你需要注意<code>reducer</code>中始终存在默认状态,尤其是你要结合<code>combineReducers</code>使用时。<br>有两种创建<code>reducer</code>的方式,一种是通过对象集合,所有方法必须遵循<code>previousState, payload) => newState</code>。另一种是使用工厂模式,话不多说,看下面的例子。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> increment = createAction()</span><br><span class="line"><span class="keyword">const</span> add = createAction()</span><br><span class="line"></span><br><span class="line"><span class="comment">// First pattern</span></span><br><span class="line"><span class="keyword">const</span> reducerMap = createReducer(</span><br><span class="line"> {</span><br><span class="line"> [increment]: <span class="function"><span class="params">state</span> =></span> state + <span class="number">1</span>,</span><br><span class="line"> [add]: <span class="function">(<span class="params">state, payload</span>) =></span> state + payload</span><br><span class="line"> },</span><br><span class="line"> <span class="number">0</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Second pattern</span></span><br><span class="line"><span class="keyword">const</span> reducerFactory = createReducer(<span class="function"><span class="keyword">function</span>(<span class="params">on, off</span>) </span>{</span><br><span class="line"> on(increment, state => state + <span class="number">1</span>)</span><br><span class="line"> on(add, (state, payload) => state + payload)</span><br><span class="line"> <span class="comment">// 'off' remove support for a specific action</span></span><br><span class="line"> <span class="comment">// See 'Adding and removing actions' section</span></span><br><span class="line">}, <span class="number">0</span>)</span><br></pre></td></tr></table></figure><h3 id="reducer"><a href="#reducer" class="headerlink" title="reducer"></a>reducer</h3><p><code>reducer</code>就是一个方法。它当前的状态和行为并返回新的状态,有以下方法:</p><h4 id="options-object"><a href="#options-object" class="headerlink" title="options(object)"></a>options(object)</h4><p>因为<code>action</code>是带有<code>type</code>、<code>payload</code>甚至还有<code>metadata</code>的对象。所有的<code>reduce</code>方法默认将<code>payload</code>作为它们的第二个参数,<code>metadata</code>作为第三个参数,而不是所有的<code>action</code>。因为所有其他属性由 lib 处理不用关心。如果你要使用全部的<code>action</code>,你可以改变<code>reducer</code>的行为。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> add = createAction()</span><br><span class="line"><span class="keyword">const</span> sub = createAction()</span><br><span class="line"><span class="keyword">const</span> reducer = createReducer(</span><br><span class="line"> {</span><br><span class="line"> [add]: <span class="function">(<span class="params">state, action</span>) =></span> state + action.payload,</span><br><span class="line"> [sub]: <span class="function">(<span class="params">state, action</span>) =></span> state - action.payload</span><br><span class="line"> },</span><br><span class="line"> <span class="number">0</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">reducer.options({</span><br><span class="line"> payload: <span class="literal">false</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure><h4 id="has-action-creator"><a href="#has-action-creator" class="headerlink" title="has(action creator)"></a>has(action creator)</h4><p>检测<code>reducer</code>是否含有<code>reduce</code>方法对于特定的<code>action</code>或者字符串类型。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> add = createAction()</span><br><span class="line"><span class="keyword">const</span> sub = createAction()</span><br><span class="line"><span class="keyword">const</span> reducer = createReducer(</span><br><span class="line"> {</span><br><span class="line"> [add]: <span class="function">(<span class="params">state, action</span>) =></span> state + action.payload</span><br><span class="line"> },</span><br><span class="line"> <span class="number">0</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">reducer.has(add) <span class="comment">// true</span></span><br><span class="line">reducer.has(sub) <span class="comment">// false</span></span><br><span class="line">reducer.has(add.getType()) <span class="comment">// true</span></span><br></pre></td></tr></table></figure><h4 id="on-action-creator-reduce-function-off-action-creator"><a href="#on-action-creator-reduce-function-off-action-creator" class="headerlink" title="on(action creator, reduce function) / off(action creator)"></a>on(action creator, reduce function) / off(action creator)</h4><p>可以动态添加或删除 action。</p><h3 id="assignAll-actionCreators-stores"><a href="#assignAll-actionCreators-stores" class="headerlink" title="assignAll(actionCreators, stores)"></a>assignAll(actionCreators, stores)</h3><h4 id="参数-2"><a href="#参数-2" class="headerlink" title="参数"></a>参数</h4><ul><li>actionCreators(对象或数组)</li><li>stores(对象或数组)</li></ul><h4 id="用法-3"><a href="#用法-3" class="headerlink" title="用法"></a>用法</h4><p>普遍的方式是导出一系列的 action 作为对象,如果你需要将所有绑定到 store,这里有一个超级小帮手。也可以使用 action 数组。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// actions.js</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> add = createAction(<span class="string">'Add'</span>);</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> sub = createAction(<span class="string">'Sub'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// reducer.js</span></span><br><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> actions <span class="keyword">from</span> <span class="string">'./actions'</span>;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> createReducer({</span><br><span class="line"> [actions.add]: <span class="function">(<span class="params">state, payload</span>) =></span> state + payload,</span><br><span class="line"> [actions.sub]: <span class="function">(<span class="params">state, payload</span>) =></span> state - payload</span><br><span class="line">}, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// store.js</span></span><br><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> actions <span class="keyword">from</span> <span class="string">'./actions'</span>;</span><br><span class="line"><span class="keyword">import</span> reducer <span class="keyword">from</span> <span class="string">'./reducer'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> store = createStore(reducer);</span><br><span class="line">assignAll(actions, store);</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> store;</span><br></pre></td></tr></table></figure><h3 id="bindAll-actionCreators-stores"><a href="#bindAll-actionCreators-stores" class="headerlink" title="bindAll(actionCreators, stores)"></a>bindAll(actionCreators, stores)</h3><h4 id="参数-3"><a href="#参数-3" class="headerlink" title="参数"></a>参数</h4><ul><li>actionCreators(对象或数组)</li><li>stores(对象或数组)</li></ul><h4 id="用法-4"><a href="#用法-4" class="headerlink" title="用法"></a>用法</h4><p>类似于<code>assignAll</code>,可以立刻绑定<code>action</code>。</p><figure class="highlight javascript"><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="keyword">import</span> { bindAll } <span class="keyword">from</span> <span class="string">'redux-act'</span>;</span><br><span class="line"><span class="keyword">import</span> store <span class="keyword">from</span> <span class="string">'./store'</span>;</span><br><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> actions <span class="keyword">from</span> <span class="string">'./actions'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> bindAll(actions, store);</span><br></pre></td></tr></table></figure><h3 id="disbatch-store-dispatch-actions"><a href="#disbatch-store-dispatch-actions" class="headerlink" title="disbatch(store | dispatch, [actions])"></a>disbatch(store | dispatch, [actions])</h3><h4 id="参数-4"><a href="#参数-4" class="headerlink" title="参数"></a>参数</h4><ul><li>store | dispatch (对象,store 或 diaptch 方法),在<code>store</code>上添加<code>disbatch</code>方法,类似于<code>diaptch</code>,但这个是触发多个<code>action</code>。</li><li>actions(数组,可选) 需要触发的一些<code>action</code></li></ul><h4 id="用法-5"><a href="#用法-5" class="headerlink" title="用法"></a>用法</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// All samples will display both syntax with and without an array</span></span><br><span class="line"><span class="comment">// They are exactly the same</span></span><br><span class="line"><span class="keyword">import</span> { disbatch } <span class="keyword">from</span> <span class="string">'redux-act'</span></span><br><span class="line"><span class="keyword">import</span> { inc, dec } <span class="keyword">from</span> <span class="string">'./actions'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Add 'disbatch' directly to the store</span></span><br><span class="line">disbatch(store)</span><br><span class="line">store.disbatch(inc(), dec(), inc())</span><br><span class="line">store.disbatch([inc(), dec(), inc()])</span><br><span class="line"></span><br><span class="line"><span class="comment">// Disbatch immediately from store</span></span><br><span class="line">disbatch(store, inc(), dec(), inc())</span><br><span class="line">disbatch(store, [inc(), dec(), inc()])</span><br><span class="line"></span><br><span class="line"><span class="comment">// Disbatch immediately from dispatch</span></span><br><span class="line">disbatch(store.dispatch, inc(), dec(), inc())</span><br><span class="line">disbatch(store.dispatch, [inc(), dec(), inc()])</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>github 路径:<a href="https://github.com/pauldijou/redux-act" target="_blank" rel="noopener">https://github.com/pauldijou/redux-act</a></p>
<p>这是一个自用的工具用于创建<code>actions</code>和<code>reducers</code>用于<code>redux</code>。主要的目标是使用<code>action</code>本身作为<code>reducer</code>的引用而不是变量。</p>
</summary>
<category term="react" scheme="https://lingmissing.github.io/tags/react/"/>
<category term="redux" scheme="https://lingmissing.github.io/tags/redux/"/>
</entry>
<entry>
<title>webpack插件列表详解</title>
<link href="https://lingmissing.github.io/2016/09/28/webpack-list-plugin/"/>
<id>https://lingmissing.github.io/2016/09/28/webpack-list-plugin/</id>
<published>2016-09-28T06:39:17.000Z</published>
<updated>2019-01-04T03:42:16.246Z</updated>
<content type="html"><![CDATA[<h2 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h2><h3 id="NormalModuleReplacementPlugin"><a href="#NormalModuleReplacementPlugin" class="headerlink" title="NormalModuleReplacementPlugin"></a>NormalModuleReplacementPlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.NormalModuleReplacementPlugin(resourceRegExp, newResource)</span><br></pre></td></tr></table></figure><a id="more"></a><p>Replace resources that matches resourceRegExp with newResource. If newResource is relative, it is resolve relative to the previous resource. If newResource is a function, it is expected to overwrite the ‘request’ attribute of the supplied object.</p><h3 id="ContextReplacementPlugin"><a href="#ContextReplacementPlugin" class="headerlink" title="ContextReplacementPlugin"></a>ContextReplacementPlugin</h3><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.ContextReplacementPlugin(</span><br><span class="line"> resourceRegExp,</span><br><span class="line"> [newContentResource],</span><br><span class="line"> [newContentRecursive],</span><br><span class="line"> [newContentRegExp]</span><br><span class="line">)</span><br></pre></td></tr></table></figure><h3 id="IgnorePlugin"><a href="#IgnorePlugin" class="headerlink" title="IgnorePlugin"></a>IgnorePlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.IgnorePlugin(requestRegExp, [contextRegExp])</span><br></pre></td></tr></table></figure><p>不要为匹配的正则生成模块。</p><ul><li>requestRegExp 正则用于测试需求</li><li>contextRegExp(可选) 正则用于测试上下文(目录)</li></ul><h3 id="PrefetchPlugin"><a href="#PrefetchPlugin" class="headerlink" title="PrefetchPlugin"></a>PrefetchPlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.PrefetchPlugin([context], request)</span><br></pre></td></tr></table></figure><p>A request for a normal module, which is resolved and built even before a require to it occurs. This can boost performance. Try to profile the build first to determine clever prefetching points.</p><ul><li>context 目录的绝对路径</li><li>request 普通模块的请求字符串</li></ul><h3 id="ResolverPlugin"><a href="#ResolverPlugin" class="headerlink" title="ResolverPlugin"></a>ResolverPlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.ResolverPlugin(plugins, [types])</span><br></pre></td></tr></table></figure><p>应用一个插件(或插件数组),作用于一个或多个解析器。</p><ul><li>plugins 应用于解析器的插件或插件数组</li><li>types 解析器类型或解析器类型数组(默认:[“normal”],解析器类型:normal, context, loader)<br>例子:</li></ul><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.ResolverPlugin(</span><br><span class="line"> [</span><br><span class="line"> <span class="keyword">new</span> webpack.ResolverPlugin.DirectoryDescriptionFilePlugin(<span class="string">'bower.json'</span>, [</span><br><span class="line"> <span class="string">'main'</span></span><br><span class="line"> ])</span><br><span class="line"> ],</span><br><span class="line"> [<span class="string">'normal'</span>, <span class="string">'loader'</span>]</span><br><span class="line">)</span><br></pre></td></tr></table></figure><h3 id="ResolverPlugin-FileAppendPlugin"><a href="#ResolverPlugin-FileAppendPlugin" class="headerlink" title="ResolverPlugin.FileAppendPlugin"></a>ResolverPlugin.FileAppendPlugin</h3><p>This plugin will append a path to the module directory to find a match, which can be useful if you have a module which has an incorrect “main” entry in its package.json/bower.json etc (e.g. “main”: “Gruntfile.js”). You can use this plugin as a special case to load the correct file for this module. Example:<br>举例:</p><figure class="highlight javascript"><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="keyword">new</span> webpack.ResolverPlugin([</span><br><span class="line"> <span class="keyword">new</span> webpack.ResolverPlugin.FileAppendPlugin([<span class="string">'/dist/compiled-moduled.js'</span>])</span><br><span class="line">])</span><br></pre></td></tr></table></figure><h3 id="EnvironmentPlugin"><a href="#EnvironmentPlugin" class="headerlink" title="EnvironmentPlugin"></a>EnvironmentPlugin</h3><p>这个插件允许你通过 process.env 参考环境变量。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.EnvironmentPlugin([<span class="string">'NODE_ENV'</span>])</span><br></pre></td></tr></table></figure><p>代码中使用:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> env = process.env.NODE_ENV</span><br></pre></td></tr></table></figure><h2 id="输出"><a href="#输出" class="headerlink" title="输出"></a>输出</h2><h3 id="BannerPlugin"><a href="#BannerPlugin" class="headerlink" title="BannerPlugin"></a>BannerPlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.BannerPlugin(banner, options)</span><br></pre></td></tr></table></figure><p>在每个生成的块中添加 banner</p><ul><li>banner 字符串,包裹在 comment 中</li><li>options.raw 如果为 true,banner 不会包裹在 comment 中</li><li>options.entryOnly 如果为 true,banner 只会添加在入口文件</li></ul><h2 id="优化"><a href="#优化" class="headerlink" title="优化"></a>优化</h2><h3 id="DedupePlugin"><a href="#DedupePlugin" class="headerlink" title="DedupePlugin"></a>DedupePlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.optimize.DedupePlugin()</span><br></pre></td></tr></table></figure><p>找出相同的依赖并在输出时删除重复依赖。这些文件来源于入口模块,但是可以有效地降低文件大小。<br>这不会改变模块的语义,不要指望能解决多个模块实例的问题,在删除后不会变成一个实例。<br>注意:不要再检测模式下使用。只能用于生产环境构建。</p><h3 id="LimitChunkCountPlugin"><a href="#LimitChunkCountPlugin" class="headerlink" title="LimitChunkCountPlugin"></a>LimitChunkCountPlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.optimize.LimitChunkCountPlugin(options)</span><br></pre></td></tr></table></figure><p>限制模块的数量。</p><ul><li><p>options.maxChunks (number) max number of chunks</p></li><li><p>options.chunkOverhead (number) an additional overhead for each chunk in bytes (default 10000, to reflect request delay)</p></li><li><p>options.entryChunkMultiplicator (number) a multiplicator for entry chunks (default 10, entry chunks are merged 10 times less likely)</p></li></ul><h3 id="MinChunkSizePlugin"><a href="#MinChunkSizePlugin" class="headerlink" title="MinChunkSizePlugin"></a>MinChunkSizePlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.optimize.MinChunkSizePlugin(options)</span><br></pre></td></tr></table></figure><ul><li>options.minChunkSize (number)</li></ul><h3 id="OccurrenceOrderPlugin"><a href="#OccurrenceOrderPlugin" class="headerlink" title="OccurrenceOrderPlugin"></a>OccurrenceOrderPlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.optimize.OccurrenceOrderPlugin(preferEntry)</span><br></pre></td></tr></table></figure><h3 id="UglifyJsPlugin"><a href="#UglifyJsPlugin" class="headerlink" title="UglifyJsPlugin"></a>UglifyJsPlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.optimize.UglifyJsPlugin([options])</span><br></pre></td></tr></table></figure><p>例子:</p><figure class="highlight javascript"><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="keyword">new</span> webpack.optimize.UglifyJsPlugin({</span><br><span class="line"> compress: {</span><br><span class="line"> warnings: <span class="literal">false</span></span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure><p>UglifyJS 配置项:</p><ul><li>compress (boolean|object) 压缩的配置项,默认启用。使用<code>compress: false</code>禁用压缩。</li><li>mangle (boolean|object) 变量名称改编的配置项,默认启用。禁用方式如上。</li><li>mangle.props (boolean|object):</li></ul><h3 id="ngAnnotatePlugin"><a href="#ngAnnotatePlugin" class="headerlink" title="ngAnnotatePlugin"></a>ngAnnotatePlugin</h3><h3 id="CommonsChunkPlugin"><a href="#CommonsChunkPlugin" class="headerlink" title="CommonsChunkPlugin"></a>CommonsChunkPlugin</h3><h3 id="DllPlugin"><a href="#DllPlugin" class="headerlink" title="DllPlugin"></a>DllPlugin</h3><h3 id="AppCachePlugin"><a href="#AppCachePlugin" class="headerlink" title="AppCachePlugin"></a>AppCachePlugin</h3><h3 id="OfflinePlugin"><a href="#OfflinePlugin" class="headerlink" title="OfflinePlugin"></a>OfflinePlugin</h3><h3 id="ImageminPlugin"><a href="#ImageminPlugin" class="headerlink" title="ImageminPlugin"></a>ImageminPlugin</h3><h2 id="模块风格"><a href="#模块风格" class="headerlink" title="模块风格"></a>模块风格</h2><h3 id="LabeledModulesPlugin"><a href="#LabeledModulesPlugin" class="headerlink" title="LabeledModulesPlugin"></a>LabeledModulesPlugin</h3><h3 id="ComponentPlugin"><a href="#ComponentPlugin" class="headerlink" title="ComponentPlugin"></a>ComponentPlugin</h3><h3 id="AngularPlugin"><a href="#AngularPlugin" class="headerlink" title="AngularPlugin"></a>AngularPlugin</h3><h2 id="依赖注入"><a href="#依赖注入" class="headerlink" title="依赖注入"></a>依赖注入</h2><h3 id="DefinePlugin"><a href="#DefinePlugin" class="headerlink" title="DefinePlugin"></a>DefinePlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.DefinePlugin(definitions)</span><br></pre></td></tr></table></figure><p>这个插件允许你在编译的时候创建全局的可配置的常量。对于在开发版本和发布版本中允许不同的行为是非常有用的。例如,你可以用一个全局的常量确定记录是否发生,或许你的执行记录是在开发版本而不是生成版本。<br>例如:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.DefinePlugin({</span><br><span class="line"> PRODUCTION: <span class="built_in">JSON</span>.stringify(<span class="literal">true</span>),</span><br><span class="line"> VERSION: <span class="built_in">JSON</span>.stringify(<span class="string">'5fa3b9'</span>),</span><br><span class="line"> BROWSER_SUPPORTS_HTML5: <span class="literal">true</span>,</span><br><span class="line"> TWO: <span class="string">'1+1'</span>,</span><br><span class="line"> <span class="string">'typeof window'</span>: <span class="built_in">JSON</span>.stringify(<span class="string">'object'</span>)</span><br><span class="line">})</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="string">'Running App version '</span> + VERSION)</span><br><span class="line"><span class="keyword">if</span> (!BROWSER_SUPPORTS_HTML5) <span class="built_in">require</span>(<span class="string">'html5shiv'</span>)</span><br></pre></td></tr></table></figure><ul><li>如果该值是一个字符串,将被用作代码片段</li><li>如果该值不是字符串,那么会被字符串化(包括方法)<br>这些值将会被内联到代码:</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (!PRODUCTION) <span class="built_in">console</span>.log(<span class="string">'Debug info'</span>)</span><br><span class="line"><span class="keyword">if</span> (PRODUCTION) <span class="built_in">console</span>.log(<span class="string">'Production log'</span>)</span><br></pre></td></tr></table></figure><p>通过 webpack 编译后没有缩小的结果:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (!<span class="literal">true</span>) <span class="built_in">console</span>.log(<span class="string">'Debug info'</span>)</span><br><span class="line"><span class="keyword">if</span> (<span class="literal">true</span>) <span class="built_in">console</span>.log(<span class="string">'Production log'</span>)</span><br></pre></td></tr></table></figure><p>最后缩小后的结果:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="string">'Production log'</span>)</span><br></pre></td></tr></table></figure><h3 id="ProvidePlugin"><a href="#ProvidePlugin" class="headerlink" title="ProvidePlugin"></a>ProvidePlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.ProvidePlugin(definitions)</span><br></pre></td></tr></table></figure><p>自动加载模块。当关键字在模块中使用时将会被加载。<br>例子:</p><figure class="highlight javascript"><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="keyword">new</span> webpack.ProvidePlugin({</span><br><span class="line"> $: <span class="string">'jquery'</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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="comment">// in a module</span></span><br><span class="line">$(<span class="string">'#item'</span>) <span class="comment">// <= just works</span></span><br><span class="line"><span class="comment">// $ is automatically set to the exports of module "jquery"</span></span><br></pre></td></tr></table></figure><h3 id="RewirePlugin"><a href="#RewirePlugin" class="headerlink" title="RewirePlugin"></a>RewirePlugin</h3><h3 id="NgRequirePlugin"><a href="#NgRequirePlugin" class="headerlink" title="NgRequirePlugin"></a>NgRequirePlugin</h3><h2 id="本土化"><a href="#本土化" class="headerlink" title="本土化"></a>本土化</h2><h3 id="I18nPlugin"><a href="#I18nPlugin" class="headerlink" title="I18nPlugin"></a>I18nPlugin</h3><h2 id="调试"><a href="#调试" class="headerlink" title="调试"></a>调试</h2><h3 id="SourceMapDevToolPlugin"><a href="#SourceMapDevToolPlugin" class="headerlink" title="SourceMapDevToolPlugin"></a>SourceMapDevToolPlugin</h3><h2 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h2><h3 id="HotModuleReplacementPlugin"><a href="#HotModuleReplacementPlugin" class="headerlink" title="HotModuleReplacementPlugin"></a>HotModuleReplacementPlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.HotModuleReplacementPlugin()</span><br></pre></td></tr></table></figure><p>启用热模块更换。</p><h3 id="ExtendedAPIPlugin"><a href="#ExtendedAPIPlugin" class="headerlink" title="ExtendedAPIPlugin"></a>ExtendedAPIPlugin</h3><h3 id="NoErrorsPlugin"><a href="#NoErrorsPlugin" class="headerlink" title="NoErrorsPlugin"></a>NoErrorsPlugin</h3><h3 id="ProgressPlugin"><a href="#ProgressPlugin" class="headerlink" title="ProgressPlugin"></a>ProgressPlugin</h3><h3 id="WatchIgnorePlugin"><a href="#WatchIgnorePlugin" class="headerlink" title="WatchIgnorePlugin"></a>WatchIgnorePlugin</h3><h3 id="HtmlWebpackPlugin"><a href="#HtmlWebpackPlugin" class="headerlink" title="HtmlWebpackPlugin"></a>HtmlWebpackPlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">HtmlWebpackPlugin = <span class="built_in">require</span>(<span class="string">'html-webpack-plugin'</span>)</span><br><span class="line"><span class="keyword">new</span> HtmlWebpackPlugin({ <span class="attr">title</span>: <span class="string">'Webpack App'</span> })</span><br></pre></td></tr></table></figure><h3 id="S3Plugin"><a href="#S3Plugin" class="headerlink" title="S3Plugin"></a>S3Plugin</h3><h3 id="BellOnBundlerErrorPlugin"><a href="#BellOnBundlerErrorPlugin" class="headerlink" title="BellOnBundlerErrorPlugin"></a>BellOnBundlerErrorPlugin</h3><h3 id="WebpackShellPlugin"><a href="#WebpackShellPlugin" class="headerlink" title="WebpackShellPlugin"></a>WebpackShellPlugin</h3><h3 id="WebpackAngularResourcePlugin"><a href="#WebpackAngularResourcePlugin" class="headerlink" title="WebpackAngularResourcePlugin"></a>WebpackAngularResourcePlugin</h3><h3 id="WebpackBrowserPlugin"><a href="#WebpackBrowserPlugin" class="headerlink" title="WebpackBrowserPlugin"></a>WebpackBrowserPlugin</h3><h3 id="FaviconsWebpackPlugin"><a href="#FaviconsWebpackPlugin" class="headerlink" title="FaviconsWebpackPlugin"></a>FaviconsWebpackPlugin</h3>]]></content>
<summary type="html">
<h2 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h2><h3 id="NormalModuleReplacementPlugin"><a href="#NormalModuleReplacementPlugin" class="headerlink" title="NormalModuleReplacementPlugin"></a>NormalModuleReplacementPlugin</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.NormalModuleReplacementPlugin(resourceRegExp, newResource)</span><br></pre></td></tr></table></figure>
</summary>
<category term="webpack" scheme="https://lingmissing.github.io/tags/webpack/"/>
</entry>
<entry>
<title>es6箭头函数</title>
<link href="https://lingmissing.github.io/2016/09/27/es6%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0/"/>
<id>https://lingmissing.github.io/2016/09/27/es6箭头函数/</id>
<published>2016-09-27T08:58:41.000Z</published>
<updated>2019-01-04T03:37:29.493Z</updated>
<content type="html"><![CDATA[<h2 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h2><h4 id="基础语法"><a href="#基础语法" class="headerlink" title="基础语法"></a>基础语法</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">(param1, param2, …, paramN) => { statements }</span><br><span class="line">(param1, param2, …, paramN) => expression</span><br><span class="line"> <span class="comment">// equivalent to: => { return expression; }</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 如果只有一个参数,圆括号是可选的:</span></span><br><span class="line">(singleParam) => { statements }</span><br><span class="line">singleParam => { statements }</span><br><span class="line"></span><br><span class="line"><span class="comment">// 无参数的函数需要使用圆括号:</span></span><br><span class="line">() => { statements }</span><br></pre></td></tr></table></figure><a id="more"></a><h4 id="高级语法"><a href="#高级语法" class="headerlink" title="高级语法"></a>高级语法</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 返回对象字面量时应当用圆括号将其包起来:</span></span><br><span class="line">params => ({<span class="attr">foo</span>: bar})</span><br><span class="line"></span><br><span class="line"><span class="comment">// 支持重置参数和默认参数:</span></span><br><span class="line">(param1, param2, ...rest) => { statements }</span><br><span class="line">(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }</span><br><span class="line"></span><br><span class="line"><span class="comment">// 支持解构参数</span></span><br><span class="line"><span class="keyword">var</span> f = <span class="function">(<span class="params">[a, b] = [<span class="number">1</span>, <span class="number">2</span>], {x: c} = {x: a + b}</span>) =></span> a + b + c;</span><br><span class="line">f(); <span class="comment">// 6</span></span><br></pre></td></tr></table></figure><h2 id="简短函数书写"><a href="#简短函数书写" class="headerlink" title="简短函数书写"></a>简短函数书写</h2><figure class="highlight javascript"><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="comment">// a is array</span></span><br><span class="line"><span class="keyword">var</span> a2 = a.map(<span class="function"><span class="keyword">function</span>(<span class="params">s</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> s.length</span><br><span class="line">})</span><br><span class="line"><span class="keyword">var</span> a3 = a.map(<span class="function"><span class="params">s</span> =></span> s.length)</span><br></pre></td></tr></table></figure><h2 id="this-词法解析"><a href="#this-词法解析" class="headerlink" title="this 词法解析"></a>this 词法解析</h2><p>在箭头函数出现之前,每个新定义的函数都有其自己的 this 值。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// ES5</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> self = <span class="keyword">this</span> <span class="comment">// 也有人选择使用 `that` 而非 `self`.</span></span><br><span class="line"> <span class="comment">// 只要保证一致就好.</span></span><br><span class="line"> self.age = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"> setInterval(<span class="function"><span class="keyword">function</span> <span class="title">growUp</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="comment">// 回调里面的 `self` 变量就指向了期望的那个对象了</span></span><br><span class="line"> self.age++</span><br><span class="line"> }, <span class="number">1000</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// ES6</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">this</span>.age = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"> setInterval(<span class="function"><span class="params">()</span> =></span> {</span><br><span class="line"> <span class="keyword">this</span>.age++ <span class="comment">// |this| 正确地指向了 person 对象</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 class="keyword">var</span> p = <span class="keyword">new</span> Person()</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h2><h4 id="基础语法"><a href="#基础语法" class="headerlink" title="基础语法"></a>基础语法</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">(param1, param2, …, paramN) =&gt; &#123; statements &#125;</span><br><span class="line">(param1, param2, …, paramN) =&gt; expression</span><br><span class="line"> <span class="comment">// equivalent to: =&gt; &#123; return expression; &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 如果只有一个参数,圆括号是可选的:</span></span><br><span class="line">(singleParam) =&gt; &#123; statements &#125;</span><br><span class="line">singleParam =&gt; &#123; statements &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 无参数的函数需要使用圆括号:</span></span><br><span class="line">() =&gt; &#123; statements &#125;</span><br></pre></td></tr></table></figure>
</summary>
<category term="javascript" scheme="https://lingmissing.github.io/tags/javascript/"/>
<category term="es6" scheme="https://lingmissing.github.io/tags/es6/"/>
</entry>
<entry>
<title>【译】Vue 2.0的变化(一)之基本API变化</title>
<link href="https://lingmissing.github.io/2016/09/27/vue-1/"/>
<id>https://lingmissing.github.io/2016/09/27/vue-1/</id>
<published>2016-09-27T06:23:20.000Z</published>
<updated>2019-01-04T03:42:06.241Z</updated>
<content type="html"><![CDATA[<h3 id="高层级的变化"><a href="#高层级的变化" class="headerlink" title="高层级的变化"></a>高层级的变化</h3><ul><li>模板解析器不再依赖于 DOM(除非你使用真正的 DOM 作为模板),因此只要你使用字符串模板,你将不再受到任何 1.0 版本中的解析限制。但是,如果你依赖在存在的内容中挂载一个元素作为模板(使用<code>el</code>元素),你将依然受到这些限制。</li><li>编译器(将字符串模板转换为渲染方法的部分)和运行时间现在能够被分开。这里有两种不同的构建:<ul><li>独立构建:包括编译并且运行。这种方式和<code>vue 1.0</code>几乎完全一样。</li><li>运行时编译:由于它不包括编译器,在编译步骤时要么预编译模板,要么手动编写渲染功能。npm 包默认导出这个版本,那么你需要有一个编译的过程(使用<code>Browserify</code>或<code>Webpack</code>),从中<code>vueify</code>或<code>vue-loader</code>将可以进行模板预编译。</li></ul></li></ul><a id="more"></a><h3 id="全局配置"><a href="#全局配置" class="headerlink" title="全局配置"></a>全局配置</h3><ul><li><code>Vue.config.silent</code></li><li><code>Vue.config.optionMergeStrategies</code></li><li><code>Vue.config.devtools</code></li><li><strong><code>Vue.config.errorHandler</code></strong>(新 API,全局的挂钩用于在组件渲染和监控的时候处理未捕获的错误)</li><li><code>Vue.config.keyCodes</code>(新 API,为<code>v-on</code>配置自定义的<code>key</code>的别名)</li><li><del><code>Vue.config.debug</code></del>(已丢弃)</li><li><del><code>Vue.config.async</code></del>(已丢弃)</li><li><del><code>Vue.config.delimiters</code></del>(已丢弃)</li><li><del><code>Vue.config.unsafeDelimiters</code></del>(已丢弃,使用<code>v-html</code>)</li></ul><h3 id="全局-API"><a href="#全局-API" class="headerlink" title="全局 API"></a>全局 API</h3><ul><li><code>Vue.extend</code></li><li><code>Vue.nextTick</code></li><li><code>Vue.set</code></li><li><code>Vue.delete</code></li><li><code>Vue.directive</code></li><li><code>Vue.component</code></li><li><code>Vue.use</code></li><li><code>Vue.mixin</code></li><li><strong><code>Vue.compile</code></strong>(新 API,只能用于独立版本构建)</li><li><code>Vue.transition</code><ul><li><del><code>stagger</code></del>(已丢弃,在<code>el</code>上设置</li></ul></li><li><code>Vue.filter</code></li><li><del><code>Vue.elementDirective</code></del>(已丢弃,使用组件)</li><li><del><code>Vue.partial</code></del> (已丢弃,使用功能组件)</li></ul><h3 id="选项"><a href="#选项" class="headerlink" title="选项"></a>选项</h3><h4 id="data"><a href="#data" class="headerlink" title="data"></a>data</h4><ul><li><code>data</code></li><li><code>props</code><ul><li><code>prop</code></li><li><code>default</code></li><li><del><code>coerce</code></del>(已丢弃,如果你需要转换<code>prop</code>,请使用<code>compute</code>属性)</li><li><del><code>prop binding modes</code></del>(已丢弃,<code>v-model</code>在组件上可以工作</li></ul></li><li><strong><code>propsData</code></strong>(新 API)只能用于实例</li><li><code>computed</code></li><li><code>methods</code></li><li><code>watch</code></li></ul><h4 id="DOM"><a href="#DOM" class="headerlink" title="DOM"></a>DOM</h4><ul><li><code>el</code></li><li><code>template</code></li><li><strong><code>render</code></strong>(新 API)</li><li><del><code>replace</code></del>(已丢弃,组件现在必须有一个根元素)</li></ul><h4 id="生命周期钩子"><a href="#生命周期钩子" class="headerlink" title="生命周期钩子"></a>生命周期钩子</h4><ul><li><del><code>init</code></del>(已丢弃,请使用<code>beforeCreate</code>)</li><li><code>created</code></li><li><code>beforeDestroy</code></li><li><code>destroyed</code></li><li><strong><code>beforeMount</code></strong>(新 API)</li><li><strong><code>mounted</code></strong>(新 API)</li><li><strong><code>beforeUpdate</code></strong>(新 API)</li><li><strong><code>updated</code></strong>(新 API)</li><li><strong><code>activated</code></strong>(新 API,用于<code>keep-alive</code>)</li><li><strong><code>deactivated</code></strong>(新 API 用于<code>keep-alive</code>)</li><li><del><code>ready</code></del>(已丢弃,使用<code>mounted</code>)</li><li><del><code>activate</code></del>(已丢弃,迁移到<code>vue-router</code>)</li><li><del><code>beforeCompile</code></del>(已丢弃,使用<code>created</code>)</li><li><del><code>compiled</code></del>(已丢弃,使用<code>mounted</code>)</li><li><del><code>attached</code></del>(已丢弃)</li><li><del><code>detached</code></del>(已丢弃,同上)</li></ul><h4 id="Assets"><a href="#Assets" class="headerlink" title="Assets"></a>Assets</h4><ul><li><code>directives</code></li><li><code>components</code></li><li><code>transitions</code></li><li><code>filters</code></li><li><del><code>partials</code></del>(已丢弃)</li><li><del><code>elementDirectives</code></del>(已丢弃)</li></ul><h4 id="杂项"><a href="#杂项" class="headerlink" title="杂项"></a>杂项</h4><ul><li><code>parent</code></li><li><code>mixins</code></li><li><code>name</code></li><li><code>extends</code></li><li><strong><code>delimiters</code></strong>(新 API,替代原版的全局配置选项,只在独立构建中可用)</li><li><strong><code>functional</code></strong>(新 API)</li><li><del><code>events</code></del>(已丢弃)</li></ul><h3 id="实例方法"><a href="#实例方法" class="headerlink" title="实例方法"></a>实例方法</h3><h4 id="data-1"><a href="#data-1" class="headerlink" title="data"></a>data</h4><ul><li><code>vm.$watch</code></li><li><del><code>vm.$get</code></del>(已丢弃,直接检索值)</li><li><del><code>vm.$set</code></del>(已丢弃,使用<code>Vue.set</code>)</li><li><del><code>vm.$delete</code></del>(已丢弃,使用<code>Vue.delete</code>)</li><li><del><code>vm.$eval</code></del>(已丢弃,没有真正的使用)</li><li><del><code>vm.$interpolate</code></del>(已丢弃,同上)</li><li><del><code>vm.$log</code></del>(已丢弃,使用<code>devtools</code>)</li></ul><h4 id="events"><a href="#events" class="headerlink" title="events"></a>events</h4><ul><li><code>vm.$on</code></li><li><code>vm.$once</code></li><li><code>vm.$off</code></li><li><code>vm.$emit</code></li><li><del><code>vm.$dispatch</code></del>(已丢弃,使用全局的事件或使用<code>vuex</code>,见下面)</li><li><del><code>vm.$broadcast</code></del>(已丢弃,同上)</li></ul><h4 id="DOM-1"><a href="#DOM-1" class="headerlink" title="DOM"></a>DOM</h4><ul><li><code>vm.$nextTick</code></li><li><del><code>vm.$appendTo</code></del>(已丢弃,在<code>vm.$el</code>上使用本地 API)</li><li><del><code>vm.$before</code></del>(已丢弃)</li><li><del><code>vm.$after</code></del>(已丢弃)</li><li><del><code>vm.$remove</code></del>(已丢弃)</li></ul><h4 id="生命周期"><a href="#生命周期" class="headerlink" title="生命周期"></a>生命周期</h4><ul><li><code>vm.$mount</code></li><li><code>vm.$destroy</code></li></ul><h3 id="指令"><a href="#指令" class="headerlink" title="指令"></a>指令</h3><ul><li><code>v-text</code></li><li><code>v-html</code>(注意三次括号被丢弃)</li><li><code>v-if</code></li><li><code>v-show</code></li><li><code>v-else</code></li><li><code>v-for</code><ul><li><strong><code>key</code></strong> (替代 <code>track-by</code>)</li><li><code>object v-for</code></li><li><code>range v-for</code></li><li>参数顺序更新:数组中使用<code>(value, index) in arr</code>,对象中使用<code>(value, key, index) in obj</code></li><li><del><code>$index</code></del>和<del><code>$key</code></del>被丢弃</li></ul></li><li><code>v-on</code><ul><li><code>modifiers</code></li><li>on child component</li><li>自定义键码,目前版本<code>Vue.config.keyCodes</code>代替原来的<code>Vue.directive('on').keyCodes</code></li></ul></li><li><code>v-bind</code><ul><li>作为<code>prop</code></li><li><code>xlink</code></li><li>绑定对象</li></ul></li><li><code>v-bind:style</code><ul><li><code>prefix sniffing</code></li></ul></li><li><code>v-bind:class</code></li><li><code>v-model</code><ul><li><code>lazy</code> (as modifier)</li><li><code>number</code> (as modifier)</li><li>`ignoring composition events</li><li><del><code>debounce</code></del>(已丢弃,使用<code>v-on:input</code>)</li></ul></li><li><code>v-cloak</code></li><li><code>v-pre</code></li><li><strong><code>v-once</code></strong>(新 API)</li><li><del><code>v-ref</code></del>(已丢弃,现在只是一个特殊的属性<code>ref</code>)</li><li><del><code>v-el</code></del>(和<code>ref</code>合并)</li></ul><h3 id="特殊组件"><a href="#特殊组件" class="headerlink" title="特殊组件"></a>特殊组件</h3><ul><li><code><component></code><ul><li><code>:is</code></li><li><code>async组件</code></li><li><code>inline-template</code></li></ul></li><li><code><transition></code></li><li><code><transition-group></code></li><li><code><keep-alive></code></li><li><code><slot></code></li><li><del><code>partial</code></del>(已丢弃)</li></ul><h3 id="特殊属性"><a href="#特殊属性" class="headerlink" title="特殊属性"></a>特殊属性</h3><ul><li><code>key</code></li><li><code>ref</code></li><li><code>slot</code></li></ul><h3 id="服务器端渲染"><a href="#服务器端渲染" class="headerlink" title="服务器端渲染"></a>服务器端渲染</h3><ul><li><code>renderToString</code></li><li><code>renderToStream</code></li><li><code>client-side hydration</code></li></ul><blockquote><p>翻译自<a href="https://github.com/vuejs/vue/issues/2873" target="_blank" rel="noopener">2.0 Changes</a></p></blockquote>]]></content>
<summary type="html">
<h3 id="高层级的变化"><a href="#高层级的变化" class="headerlink" title="高层级的变化"></a>高层级的变化</h3><ul>
<li>模板解析器不再依赖于 DOM(除非你使用真正的 DOM 作为模板),因此只要你使用字符串模板,你将不再受到任何 1.0 版本中的解析限制。但是,如果你依赖在存在的内容中挂载一个元素作为模板(使用<code>el</code>元素),你将依然受到这些限制。</li>
<li>编译器(将字符串模板转换为渲染方法的部分)和运行时间现在能够被分开。这里有两种不同的构建:<ul>
<li>独立构建:包括编译并且运行。这种方式和<code>vue 1.0</code>几乎完全一样。</li>
<li>运行时编译:由于它不包括编译器,在编译步骤时要么预编译模板,要么手动编写渲染功能。npm 包默认导出这个版本,那么你需要有一个编译的过程(使用<code>Browserify</code>或<code>Webpack</code>),从中<code>vueify</code>或<code>vue-loader</code>将可以进行模板预编译。</li>
</ul>
</li>
</ul>
</summary>
<category term="vue" scheme="https://lingmissing.github.io/tags/vue/"/>
</entry>
<entry>
<title>fetch用法说明</title>
<link href="https://lingmissing.github.io/2016/09/07/fech/"/>
<id>https://lingmissing.github.io/2016/09/07/fech/</id>
<published>2016-09-07T03:08:38.000Z</published>
<updated>2019-01-04T03:37:36.882Z</updated>
<content type="html"><![CDATA[<p>由于 <code>Fetch</code>API 是基于 <code>Promise</code> 设计,有必要先学习一下 <code>Promise</code>,推荐阅读<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise" target="_blank" rel="noopener"> MDN Promise 教程 </a><br>本文章内容推荐阅读<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalFetch/fetch" target="_blank" rel="noopener"> MDN Fetch 教程</a></p><a id="more"></a><h2 id="语法说明"><a href="#语法说明" class="headerlink" title="语法说明"></a>语法说明</h2><figure class="highlight javascript"><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">fetch(url, options).then(<span class="function"><span class="keyword">function</span>(<span class="params">response</span>) </span>{</span><br><span class="line"> <span class="comment">// handle HTTP response</span></span><br><span class="line">}, <span class="function"><span class="keyword">function</span>(<span class="params">error</span>) </span>{</span><br><span class="line"> <span class="comment">// handle network error</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure><p>具体参数案例:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//兼容包</span></span><br><span class="line"><span class="built_in">require</span>(<span class="string">'babel-polyfill'</span>)</span><br><span class="line"><span class="built_in">require</span>(<span class="string">'es6-promise'</span>).polyfill()</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="string">'whatwg-fetch'</span></span><br><span class="line"></span><br><span class="line">fetch(url, {</span><br><span class="line"> method: <span class="string">"POST"</span>,</span><br><span class="line"> body: <span class="built_in">JSON</span>.stringify(data),</span><br><span class="line"> headers: {</span><br><span class="line"> <span class="string">"Content-Type"</span>: <span class="string">"application/json"</span></span><br><span class="line"> },</span><br><span class="line"> credentials: <span class="string">"same-origin"</span></span><br><span class="line">}).then(<span class="function"><span class="keyword">function</span>(<span class="params">response</span>) </span>{</span><br><span class="line"> response.status <span class="comment">//=> number 100–599</span></span><br><span class="line"> response.statusText <span class="comment">//=> String</span></span><br><span class="line"> response.headers <span class="comment">//=> Headers</span></span><br><span class="line"> response.url <span class="comment">//=> String</span></span><br><span class="line"></span><br><span class="line"> response.text().then(<span class="function"><span class="keyword">function</span>(<span class="params">responseText</span>) </span>{ ... })</span><br><span class="line">}, <span class="function"><span class="keyword">function</span>(<span class="params">error</span>) </span>{</span><br><span class="line"> error.message <span class="comment">//=> String</span></span><br><span class="line">})</span><br></pre></td></tr></table></figure><h4 id="url"><a href="#url" class="headerlink" title="url"></a>url</h4><p>定义要获取的资源。这可能是:</p><ul><li>一个 <code>USVString</code> 字符串,包含要获取资源的 <code>URL</code>。</li><li>一个 <code>Request</code> 对象。</li></ul><h4 id="options(可选)"><a href="#options(可选)" class="headerlink" title="options(可选)"></a>options(可选)</h4><p>一个配置项对象,包括所有对请求的设置。可选的参数有:</p><ul><li><code>method</code>: 请求使用的方法,如 <code>GET</code>、<code>POST</code>。</li><li><code>headers</code>: 请求的头信息,形式为 <code>Headers</code> 对象或 <code>ByteString</code>。</li><li><code>body</code>: 请求的 <code>body</code> 信息:可能是一个 <code>Blob</code>、<code>BufferSource</code>、<code>FormData</code>、<code>URLSearchParams</code> 或者 <code>USVString</code> 对象。注意 <code>GET</code> 或 <code>HEAD</code> 方法的请求不能包含 <code>body</code> 信息。</li><li><code>mode</code>: 请求的模式,如 <code>cors</code>、 <code>no-cors</code> 或者 <code>same-origin</code>。</li><li><code>credentials</code>: 请求的 <code>credentials</code>,如 <code>omit</code>、<code>same-origin</code> 或者 <code>include</code>。</li><li><code>cache</code>: 请求的 <code>cache</code> 模式: <code>default</code>, <code>no-store</code>, <code>reload</code>, <code>no-cache</code>, <code>force-cache</code>, 或者 <code>only-if-cached</code>。</li></ul><h4 id="response"><a href="#response" class="headerlink" title="response"></a>response</h4><p>一个 <code>Promise</code>,<code>resolve</code> 时回传 <code>Response</code> 对象:</p><ul><li>属性:<ul><li><code>status (number)</code> - HTTP 请求结果参数,在 100–599 范围</li><li><code>statusText (String)</code> - 服务器返回的状态报告</li><li><code>ok (boolean)</code> - 如果返回 200 表示请求成功则为 true</li><li><code>headers (Headers)</code> - 返回头部信息,下面详细介绍</li><li><code>url (String)</code> - 请求的地址</li></ul></li><li>方法:<ul><li><code>text()</code> - 以<code>string</code>的形式生成请求 text</li><li><code>json()</code> - 生成<code>JSON.parse(responseText)</code>的结果</li><li><code>blob()</code> - 生成一个<code>Blob</code></li><li><code>arrayBuffer()</code> - 生成一个<code>ArrayBuffer</code></li><li><code>formData()</code> - 生成格式化的数据,可用于其他的请求</li></ul></li><li>其他方法:<ul><li><code>clone()</code></li><li><code>Response.error()</code></li><li><code>Response.redirect()</code></li></ul></li></ul><h4 id="response-headers"><a href="#response-headers" class="headerlink" title="response.headers"></a>response.headers</h4><ul><li><code>has(name) (boolean)</code> - 判断是否存在该信息头</li><li><code>get(name) (String)</code> - 获取信息头的数据</li><li><code>getAll(name) (Array)</code> - 获取所有头部数据</li><li><code>set(name, value)</code> - 设置信息头的参数</li><li><code>append(name, value)</code> - 添加 header 的内容</li><li><code>delete(name)</code> - 删除 header 的信息</li><li><code>forEach(function(value, name){ ... }, [thisContext])</code> - 循环读取 header 的信息</li></ul><h2 id="使用案例"><a href="#使用案例" class="headerlink" title="使用案例"></a>使用案例</h2><h4 id="GET-请求"><a href="#GET-请求" class="headerlink" title="GET 请求"></a>GET 请求</h4><ul><li><p>HTML</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">fetch(<span class="string">'/users.html'</span>)</span><br><span class="line"> .then(<span class="function"><span class="keyword">function</span>(<span class="params">response</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> response.text()</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">body</span>) </span>{</span><br><span class="line"> <span class="built_in">document</span>.body.innerHTML = body</span><br><span class="line"> })</span><br></pre></td></tr></table></figure></li><li><p>IMAGE</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myImage = <span class="built_in">document</span>.querySelector(<span class="string">'img'</span>);</span><br><span class="line"></span><br><span class="line">fetch(<span class="string">'flowers.jpg'</span>)</span><br><span class="line"> .then(<span class="function"><span class="keyword">function</span>(<span class="params">response</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> response.blob();</span><br><span class="line"> })</span><br><span class="line"> .then(<span class="function"><span class="keyword">function</span>(<span class="params">myBlob</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> objectURL = URL.createObjectURL(myBlob);</span><br><span class="line"> myImage.src = objectURL;</span><br><span class="line"> });</span><br></pre></td></tr></table></figure></li><li><p>JSON</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">fetch(url)</span><br><span class="line"> .then(<span class="function"><span class="keyword">function</span>(<span class="params">response</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> response.json();</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(data);</span><br><span class="line"> }).catch(<span class="function"><span class="keyword">function</span>(<span class="params">e</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"Oops, error"</span>);</span><br><span class="line"> });</span><br></pre></td></tr></table></figure><p>使用 ES6 的 箭头函数 后:</p><figure class="highlight javascript"><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">fetch(url)</span><br><span class="line"> .then(<span class="function"><span class="params">response</span> =></span> response.json())</span><br><span class="line"> .then(<span class="function"><span class="params">data</span> =></span> <span class="built_in">console</span>.log(data))</span><br><span class="line"> .catch(<span class="function"><span class="params">e</span> =></span> <span class="built_in">console</span>.log(<span class="string">"Oops, error"</span>, e))</span><br></pre></td></tr></table></figure><p>response 的数据</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">fetch(<span class="string">'/users.json'</span>).then(<span class="function"><span class="keyword">function</span>(<span class="params">response</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(response.headers.get(<span class="string">'Content-Type'</span>))</span><br><span class="line"> <span class="built_in">console</span>.log(response.headers.get(<span class="string">'Date'</span>))</span><br><span class="line"> <span class="built_in">console</span>.log(response.status)</span><br><span class="line"> <span class="built_in">console</span>.log(response.statusText)</span><br><span class="line">})</span><br></pre></td></tr></table></figure></li></ul><h4 id="POST-请求"><a href="#POST-请求" class="headerlink" title="POST 请求"></a>POST 请求</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">fetch(<span class="string">'/users'</span>, {</span><br><span class="line"> method: <span class="string">'POST'</span>,</span><br><span class="line"> headers: {</span><br><span class="line"> <span class="string">'Accept'</span>: <span class="string">'application/json'</span>,</span><br><span class="line"> <span class="string">'Content-Type'</span>: <span class="string">'application/json'</span></span><br><span class="line"> },</span><br><span class="line"> body: <span class="built_in">JSON</span>.stringify({</span><br><span class="line"> name: <span class="string">'Hubot'</span>,</span><br><span class="line"> login: <span class="string">'hubot'</span>,</span><br><span class="line"> })</span><br><span class="line">})</span><br></pre></td></tr></table></figure><p>检查请求状态</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">checkStatus</span>(<span class="params">response</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (response.status >= <span class="number">200</span> && response.status < <span class="number">300</span>) {</span><br><span class="line"> <span class="keyword">return</span> response</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">var</span> error = <span class="keyword">new</span> <span class="built_in">Error</span>(response.statusText)</span><br><span class="line"> error.response = response</span><br><span class="line"> <span class="keyword">throw</span> error</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">parseJSON</span>(<span class="params">response</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> response.json()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">fetch(<span class="string">'/users'</span>)</span><br><span class="line"> .then(checkStatus)</span><br><span class="line"> .then(parseJSON)</span><br><span class="line"> .then(<span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'request succeeded with JSON response'</span>, data)</span><br><span class="line"> }).catch(<span class="function"><span class="keyword">function</span>(<span class="params">error</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'request failed'</span>, error)</span><br><span class="line"> })</span><br></pre></td></tr></table></figure><h2 id="采用-promise-形式"><a href="#采用-promise-形式" class="headerlink" title="采用 promise 形式"></a>采用 promise 形式</h2><p>Promise 对象是一个返回值的代理,这个返回值在 promise 对象创建时未必已知。它允许你为异步操作的成功或失败指定处理方法。 这使得异步方法可以像同步方法那样返回值:异步方法会返回一个包含了原返回值的 promise 对象来替代原返回值。</p><p>Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是<code>resolve</code>方法和<code>reject</code>方法。如果异步操作成功,则用<code>resolve</code>方法将<code>Promise</code>对象的状态变为“成功”(即从 pending 变为 resolved);如果异步操作失败,则用 reject 方法将状态变为“失败”(即从 pending 变为 rejected)。</p><p>promise 实例生成以后,可以用 then 方法分别指定 resolve 方法和 reject 方法的回调函数。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//创建一个promise对象</span></span><br><span class="line"><span class="keyword">var</span> promise = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve, reject</span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="comment">/* 异步操作成功 */</span>){</span><br><span class="line"> resolve(value);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> reject(error);</span><br><span class="line"> }</span><br><span class="line">});</span><br><span class="line"><span class="comment">//then方法可以接受两个回调函数作为参数。</span></span><br><span class="line"><span class="comment">//第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Reject时调用。</span></span><br><span class="line"><span class="comment">//其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。</span></span><br><span class="line">promise.then(<span class="function"><span class="keyword">function</span>(<span class="params">value</span>) </span>{</span><br><span class="line"> <span class="comment">// success</span></span><br><span class="line">}, <span class="function"><span class="keyword">function</span>(<span class="params">value</span>) </span>{</span><br><span class="line"> <span class="comment">// failure</span></span><br><span class="line">});</span><br></pre></td></tr></table></figure><p>那么结合 promise 后 fetch 的用法:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//Fetch.js</span></span><br><span class="line"><span class="keyword">export</span> <span class="function"><span class="keyword">function</span> <span class="title">Fetch</span>(<span class="params">url, options</span>) </span>{</span><br><span class="line"> options.body = <span class="built_in">JSON</span>.stringify(options.body)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> defer = <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =></span> {</span><br><span class="line"> fetch(url, options)</span><br><span class="line"> .then(<span class="function"><span class="params">response</span> =></span> {</span><br><span class="line"> <span class="keyword">return</span> response.json()</span><br><span class="line"> })</span><br><span class="line"> .then(<span class="function"><span class="params">data</span> =></span> {</span><br><span class="line"> <span class="keyword">if</span> (data.code === <span class="number">0</span>) {</span><br><span class="line"> resolve(data) <span class="comment">//返回成功数据</span></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"><span class="keyword">if</span> (data.code === <span class="number">401</span>) {</span><br><span class="line"> <span class="comment">//失败后的一种状态</span></span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">//失败的另一种状态</span></span><br><span class="line">}</span><br><span class="line"> reject(data) <span class="comment">//返回失败数据</span></span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> .catch(<span class="function"><span class="params">error</span> =></span> {</span><br><span class="line"> <span class="comment">//捕获异常</span></span><br><span class="line"> <span class="built_in">console</span>.log(error.msg)</span><br><span class="line"> reject()</span><br><span class="line"> })</span><br><span class="line"> })</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> defer</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>调用 Fech 方法:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { Fetch } <span class="keyword">from</span> <span class="string">'./Fetch'</span></span><br><span class="line"></span><br><span class="line">Fetch(getAPI(<span class="string">'search'</span>), {</span><br><span class="line"> method: <span class="string">'POST'</span>,</span><br><span class="line"> options</span><br><span class="line">})</span><br><span class="line">.then(<span class="function"><span class="params">data</span> =></span> {</span><br><span class="line"> <span class="built_in">console</span>.log(data)</span><br><span class="line">})</span><br></pre></td></tr></table></figure><h2 id="支持状况及解决方案"><a href="#支持状况及解决方案" class="headerlink" title="支持状况及解决方案"></a>支持状况及解决方案</h2><p>原生支持率并不高,幸运的是,引入下面这些 <code>polyfill</code> 后可以完美支持 IE8+ :</p><ul><li>由于 IE8 是 ES3,需要引入 ES5 的 <code>polyfill</code>: <code>es5-shim</code>, <code>es5-sham</code></li><li>引入 <code>Promise</code> 的 <code>polyfill</code>: <code>es6-promise</code></li><li>引入 <code>fetch</code> 探测库:<code>fetch-detector</code></li><li>引入 <code>fetch</code> 的 <code>polyfill</code>: <code>fetch-ie8</code></li><li>可选:如果你还使用了 <code>jsonp</code>,引入 <code>fetch-jsonp</code></li><li>可选:开启 <code>Babel</code> 的 <code>runtime</code> 模式,现在就使用 <code>async</code>/<code>await</code></li></ul><p>翻译自 <a href="https://github.github.io/fetch/" target="_blank" rel="noopener">Fetch</a></p>]]></content>
<summary type="html">
<p>由于 <code>Fetch</code>API 是基于 <code>Promise</code> 设计,有必要先学习一下 <code>Promise</code>,推荐阅读<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise" target="_blank" rel="noopener"> MDN Promise 教程 </a><br>本文章内容推荐阅读<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalFetch/fetch" target="_blank" rel="noopener"> MDN Fetch 教程</a></p>
</summary>
<category term="javascript" scheme="https://lingmissing.github.io/tags/javascript/"/>
<category term="es6" scheme="https://lingmissing.github.io/tags/es6/"/>
</entry>
<entry>
<title>数组的操作</title>
<link href="https://lingmissing.github.io/2016/09/01/%E6%95%B0%E7%BB%84%E7%9A%84%E6%93%8D%E4%BD%9C/"/>
<id>https://lingmissing.github.io/2016/09/01/数组的操作/</id>
<published>2016-09-01T09:05:00.000Z</published>
<updated>2019-01-04T03:42:27.607Z</updated>
<content type="html"><![CDATA[<h3 id="数组的创建"><a href="#数组的创建" class="headerlink" title="数组的创建"></a>数组的创建</h3><figure class="highlight javascript"><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="keyword">var</span> arrayObj = []; <span class="comment">//普通数组创建</span></span><br><span class="line"><span class="keyword">var</span> arrayObj = <span class="keyword">new</span> <span class="built_in">Array</span>(); <span class="comment">//创建一个数组</span></span><br><span class="line"><span class="keyword">var</span> arrayObj = <span class="keyword">new</span> <span class="built_in">Array</span>([size]); <span class="comment">//创建一个数组并指定长度,注意不是上限,是长度</span></span><br><span class="line"><span class="keyword">var</span> arrayObj = <span class="keyword">new</span> <span class="built_in">Array</span>([element0[, element1[, ...[, elementN]]]]); <span class="comment">//创建一个数组并赋值</span></span><br></pre></td></tr></table></figure><a id="more"></a><h3 id="数组的添加"><a href="#数组的添加" class="headerlink" title="数组的添加"></a>数组的添加</h3><ul><li><code>push()</code>方法将一个或多个新元素添加到数组结尾,并返回数组新长度,数组不变</li></ul><figure class="highlight javascript"><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="keyword">var</span> arr = [<span class="number">1</span>]</span><br><span class="line"><span class="built_in">console</span>.log(arr.push(<span class="number">2</span>)) <span class="comment">//2</span></span><br><span class="line"><span class="built_in">console</span>.log(arr) <span class="comment">//[1, 2]</span></span><br></pre></td></tr></table></figure><ul><li><code>unshift()</code>方法将一个或多个新元素添加到数组头部,并返回数组新长度,数组不变</li></ul><figure class="highlight javascript"><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="keyword">var</span> arr = [<span class="number">1</span>]</span><br><span class="line"><span class="built_in">console</span>.log(arr.unshift(<span class="number">2</span>)) <span class="comment">//2</span></span><br><span class="line"><span class="built_in">console</span>.log(arr) <span class="comment">//[2, 1]</span></span><br></pre></td></tr></table></figure><ul><li><code>splice()</code>将一个或多个新元素插入到数组的指定位置,插入位置的元素自动后移,返回””。</li></ul><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line">arr.splice(<span class="number">2</span>, <span class="number">0</span>, <span class="string">'insert'</span>) <span class="comment">//表示在第二个位置插入,删除0个元素,返回[]</span></span><br><span class="line"><span class="built_in">console</span>.log(arr) <span class="comment">//[1, 2, "insert", 3, 4, 5]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> newArr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line">newArr.splice(<span class="number">2</span>, <span class="number">1</span>, <span class="string">'insert'</span>) <span class="comment">//表示删除第二个位置后的1个元素并插入</span></span><br><span class="line"><span class="built_in">console</span>.log(newArr) <span class="comment">//[1, 2, "insert", 4, 5]</span></span><br></pre></td></tr></table></figure><h3 id="数组的删除"><a href="#数组的删除" class="headerlink" title="数组的删除"></a>数组的删除</h3><ul><li><code>pop()</code>移除最后一个元素并返回该元素值</li><li><code>shift()</code>移除最前一个元素并返回该元素值,数组中元素自动前移</li><li><code>splice(deletePos,deleteCount)</code>删除从指定位置 deletePos 开始的指定数量 deleteCount 的元素,数组形式返回所移除的元素</li></ul><h3 id="数组的截取和合并"><a href="#数组的截取和合并" class="headerlink" title="数组的截取和合并"></a>数组的截取和合并</h3><ul><li><code>concat()</code>将多个数组(也可以是字符串,或者是数组和字符串的混合)连接为一个数组,返回连接好的新的数组</li></ul><figure class="highlight javascript"><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="keyword">var</span> a = [<span class="number">1</span>]</span><br><span class="line"><span class="keyword">var</span> b = [<span class="number">2</span>]</span><br><span class="line">a.concat(b) <span class="comment">//[1,2] 既不是a也不是b</span></span><br></pre></td></tr></table></figure><ul><li><code>slice(start, [end])</code>以数组的形式返回数组的一部分,注意不包括 end 对应的元素,如果省略 end 将复制 start 之后的所有元素</li></ul><h3 id="数组的拷贝"><a href="#数组的拷贝" class="headerlink" title="数组的拷贝"></a>数组的拷贝</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">arrayObj.slice(<span class="number">0</span>) <span class="comment">//返回数组的拷贝数组,注意是一个新的数组,不是指向</span></span><br><span class="line">arrayObj.concat() <span class="comment">//返回数组的拷贝数组,注意是一个新的数组,不是指向</span></span><br></pre></td></tr></table></figure><h3 id="数组元素的排序"><a href="#数组元素的排序" class="headerlink" title="数组元素的排序"></a>数组元素的排序</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">arrayObj.reverse() <span class="comment">//反转元素(最前的排到最后、最后的排到最前),返回数组地址</span></span><br><span class="line">arrayObj.sort() <span class="comment">//对数组元素排序,返回数组地址</span></span><br></pre></td></tr></table></figure><h3 id="数组元素的字符串化"><a href="#数组元素的字符串化" class="headerlink" title="数组元素的字符串化"></a>数组元素的字符串化</h3><p><code>join()</code>方法是一个非常实用的方法,它把当前 Array 的每个元素都用指定的字符串连接起来,然后返回连接后的字符串:</p><figure class="highlight javascript"><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">arrayObj.join(separator) <span class="comment">//返回字符串,这个字符串将数组的每一个元素值连接在一起,中间用 separator 隔开。</span></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="string">'A'</span>, <span class="string">'B'</span>, <span class="string">'C'</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line">arr.join(<span class="string">'-'</span>) <span class="comment">// 'A-B-C-1-2-3'</span></span><br></pre></td></tr></table></figure><h3 id="数组的查找"><a href="#数组的查找" class="headerlink" title="数组的查找"></a>数组的查找</h3><ul><li>indexOf()</li><li>lastIndexOf()</li><li><p><code>find()</code>方法,用于找出第一个符合条件的数组成员</p><p>find 方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。</p><figure class="highlight javascript"><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="number">1</span>, <span class="number">5</span>, <span class="number">10</span>, <span class="number">15</span>].find(<span class="function"><span class="keyword">function</span>(<span class="params">value, index, arr</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> value > <span class="number">9</span></span><br><span class="line">}) <span class="comment">// 10</span></span><br></pre></td></tr></table></figure></li><li><p><code>findIndex()</code>返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。</p><figure class="highlight javascript"><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="number">1</span>, <span class="number">5</span>, <span class="number">10</span>, <span class="number">15</span>].findIndex(<span class="function"><span class="keyword">function</span>(<span class="params">value, index, arr</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> value > <span class="number">9</span></span><br><span class="line">}) <span class="comment">// 2</span></span><br></pre></td></tr></table></figure></li></ul><h3 id="判断是否为数组"><a href="#判断是否为数组" class="headerlink" title="判断是否为数组"></a>判断是否为数组</h3><ul><li><p><code>typeof</code> 操作符</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr = <span class="keyword">new</span> <span class="built_in">Array</span>(<span class="string">'1'</span>, <span class="string">'2'</span>, <span class="string">'3'</span>, <span class="string">'4'</span>, <span class="string">'5'</span>)</span><br><span class="line">alert(<span class="keyword">typeof</span> arr) <span class="comment">// Object</span></span><br></pre></td></tr></table></figure></li><li><p><code>instanceof()</code>运算符会返回一个 Boolean 值,指出对象是否是特定类的一个实例。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arrayStr = <span class="keyword">new</span> <span class="built_in">Array</span>(<span class="string">'1'</span>, <span class="string">'2'</span>, <span class="string">'3'</span>, <span class="string">'4'</span>, <span class="string">'5'</span>)</span><br><span class="line">alert(arrayStr <span class="keyword">instanceof</span> <span class="built_in">Array</span>) <span class="comment">//true</span></span><br></pre></td></tr></table></figure></li><li><p><code>Array.isArray()</code>用来判断某个值是否为数组。如果是,则返回 true,否则返回 false。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 下面的函数调用都返回 true</span></span><br><span class="line"><span class="built_in">Array</span>.isArray([])</span><br><span class="line"><span class="built_in">Array</span>.isArray([<span class="number">1</span>])</span><br><span class="line"><span class="built_in">Array</span>.isArray(<span class="keyword">new</span> <span class="built_in">Array</span>())</span><br><span class="line"><span class="comment">// 鲜为人知的事实:其实 Array.prototype 也是一个数组。</span></span><br><span class="line"><span class="built_in">Array</span>.isArray(<span class="built_in">Array</span>.prototype)</span><br></pre></td></tr></table></figure></li></ul><h3 id="数组迭代"><a href="#数组迭代" class="headerlink" title="数组迭代"></a>数组迭代</h3><ul><li><p><code>filter()</code>使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组。</p><figure class="highlight javascript"><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="function"><span class="keyword">function</span> <span class="title">isBigEnough</span>(<span class="params">element</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> element >= <span class="number">10</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> filtered = [<span class="number">12</span>, <span class="number">5</span>, <span class="number">8</span>, <span class="number">130</span>, <span class="number">44</span>].filter(isBigEnough)</span><br><span class="line"><span class="comment">// filtered is [12, 130, 44]</span></span><br></pre></td></tr></table></figure></li><li><p><code>forEach()</code>让数组的每一项都执行一次给定的函数。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">logArrayElements</span>(<span class="params">element, index, array</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'a['</span> + index + <span class="string">'] = '</span> + element)</span><br><span class="line">}</span><br><span class="line">;[<span class="number">2</span>, <span class="number">5</span>, <span class="number">9</span>].forEach(logArrayElements)</span><br><span class="line"><span class="comment">// logs:</span></span><br><span class="line"><span class="comment">// a[0] = 2</span></span><br><span class="line"><span class="comment">// a[1] = 5</span></span><br><span class="line"><span class="comment">// a[2] = 9</span></span><br></pre></td></tr></table></figure></li><li><p><code>every()</code>测试数组的所有元素是否都通过了指定函数的测试。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//检测数组中的所有元素是否都大于 10</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">isBigEnough</span>(<span class="params">element, index, array</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> element >= <span class="number">10</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> passed = [<span class="number">12</span>, <span class="number">5</span>, <span class="number">8</span>, <span class="number">130</span>, <span class="number">44</span>].every(isBigEnough)</span><br><span class="line"><span class="comment">// passed is false</span></span><br><span class="line">passed = [<span class="number">12</span>, <span class="number">54</span>, <span class="number">18</span>, <span class="number">130</span>, <span class="number">44</span>].every(isBigEnough)</span><br><span class="line"><span class="comment">// passed is true</span></span><br></pre></td></tr></table></figure></li><li><p><code>map()</code>返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组。</p><figure class="highlight javascript"><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="keyword">const</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line">arr.map(<span class="function">(<span class="params">item, index</span>) =></span> {</span><br><span class="line"> <span class="built_in">console</span>.log(item)</span><br><span class="line">})</span><br></pre></td></tr></table></figure></li><li><p><code>some()</code>测试数组中的某些元素是否通过了指定函数的测试。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//检测在数组中是否有元素大于 10。</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">isBigEnough</span>(<span class="params">element, index, array</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> element >= <span class="number">10</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> passed = [<span class="number">2</span>, <span class="number">5</span>, <span class="number">8</span>, <span class="number">1</span>, <span class="number">4</span>].some(isBigEnough)</span><br><span class="line"><span class="comment">// passed is false</span></span><br><span class="line">passed = [<span class="number">12</span>, <span class="number">5</span>, <span class="number">8</span>, <span class="number">1</span>, <span class="number">4</span>].some(isBigEnough)</span><br><span class="line"><span class="comment">// passed is true</span></span><br></pre></td></tr></table></figure></li></ul><ul><li><p><code>reduce()</code>接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值。</p><p>语法: arr.reduce(callback,[initialValue]) callback:执行数组中每个值的函数,包含四个参数</p><ul><li><code>previousValue</code> 上一次调用回调返回的值,或者是提供的初始值(initialValue)</li><li><code>currentValue</code> 数组中当前被处理的元素</li><li><code>index</code> 当前元素在数组中的索引</li><li><code>array</code> 调用 reduce 的数组 initialValue: 作为第一次调用 callback 的第一个参数。</li></ul><figure class="highlight javascript"><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="keyword">var</span> total = [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>].reduce(<span class="function"><span class="keyword">function</span>(<span class="params">a, b</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> a + b</span><br><span class="line">})</span><br><span class="line"><span class="comment">// total == 6</span></span><br></pre></td></tr></table></figure></li><li><p><code>Array.from()</code>用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arrayLike = {</span><br><span class="line"> <span class="string">'0'</span>: <span class="string">'a'</span>,</span><br><span class="line"> <span class="string">'1'</span>: <span class="string">'b'</span>,</span><br><span class="line"> <span class="string">'2'</span>: <span class="string">'c'</span>,</span><br><span class="line"> length: <span class="number">3</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// ES6的写法</span></span><br><span class="line"><span class="keyword">let</span> arr2 = <span class="built_in">Array</span>.from(arrayLike) <span class="comment">// ['a', 'b', 'c']</span></span><br></pre></td></tr></table></figure></li><li><p><code>Array.of()</code>方法用于将一组值,转换为数组。</p><figure class="highlight javascript"><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="built_in">Array</span>.of(<span class="number">3</span>, <span class="number">11</span>, <span class="number">8</span>) <span class="comment">// [3,11,8]</span></span><br><span class="line"><span class="built_in">Array</span>.of(<span class="number">3</span>) <span class="comment">// [3]</span></span><br><span class="line"><span class="built_in">Array</span>.of(<span class="number">3</span>).length <span class="comment">// 1</span></span><br></pre></td></tr></table></figure></li><li><p><code>fill()</code>方法使用给定值,填充一个数组。</p><figure class="highlight javascript"><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="string">'a'</span>, <span class="string">'b'</span>, <span class="string">'c'</span>].fill(<span class="number">7</span>)</span><br><span class="line"><span class="comment">// [7, 7, 7]</span></span><br><span class="line"><span class="keyword">new</span> <span class="built_in">Array</span>(<span class="number">3</span>).fill(<span class="number">7</span>)</span><br><span class="line"><span class="comment">// [7, 7, 7]</span></span><br></pre></td></tr></table></figure><p><code>fill</code>方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">;[<span class="string">'a'</span>, <span class="string">'b'</span>, <span class="string">'c'</span>].fill(<span class="number">7</span>, <span class="number">1</span>, <span class="number">2</span>)</span><br><span class="line"><span class="comment">// ['a', 7, 'c']</span></span><br></pre></td></tr></table></figure></li></ul><h3 id="遍历数组"><a href="#遍历数组" class="headerlink" title="遍历数组"></a>遍历数组</h3><ul><li><p>·keys()`是对键名的遍历</p><figure class="highlight javascript"><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="keyword">for</span> (<span class="keyword">let</span> index <span class="keyword">of</span> [<span class="string">'a'</span>, <span class="string">'b'</span>].keys()) {</span><br><span class="line"> <span class="built_in">console</span>.log(index)</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 0</span></span><br><span class="line"><span class="comment">// 1</span></span><br></pre></td></tr></table></figure></li><li><p><code>values()</code>是对键值的遍历</p></li></ul><figure class="highlight javascript"><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="keyword">for</span> (<span class="keyword">let</span> elem <span class="keyword">of</span> [<span class="string">'a'</span>, <span class="string">'b'</span>].values()) {</span><br><span class="line"> <span class="built_in">console</span>.log(elem)</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 'a'</span></span><br><span class="line"><span class="comment">// 'b'</span></span><br></pre></td></tr></table></figure><ul><li><code>entries()</code>是对键值对的遍历。</li></ul><figure class="highlight javascript"><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="keyword">for</span> (<span class="keyword">let</span> [index, elem] <span class="keyword">of</span> [<span class="string">'a'</span>, <span class="string">'b'</span>].entries()) {</span><br><span class="line"> <span class="built_in">console</span>.log(index, elem)</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 0 "a"</span></span><br><span class="line"><span class="comment">// 1 "b"</span></span><br></pre></td></tr></table></figure><ul><li>includes()</li></ul>]]></content>
<summary type="html">
<h3 id="数组的创建"><a href="#数组的创建" class="headerlink" title="数组的创建"></a>数组的创建</h3><figure class="highlight javascript"><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="keyword">var</span> arrayObj = []; <span class="comment">//普通数组创建</span></span><br><span class="line"><span class="keyword">var</span> arrayObj = <span class="keyword">new</span> <span class="built_in">Array</span>(); <span class="comment">//创建一个数组</span></span><br><span class="line"><span class="keyword">var</span> arrayObj = <span class="keyword">new</span> <span class="built_in">Array</span>([size]); <span class="comment">//创建一个数组并指定长度,注意不是上限,是长度</span></span><br><span class="line"><span class="keyword">var</span> arrayObj = <span class="keyword">new</span> <span class="built_in">Array</span>([element0[, element1[, ...[, elementN]]]]); <span class="comment">//创建一个数组并赋值</span></span><br></pre></td></tr></table></figure>
</summary>
<category term="javascript" scheme="https://lingmissing.github.io/tags/javascript/"/>
</entry>
<entry>
<title>ES6展开运算符</title>
<link href="https://lingmissing.github.io/2016/08/25/es6%E5%B1%95%E5%BC%80%E8%BF%90%E7%AE%97%E7%AC%A6/"/>
<id>https://lingmissing.github.io/2016/08/25/es6展开运算符/</id>
<published>2016-08-25T13:05:00.000Z</published>
<updated>2019-01-04T03:37:20.027Z</updated>
<content type="html"><![CDATA[<h3 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h3><ul><li><p>用于函数调用</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">myFunction(...iterableObj)</span><br></pre></td></tr></table></figure></li><li><p>用于数组字面量</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">;[...iterableObj, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br></pre></td></tr></table></figure></li></ul><a id="more"></a><h3 id="函数传参"><a href="#函数传参" class="headerlink" title="函数传参"></a>函数传参</h3><p>目前为止,我们都是使用<code>Function.prototype.apply</code>方法来将一个数组展开成多个参数:</p><figure class="highlight javascript"><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="function"><span class="keyword">function</span> <span class="title">myFunction</span>(<span class="params">x, y, z</span>) </span>{}</span><br><span class="line"><span class="keyword">var</span> args = [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>]</span><br><span class="line">myFunction.apply(<span class="literal">null</span>, args)</span><br></pre></td></tr></table></figure><p>使用 es6 的展开运算符可以这么写:</p><figure class="highlight javascript"><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="function"><span class="keyword">function</span> <span class="title">myFunction</span>(<span class="params">x, y, z</span>) </span>{}</span><br><span class="line"><span class="keyword">var</span> args = [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>]</span><br><span class="line">myFunction(...args)</span><br></pre></td></tr></table></figure><ul><li>选择性传参<figure class="highlight javascript"><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="function"><span class="keyword">function</span> <span class="title">filter</span>(<span class="params">type, ...items</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> items.filter(<span class="function"><span class="params">item</span> =></span> <span class="keyword">typeof</span> item === type)</span><br><span class="line">}</span><br><span class="line">filter(<span class="string">'boolean'</span>, <span class="literal">true</span>, <span class="number">0</span>, <span class="literal">false</span>) <span class="comment">// => [true, false]</span></span><br><span class="line">filter(<span class="string">'number'</span>, <span class="literal">false</span>, <span class="number">4</span>, <span class="string">'Welcome'</span>, <span class="number">7</span>) <span class="comment">// => [4, 7]</span></span><br></pre></td></tr></table></figure></li></ul><p>还可以同时展开多个数组:</p><figure class="highlight javascript"><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="function"><span class="keyword">function</span> <span class="title">myFunction</span>(<span class="params">v, w, x, y, z</span>) </span>{}</span><br><span class="line"><span class="keyword">var</span> args = [<span class="number">0</span>, <span class="number">1</span>]</span><br><span class="line">myFunction(<span class="number">-1</span>, ...args, <span class="number">2</span>, ...[<span class="number">3</span>])</span><br></pre></td></tr></table></figure><h3 id="数据解构"><a href="#数据解构" class="headerlink" title="数据解构"></a>数据解构</h3><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> cold = [<span class="string">'autumn'</span>, <span class="string">'winter'</span>]</span><br><span class="line"><span class="keyword">let</span> warm = [<span class="string">'spring'</span>, <span class="string">'summer'</span>]</span><br><span class="line"><span class="comment">// 析构数组</span></span><br><span class="line"><span class="keyword">let</span> otherSeasons, autumn</span><br><span class="line">;[autumn, ...otherSeasons] = cold</span><br><span class="line">otherSeasons <span class="comment">// => ['winter']</span></span><br></pre></td></tr></table></figure><h3 id="数据构造"><a href="#数据构造" class="headerlink" title="数据构造"></a>数据构造</h3><ul><li><p>两个对象连接返回新的对象</p><figure class="highlight javascript"><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="keyword">let</span> a = { <span class="attr">aa</span>: <span class="string">'aa'</span> }</span><br><span class="line"><span class="keyword">let</span> b = { <span class="attr">bb</span>: <span class="string">'bb'</span> }</span><br><span class="line"><span class="keyword">let</span> c = { ...a, ...b }</span><br><span class="line"><span class="built_in">console</span>.log(c)</span><br><span class="line"><span class="comment">// {"aa":"aa","bb":"bb"}</span></span><br></pre></td></tr></table></figure></li><li><p>两个数组连接返回新的数组</p><figure class="highlight javascript"><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="keyword">let</span> d = [<span class="string">'dd'</span>]</span><br><span class="line"><span class="keyword">let</span> e = [<span class="string">'ee'</span>]</span><br><span class="line"><span class="keyword">let</span> f = [...d, ...e]</span><br><span class="line"><span class="built_in">console</span>.log(f)</span><br><span class="line"><span class="comment">// ["dd","ee"]</span></span><br></pre></td></tr></table></figure><ul><li><p>在中间插入数组</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> parts = [<span class="string">'shoulder'</span>, <span class="string">'knees'</span>]</span><br><span class="line"><span class="keyword">var</span> lyrics = [<span class="string">'head'</span>, ...parts, <span class="string">'and'</span>, <span class="string">'toes'</span>] <span class="comment">// ["head", "shoulders", "knees", "and", "toes"]</span></span><br></pre></td></tr></table></figure></li><li><p>在尾部插入数组</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// ES5</span></span><br><span class="line"><span class="keyword">var</span> arr1 = [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>]</span><br><span class="line"><span class="keyword">var</span> arr2 = [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line"><span class="comment">// 将arr2中的所有元素添加到arr1中</span></span><br><span class="line"><span class="built_in">Array</span>.prototype.push.apply(arr1, arr2)</span><br><span class="line"></span><br><span class="line"><span class="comment">// ES6</span></span><br><span class="line"><span class="keyword">var</span> arr1 = [<span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>]</span><br><span class="line"><span class="keyword">var</span> arr2 = [<span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line">arr1.push(...arr2)</span><br></pre></td></tr></table></figure></li></ul></li><li><p>数组加上对象返回新的数组</p><figure class="highlight javascript"><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="keyword">let</span> g = [{ <span class="attr">gg</span>: <span class="string">'gg'</span> }]</span><br><span class="line"><span class="keyword">let</span> h = { <span class="attr">hh</span>: <span class="string">'hh'</span> }</span><br><span class="line"><span class="keyword">let</span> i = [...g, h]</span><br><span class="line"><span class="built_in">console</span>.log(i)</span><br><span class="line"><span class="comment">// [{"gg":"gg"},{"hh":"hh"}</span></span><br></pre></td></tr></table></figure></li><li><p>数组+字符串</p><figure class="highlight javascript"><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="keyword">let</span> j = [<span class="string">'jj'</span>]</span><br><span class="line"><span class="keyword">let</span> k = <span class="string">'kk'</span></span><br><span class="line"><span class="keyword">let</span> l = [...j, k]</span><br><span class="line"><span class="built_in">console</span>.log(l)</span><br><span class="line"><span class="comment">// ["jj","kk"]</span></span><br></pre></td></tr></table></figure></li><li><p>带有数组和对象的结合</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> state = {</span><br><span class="line"> resultList: [],</span><br><span class="line"> currentPage: <span class="number">0</span>,</span><br><span class="line"> totalRows: {}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">let</span> data = {</span><br><span class="line"> resultList: [{ <span class="attr">new</span>: <span class="string">'new'</span> }],</span><br><span class="line"> currentPage: <span class="number">2</span>,</span><br><span class="line"> totalRows: { <span class="attr">row</span>: <span class="string">'row'</span> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">let</span> combile = {</span><br><span class="line"> ...state,</span><br><span class="line"> resultList: [...state.resultList, ...data.resultList],</span><br><span class="line"> currentPage: data.currentPage,</span><br><span class="line"> totalRows: data.totalRows</span><br><span class="line">}</span><br><span class="line"><span class="built_in">console</span>.log(combile)</span><br><span class="line"><span class="comment">// {"resultList":[{"new":"new"}],"currentPage":2,"totalRows":{"row":"row"}}</span></span><br></pre></td></tr></table></figure></li></ul>]]></content>
<summary type="html">
<h3 id="语法"><a href="#语法" class="headerlink" title="语法"></a>语法</h3><ul>
<li><p>用于函数调用</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">myFunction(...iterableObj)</span><br></pre></td></tr></table></figure>
</li>
<li><p>用于数组字面量</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">;[...iterableObj, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br></pre></td></tr></table></figure>
</li>
</ul>
</summary>
<category term="javascript" scheme="https://lingmissing.github.io/tags/javascript/"/>
</entry>
<entry>
<title>flex布局</title>
<link href="https://lingmissing.github.io/2016/08/19/flex%E5%B8%83%E5%B1%80/"/>
<id>https://lingmissing.github.io/2016/08/19/flex布局/</id>
<published>2016-08-19T06:41:02.000Z</published>
<updated>2019-01-04T03:37:45.636Z</updated>
<content type="html"><![CDATA[<h2 id="Flex-容器属性"><a href="#Flex-容器属性" class="headerlink" title="Flex 容器属性"></a>Flex 容器属性</h2><h5 id="display"><a href="#display" class="headerlink" title="display"></a>display</h5><p>定义一个 Flex 容器,根据其取的值来决定是内联还是块。Flex 容器会为其内容建立新的伸缩格式化上下文。</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">.container</span> {</span><br><span class="line"> <span class="attribute">display</span>: flex; <span class="comment">/* or inline-flex */</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><a id="more"></a><h5 id="flex-direction"><a href="#flex-direction" class="headerlink" title="flex-direction"></a>flex-direction</h5><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">.container</span> {</span><br><span class="line"> <span class="attribute">flex-direction</span>: row | row-reverse | column | column-reverse;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>row(默认值):如果书写方式是 ltr,那么 Flex 项目从左向右排列;如果书写方式是 rtl,那么 Flex 项目从右向左排列</li><li>row-reverse:如果书写方式是 ltr,那么 Flex 项目从右向左排列;如果书写方式是 rtl,那么 Flex 项目从左向右排列</li><li>column:和 row 类似,只不过方向是从上到下排列</li><li>column-reverse:和 row-reverse 类似,只不过方向是从下向上排列</li></ul><h5 id="flex-wrap"><a href="#flex-wrap" class="headerlink" title="flex-wrap"></a>flex-wrap</h5><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">.container</span> {</span><br><span class="line"> <span class="attribute">flex-wrap</span>: nowrap | wrap | wrap-reverse;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>nowrap(默认值):单行显示,如果书写方式是 ltr,Flex 项目从左向右排列,反之 rtl,从右向左排列</li><li>wrap:多行显示,如果书写方式是 ltr,Flex 项目从左向右排列,反之 rtl,从右向左排列</li><li>wrap-reverse:多行显示,如果书写方式是 ltr,Flex 项目从右向左排列,反之 rtl,从左向右排列</li></ul><h5 id="flex-flow-适用于-flex-容器元素"><a href="#flex-flow-适用于-flex-容器元素" class="headerlink" title="flex-flow(适用于 flex 容器元素)"></a>flex-flow(适用于 flex 容器元素)</h5><p>这是 flex-direction 和 flex-wrap 两个属性的缩写。两个属性决定了伸缩容器的主轴与侧轴。默认值是 row nowrap(中间用空格隔开)。</p><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">flex-flow: <‘flex-direction’> || <‘flex-wrap’>;</span><br></pre></td></tr></table></figure><h5 id="justify-content"><a href="#justify-content" class="headerlink" title="justify-content"></a>justify-content</h5><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">.container</span> {</span><br><span class="line"> <span class="attribute">justify-content</span>: flex-start | flex-end | center | space-between | space-around;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>flex-start(默认值):伸缩项目向一行的起始位置靠齐。该行的第一个伸缩项目在主轴起点边的外边距与该行在主轴起点的边对齐,同时所有后续的伸缩项目与其前一个项目对齐。</li><li>flex-end:伸缩项目向一行的结束位置靠齐。该行的最后一个伸缩项目在主轴终点边的外边距与该行在主轴终点的边对齐,同时所有前面的伸缩项目与其后一个项目对齐。</li><li>center:伸缩项目向一行的中间位置靠齐。该行的伸缩项目将相互对齐并在行中居中对齐,同时第一个项目与该行在主轴起点的边的距离等同与最后一个项目与该行在主轴终点的边的距离(如果剩余空间是负数,则保持两端溢出的长度相等)。</li><li>space-between:伸缩项目会平均地分布在行里。如果剩余空间是负数,或该行只有一个伸缩项目,则此值等效于 flex-start。在其它情况下,第一个项目在主轴起点边的外边距会与该行在主轴起点的边对齐,同时最后一个项目在主轴终点边的外边距与该行在主轴终点的边对齐,而剩下的伸缩项目在确保两两之间的空白空间相等下平均分布。</li><li>space-around:伸缩项目会平均地分布在行里,两端保留一半的空间。如果剩余空间是负数,或该行只有一个伸缩项目,则该值等效于 center。在其它情况下,伸缩项目在确保两两之间的空白空间相等,同时第一个元素前的空间以及最后一个元素后的空间为其他空白空间的一半下平均分布。</li></ul><h5 id="align-items"><a href="#align-items" class="headerlink" title="align-items"></a>align-items</h5><p>align-items 可以用来设置伸缩容器中包括匿名伸缩项目的所有项目的对齐方式。</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">.container</span> {</span><br><span class="line"> <span class="attribute">align-items</span>: flex-start | flex-end | center | baseline | stretch;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>flex-start:伸缩项目在侧轴起点边的外边距紧靠住该行在侧轴起始的边。</li><li>flex-end:伸缩项目在侧轴终点边的外边距靠住该行在侧轴终点的边 。</li><li>center:伸缩项目的外边距盒在该行的侧轴上居中放置。(如果伸缩行的尺寸小于伸缩项目,则伸缩项目会向两个方向溢出相同的量)。</li><li>baseline:如果伸缩项目的行内轴与侧轴为同一条,则该值和 flex-start 等效。其它情况下,该值将参与基线对齐。所有参与该对齐方式的伸缩项目将按下列方式排列:首先将这些伸缩项目的基线进行对齐,随后其中基线至侧轴起点边的外边距距离最长的那个项目将紧靠住该行在侧轴起点的边。</li><li>stretch:如果侧轴长度属性的值为 auto,则此值会使项目的外边距盒的尺寸在遵照 min/max-width/height 属性的限制下尽可能接近所在行的尺寸。</li></ul><h5 id="align-content"><a href="#align-content" class="headerlink" title="align-content"></a>align-content</h5><p>当伸缩容器的侧轴还有多余空间时,align-content 属性可以用来调准伸缩行在伸缩容器里的对齐方式.</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><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.container</span> {</span><br><span class="line"> <span class="attribute">align-content</span>: flex-start | flex-end | center | space-between | space-around |</span><br><span class="line"> stretch;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>flex-start:各行向伸缩容器的起点位置堆叠。伸缩容器中第一行在侧轴起点的边会紧靠住伸缩容器在侧轴起点的边,之后的每一行都紧靠住前面一行。</li><li>flex-end:各行向伸缩容器的结束位置堆叠。伸缩容器中最后一行在侧轴终点的边会紧靠住该伸缩容器在侧轴终点的边,之前的每一行都紧靠住后面一行。</li><li>center:各行向伸缩容器的中间位置堆叠。各行两两紧靠住同时在伸缩容器中居中对齐,保持伸缩容器在侧轴起点边的内容边和第一行之间的距离与该容器在侧轴终点边的内容边与第最后一行之间的距离相等。(如果剩下的空间是负数,则行的堆叠会向两个方向溢出的相等距离。)</li><li>space-between:各行在伸缩容器中平均分布。如果剩余的空间是负数或伸缩容器中只有一行,该值等效于 flex-start。在其它情况下,第一行在侧轴起点的边会紧靠住伸缩容器在侧轴起点边的内容边,最后一行在侧轴终点的边会紧靠住伸缩容器在侧轴终点的内容边,剩余的行在保持两两之间的空间相等的状况下排列。</li><li>space-around:各行在伸缩容器中平均分布,在两边各有一半的空间。如果剩余的空间是负数或伸缩容器中只有一行,该值等效于 center。在其它情况下,各行会在保持两两之间的空间相等,同时第一行前面及最后一行后面的空间是其他空间的一半的状况下排列。</li><li>stretch:各行将会伸展以占用剩余的空间。如果剩余的空间是负数,该值等效于 flex-start。在其它情况下,剩余空间被所有行平分,扩大各行的侧轴尺寸。</li></ul><h2 id="Flex-项目属性"><a href="#Flex-项目属性" class="headerlink" title="Flex 项目属性"></a>Flex 项目属性</h2><h5 id="order"><a href="#order" class="headerlink" title="order"></a>order</h5><p>默认情况,Flex 项目是按文档源的流顺序排列。然而,在 Flex 容器中可以通过 order 属性来控制 Flex 项目的顺序源。</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">.item</span> {</span><br><span class="line"> <span class="attribute">order</span>: <integer>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="flex-grow"><a href="#flex-grow" class="headerlink" title="flex-grow"></a>flex-grow</h5><p>如果所有 Flex 项目的 flex-grow 设置为 1 时,表示 Flex 容器中的 Flex 项目具有相等的尺寸。如果你给其中一个 Flex 项目设置 flex-grow 的值为 2,那么这个 Flex 项目的尺寸将是其他 Flex 项目两倍。</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">.item</span> {</span><br><span class="line"> <span class="attribute">flex-grow</span>: <number>; <span class="comment">/* default 0 */</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="flex-shrink"><a href="#flex-shrink" class="headerlink" title="flex-shrink"></a>flex-shrink</h5><p>如果有必要,flex-shrink 可以定义 Flex 项目的缩小比例。</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">.item</span> {</span><br><span class="line"> <span class="attribute">flex-shrink</span>: <number>; <span class="comment">/* default 1 */</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="flex-basis"><a href="#flex-basis" class="headerlink" title="flex-basis"></a>flex-basis</h5><p>flex-basis 属性定义了 Flex 项目在分配 Flex 容器剩余空间之前的一个默认尺寸。main-size 值使它具有匹配的宽度或高度,不过都需要取决于 flex-direction 的值。</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">.item</span> {</span><br><span class="line"> <span class="attribute">flex-basis</span>: <length> | auto; <span class="comment">/* default auto */</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="flex"><a href="#flex" class="headerlink" title="flex"></a>flex</h5><p>flex 是 flex-grow,flex-shrink 和 flex-basis 三个属性的缩写。第二个和第三个参数(flex-shrink 和 flex-basis)是可选值。其默认值是 0 1 auto。</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">.item</span> {</span><br><span class="line"> <span class="attribute">flex</span>: none | [ < <span class="string">'flex-grow'</span> > < <span class="string">'flex-shrink'</span> >? || < <span class="string">'flex-basis'</span> > ];</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="align-self"><a href="#align-self" class="headerlink" title="align-self"></a>align-self</h5><p>align-self 则用来在单独的伸缩项目上覆写默认的对齐方式。(对于匿名伸缩项目,align-self 的值永远与其关联的伸缩容器的 align-items 的值相同。)</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">.item</span> {</span><br><span class="line"> <span class="attribute">align-self</span>: auto | flex-start | flex-end | center | baseline | stretch;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="常用案例"><a href="#常用案例" class="headerlink" title="常用案例"></a>常用案例</h2><ul><li>子元素等分</li></ul><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><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">ul</span> {</span><br><span class="line"> <span class="attribute">display</span>: flex;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">li</span> {</span><br><span class="line"> <span class="attribute">flex</span>: <span class="number">1</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>左右固定宽度,中间自适应</li></ul><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><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></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">ul</span> {</span><br><span class="line"> <span class="attribute">display</span>: flex;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">li</span><span class="selector-pseudo">:first-child</span>,</span><br><span class="line"><span class="selector-tag">li</span><span class="selector-pseudo">:last-child</span> {</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">50px</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">li</span><span class="selector-pseudo">:nth-child(2)</span> {</span><br><span class="line"> <span class="attribute">flex</span>: <span class="number">1</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>底部贴底</li></ul><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><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></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">html</span>,</span><br><span class="line"><span class="selector-tag">body</span>,</span><br><span class="line"><span class="selector-tag">ul</span> {</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">100%</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">ul</span> {</span><br><span class="line"> <span class="attribute">display</span>: flex;</span><br><span class="line"> <span class="attribute">flex-direction</span>: column;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">li</span><span class="selector-pseudo">:first-child</span>,</span><br><span class="line"><span class="selector-tag">li</span><span class="selector-pseudo">:last-child</span> {</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">50px</span>;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">li</span><span class="selector-pseudo">:nth-child(2)</span> {</span><br><span class="line"> <span class="attribute">flex</span>: <span class="number">1</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>多行多列(商品列表)</li></ul><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><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">ul</span> {</span><br><span class="line"> <span class="attribute">display</span>: flex;</span><br><span class="line"> flex-wrap: wrap; //允许换行</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">li</span> {</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">50%</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>两端对齐垂直居中(导航)</li></ul><figure class="highlight html"><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="tag"><<span class="name">header</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">h1</span>></span>标题<span class="tag"></<span class="name">h1</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">""</span>></span>更多<span class="tag"></<span class="name">a</span>></span></span><br><span class="line"><span class="tag"></<span class="name">header</span>></span></span><br></pre></td></tr></table></figure><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><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">header</span> {</span><br><span class="line"> <span class="attribute">display</span>: flex;</span><br><span class="line"> <span class="attribute">justify-content</span>: space-between;</span><br><span class="line"> <span class="attribute">align-items</span>: center;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>水平垂直居中(img)</li></ul><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><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">header</span> {</span><br><span class="line"> <span class="attribute">display</span>: flex;</span><br><span class="line"> <span class="attribute">justify-content</span>: center;</span><br><span class="line"> <span class="attribute">align-items</span>: center;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>子元素横向排列,超过父容器宽度不换行(slider)</li></ul><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><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">ul</span> {</span><br><span class="line"> <span class="attribute">display</span>: flex;</span><br><span class="line">}</span><br><span class="line"><span class="selector-tag">li</span> {</span><br><span class="line"> <span class="attribute">flex-shrink</span>: <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>转载自<a href="http://www.w3cplus.com/css3/a-guide-to-flexbox-new.html" target="_blank" rel="noopener">一个完整的 Flexbox 指南</a></p>]]></content>
<summary type="html">
<h2 id="Flex-容器属性"><a href="#Flex-容器属性" class="headerlink" title="Flex 容器属性"></a>Flex 容器属性</h2><h5 id="display"><a href="#display" class="headerlink" title="display"></a>display</h5><p>定义一个 Flex 容器,根据其取的值来决定是内联还是块。Flex 容器会为其内容建立新的伸缩格式化上下文。</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">.container</span> &#123;</span><br><span class="line"> <span class="attribute">display</span>: flex; <span class="comment">/* or inline-flex */</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</summary>
<category term="css3" scheme="https://lingmissing.github.io/tags/css3/"/>
</entry>
<entry>
<title>react&redux基础</title>
<link href="https://lingmissing.github.io/2016/08/18/react-redux%E5%9F%BA%E7%A1%80/"/>
<id>https://lingmissing.github.io/2016/08/18/react-redux基础/</id>
<published>2016-08-18T02:36:45.000Z</published>
<updated>2019-01-04T03:40:20.124Z</updated>
<content type="html"><![CDATA[<p><code>Redux</code> 主要分为三个部分 <code>Action</code>、<code>Reducer</code>、及 <code>Store</code></p><p>原理:</p><ul><li><code>view</code>直接触发<code>dispatch</code>;</li><li>将<code>action</code>发送到<code>reducer</code>中后,根节点上会更新 <code>state</code>,改变全局<code>view</code>。</li></ul><a id="more"></a><p>本案例以一个提到 TODOLIST 为案例。</p><h2 id="Action"><a href="#Action" class="headerlink" title="Action"></a>Action</h2><p>在 <code>Redux</code> 中,<code>action</code> 主要用来传递操作 <code>State</code> 的信息,只是一种命令,并没有实际改变<code>state</code>。</p><p>我们约定,<code>action</code> 内必须使用一个字符串类型的 <code>type</code> 字段来表示将要执行的动作。<code>type</code> 属性是必要的,除了 <code>type</code> 字段外,<code>action</code> 对象的结构完全取决于你,建议尽可能简单。<code>type</code> 一般用来表达处理 <code>state</code> 数据的方式。</p><p>比如添加<code>todo</code>的<code>action</code>:</p><figure class="highlight javascript"><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="keyword">const</span> ADD_TODO = <span class="string">'ADD_TODO'</span></span><br><span class="line">{</span><br><span class="line"> type: ADD_TODO,</span><br><span class="line"> text: <span class="string">'Build my first Redux app'</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这个动作需要改变哪些属性就传递这些属性。</p><h5 id="创建函数"><a href="#创建函数" class="headerlink" title="创建函数"></a>创建函数</h5><p>如果有多个数据是同样的动作,那么我们就需要一个通用的函数来传递数据。在 <code>Redux</code> 中的 <code>action</code> 创建函数只是简单的返回一个 <code>action</code>:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//actions</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> ADD_TODO = <span class="string">'ADD_TODO'</span></span><br><span class="line"><span class="keyword">export</span> <span class="function"><span class="keyword">function</span> <span class="title">addTodo</span>(<span class="params">text</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> type: ADD_TODO,</span><br><span class="line"> text</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>或者</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//actions</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> ADD_TODO = <span class="string">'ADD_TODO'</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> addTodo = <span class="function"><span class="params">text</span> =></span> {</span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> type: ADD_TODO,</span><br><span class="line"> text</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>在组件的事件中,<code>Redux</code> 中只需把 <code>action</code> 创建函数的结果传给 <code>dispatch()</code> 方法即可发起一次 <code>dispatch</code> 过程。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dispatch(addTodo(text))</span><br></pre></td></tr></table></figure><p>或者</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> boundAddTodo = <span class="function"><span class="params">text</span> =></span> dispatch(addTodo(text))</span><br><span class="line">boundAddTodo(text)</span><br></pre></td></tr></table></figure><h5 id="bindActionCreators"><a href="#bindActionCreators" class="headerlink" title="bindActionCreators"></a>bindActionCreators</h5><p>如上所示,我们每次都需要调用时 dispatch 这个 action。</p><p>在 React 组件中,如果你希望让组件通过调用函数来更新 state,可以通过使用 const actions = bindActionCreators(FilmActions, dispatch); 将 actions 和 dispatch 揉在一起,成为具备操作 store.state 的 actions。</p><h2 id="Reducer"><a href="#Reducer" class="headerlink" title="Reducer"></a>Reducer</h2><p>Action 只是描述了有事情发生了这一事实,并没有指明应用如何更新 state。而这正是 reducer 要做的事情。</p><p>当明确 action 的任务,就可以开始编写 reducer,并让它来处理之前定义过的 action。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//reducers</span></span><br><span class="line"><span class="keyword">import</span> { addTodo, ADD_TODO } <span class="keyword">from</span> <span class="string">'./actions'</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">todoApp</span>(<span class="params">state = initialState, action</span>) </span>{</span><br><span class="line"> <span class="keyword">switch</span> (action.type) {</span><br><span class="line"> <span class="keyword">case</span> ADD_TODO:</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">Object</span>.assign({}, state, {</span><br><span class="line"> text: action.text</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> <span class="keyword">return</span> state</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>注意:</p><ul><li>不要修改 state。 使用 Object.assign() 新建了一个副本。为了对 ES7 提案对象展开运算符的支持, 也可以使用 { …state, …newState } 达到相同的目的。</li><li>在 default 情况下返回旧的 state。遇到未知的 action 时,一定要返回旧的 state。</li><li>reducer 中的一个 fun 在 store 里作为一个对象存储。</li></ul><h5 id="combineReducers"><a href="#combineReducers" class="headerlink" title="combineReducers"></a>combineReducers</h5><p>combineReducers() 所做的只是生成一个函数,这个函数来调用你的一系列 reducer,每个 reducer 根据它们的 key 来筛选出 state 中的一部分数据并处理,然后这个生成的函数再将所有 reducer 的结果合并成一个大的对象。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { combineReducers } <span class="keyword">from</span> <span class="string">'redux'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> todoApp = combineReducers({</span><br><span class="line"> todoApp</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> todoApp</span><br></pre></td></tr></table></figure><h2 id="Store"><a href="#Store" class="headerlink" title="Store"></a>Store</h2><p><code>Store</code> 就是把<code>action</code>和<code>reducer</code>联系到一起的对象。<code>Store</code> 有以下职责:</p><ul><li>维持应用的 <code>state</code>;</li><li>提供 <code>getState()</code> 方法获取 <code>state</code>;</li><li>提供 <code>dispatch(action)</code> 方法更新 <code>state</code>;</li><li>通过 <code>subscribe(listener)</code> 注册监听器;</li><li>通过 <code>subscribe(listener)</code> 返回的函数注销监听器。</li></ul><blockquote><p><code>Redux</code> 应用只有一个单一的 <code>store</code>。当需要拆分数据处理逻辑时,你应该使用 <code>reducer</code>组合 而不是创建多个 <code>store</code>。</p></blockquote><p>我们使用 <code>combineReducers()</code> 将多个 <code>reducer</code> 合并成为一个。现在我们将其导入,并传递 <code>createStore()</code>。</p><figure class="highlight javascript"><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="keyword">import</span> { createStore } <span class="keyword">from</span> <span class="string">'redux'</span></span><br><span class="line"><span class="keyword">import</span> todoApp <span class="keyword">from</span> <span class="string">'./reducers'</span></span><br><span class="line"><span class="keyword">let</span> store = createStore(todoApp)</span><br></pre></td></tr></table></figure><h5 id="Middleware"><a href="#Middleware" class="headerlink" title="Middleware"></a>Middleware</h5><p><code>redux</code>中的<code>middleware</code>还是比较简单的,它只是针对于<code>dispatch</code>方法做了<code>middleware</code>处理;也就是说,只接受一个<code>action</code>对象;</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> createLogger <span class="keyword">from</span> <span class="string">'redux-logger'</span></span><br><span class="line"><span class="keyword">import</span> { createStore, applyMiddleware } <span class="keyword">from</span> <span class="string">'redux'</span></span><br><span class="line"><span class="keyword">import</span> thunk <span class="keyword">from</span> <span class="string">'redux-thunk'</span></span><br><span class="line"><span class="keyword">import</span> reducers <span class="keyword">from</span> <span class="string">'./reducers'</span></span><br><span class="line"><span class="keyword">const</span> logger = createLogger()</span><br><span class="line"><span class="keyword">let</span> thunkStore = applyMiddleware(thunk, logger)(createStore)</span><br><span class="line"><span class="keyword">let</span> store = thunkStore(reducers)</span><br></pre></td></tr></table></figure><h2 id="connect"><a href="#connect" class="headerlink" title="connect"></a>connect</h2><figure class="highlight javascript"><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">connect(</span><br><span class="line"> mapStateToProps,</span><br><span class="line"> mapDispatchToProps,</span><br><span class="line"> mergeToProps</span><br><span class="line">)(App)</span><br></pre></td></tr></table></figure><p>第一个函数接收 store 中 state 和 props,使页面可以根据当前的 store 中 state 和 props 返回新的<code>stateProps</code>;<br>第二个函数接收 store 中的 dispatch 和 props,使页面可以复写 dispatch 方法,返回新的<code>dispatchProps</code>;<br>第三个函数接收前 2 个函数生成的<code>stateProps</code>和<code>dispatchProps</code>,在加上原始的<code>props</code>,合并成新的<code>props</code>,并传给原始根节点的<code>props</code>。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> mapStateToProps = <span class="function">(<span class="params">state, ownProps</span>) =></span> {</span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> active: ownProps.filter === state.visibilityFilter</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> mapDispatchToProps = <span class="function">(<span class="params">dispatch, ownProps</span>) =></span> {</span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> onClick: <span class="function"><span class="params">()</span> =></span> {</span><br><span class="line"> dispatch(setVisibilityFilter(ownProps.filter))</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="keyword">const</span> FilterLink = connect(</span><br><span class="line"> mapStateToProps,</span><br><span class="line"> mapDispatchToProps</span><br><span class="line">)(Link)</span><br></pre></td></tr></table></figure><h2 id="Provider"><a href="#Provider" class="headerlink" title="Provider"></a>Provider</h2><p><provider store=""> 使组件层级中的 connect() 方法都能够获得 Redux store。正常情况下,你的根组件应该嵌套在 <provider> 中才能使用 connect() 方法。</provider></provider></p><p><code>react-redux</code>首先提供了一个<code>Provider</code>,可以将从<code>createStore</code>返回的<code>store</code>放入<code>context</code>中,使子集可以获取到<code>store</code>并进行操作;</p><p>Connect 组件需要 store。这个需求由 Redux 提供的另一个组件 Provider 来提供。源码中,Provider 继承了 React.Component,所以可以以 React 组件的形式来为 Provider 注入 store,从而使得其子组件能够在上下文中得到 store 对象。</p><figure class="highlight javascript"><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"><Provider store={store}></span><br><span class="line"> <App /></span><br><span class="line"><<span class="regexp">/Provider></span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p><code>Redux</code> 主要分为三个部分 <code>Action</code>、<code>Reducer</code>、及 <code>Store</code></p>
<p>原理:</p>
<ul>
<li><code>view</code>直接触发<code>dispatch</code>;</li>
<li>将<code>action</code>发送到<code>reducer</code>中后,根节点上会更新 <code>state</code>,改变全局<code>view</code>。</li>
</ul>
</summary>
<category term="react" scheme="https://lingmissing.github.io/tags/react/"/>
<category term="redux" scheme="https://lingmissing.github.io/tags/redux/"/>
</entry>
<entry>
<title>React组件生命周期</title>
<link href="https://lingmissing.github.io/2016/08/16/React%E7%BB%84%E4%BB%B6%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/"/>
<id>https://lingmissing.github.io/2016/08/16/React组件生命周期/</id>
<published>2016-08-16T06:14:55.000Z</published>
<updated>2019-01-04T03:40:53.612Z</updated>
<content type="html"><![CDATA[<p>组件的生命周期包含三个主要部分:</p><ul><li>挂载: 组件被插入到 DOM 中。</li><li>更新: 组件被重新渲染,查明 DOM 是否应该刷新。</li><li>移除: 组件从 DOM 中移除。</li></ul><a id="more"></a><blockquote><p>React 提供生命周期方法,你可以在这些方法中放入自己的代码。我们提供 will 方法,会在某些行为发生之前调用,和 did 方法,会在某些行为发生之后调用。</p></blockquote><p><img src="/myBlog/artical_imgs/component-lifecycle.jpg"></p><h3 id="装载组件触发"><a href="#装载组件触发" class="headerlink" title="装载组件触发"></a>装载组件触发</h3><h5 id="getInitialState"><a href="#getInitialState" class="headerlink" title="getInitialState"></a>getInitialState</h5><p><code>object</code>在组件被挂载之前调用。状态化的组件应该实现这个方法,返回初始的<code>state</code>数据。</p><p>初始化 <code>this.state</code> 的值,只在组件装载之前调用一次。</p><p>如果是使用 ES6 的语法,你也可以在构造函数中初始化状态,比如:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Counter</span> <span class="keyword">extends</span> <span class="title">Component</span> </span>{</span><br><span class="line"> <span class="keyword">constructor</span>(props) {</span><br><span class="line"> <span class="keyword">super</span>(props)</span><br><span class="line"> <span class="keyword">this</span>.state = { <span class="attr">count</span>: props.initialCount }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> render() {</span><br><span class="line"> <span class="comment">// ...</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="getDefaultProps"><a href="#getDefaultProps" class="headerlink" title="getDefaultProps"></a>getDefaultProps</h5><p>只在组件创建时调用一次并缓存返回的对象(即在 <code>React.createClass</code> 之后就会调用)。</p><p>因为这个方法在实例初始化之前调用,所以在这个方法里面不能依赖 <code>this</code> 获取到这个组件的实例。<br>在组件装载之后,这个方法缓存的结果会用来保证访问 <code>this.props</code> 的属性时,当这个属性没有在父组件中传入(在这个组件的 JSX 属性里设置),也总是有值的。</p><p>如果是使用 ES6 语法,可以直接定义 <code>defaultProps</code> 这个类属性来替代,这样能更直观的知道 <code>default props</code> 是预先定义好的对象值:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Counter.defaultProps = { <span class="attr">initialCount</span>: <span class="number">0</span> }</span><br></pre></td></tr></table></figure><h5 id="componentWillMount"><a href="#componentWillMount" class="headerlink" title="componentWillMount()"></a>componentWillMount()</h5><p><code>componentWillMount()</code>只会在装载之前调用一次,在 <code>render</code> 之前调用,你可以在这个方法里面调用 <code>setState</code> 改变状态,并且不会导致额外调用一次 <code>render</code>。</p><h5 id="render"><a href="#render" class="headerlink" title="render()"></a>render()</h5><p>组装生成这个组件的 <code>HTML</code> 结构(使用原生 <code>HTML</code> 标签或者子组件),也可以返回 <code>null</code>或者 <code>false</code>,这时候 <code>ReactDOM.findDOMNode(this)</code> 会返回 <code>null</code>。</p><h5 id="componentDidMount"><a href="#componentDidMount" class="headerlink" title="componentDidMount()"></a>componentDidMount()</h5><p><code>componentDidMount()</code>在挂载结束之后马上被调用。只会在装载完成之后调用一次,在 render 之后调用,从这里开始可以通过 <code>ReactDOM.findDOMNode(this)</code> 获取到组件的 DOM 节点。</p><h3 id="更新组件触发"><a href="#更新组件触发" class="headerlink" title="更新组件触发"></a>更新组件触发</h3><h5 id="componentWillReceiveProps-object-nextProps"><a href="#componentWillReceiveProps-object-nextProps" class="headerlink" title="componentWillReceiveProps(object nextProps)"></a>componentWillReceiveProps(object nextProps)</h5><p>当一个挂载的组件接收到新的 props 的时候被调用。该方法应该用于比较<code>this.props</code>和<code>nextProps</code>,然后使用<code>this.setState()</code>来改变<code>state</code>。</p><p>在初始化渲染的时候,该方法不会调用。</p><figure class="highlight javascript"><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">componentWillReceiveProps: <span class="function"><span class="keyword">function</span>(<span class="params">nextProps</span>) </span>{</span><br><span class="line"> <span class="keyword">this</span>.setState({</span><br><span class="line"> likesIncreasing: nextProps.likeCount > <span class="keyword">this</span>.props.likeCount</span><br><span class="line"> });</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="shouldComponentUpdate-object-nextProps-object-nextState-boolean"><a href="#shouldComponentUpdate-object-nextProps-object-nextState-boolean" class="headerlink" title="shouldComponentUpdate(object nextProps, object nextState): boolean"></a>shouldComponentUpdate(object nextProps, object nextState): boolean</h5><p>当组件做出是否要更新 DOM 的决定的时候被调用。</p><p>在接收到新的 <code>props</code>或者 <code>state</code>,将要渲染之前调用。该方法在初始化渲染的时候不会调用,在使用 forceUpdate 方法的时候也不会。</p><p>如果确定新的 <code>props</code> 和 <code>state</code> 不会导致组件更新,则此处应该返回 <code>false</code>。</p><figure class="highlight javascript"><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">shouldComponentUpdate: <span class="function"><span class="keyword">function</span>(<span class="params">nextProps, nextState</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> nextProps.id !== <span class="keyword">this</span>.props.id;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>如果 <code>shouldComponentUpdate</code> 返回 <code>false</code>,则 <code>render()</code> 将不会执行,直到下一次 <code>state</code> 改变。</p><h5 id="componentWillUpdate-object-nextProps-object-nextState"><a href="#componentWillUpdate-object-nextProps-object-nextState" class="headerlink" title="componentWillUpdate(object nextProps, object nextState)"></a>componentWillUpdate(object nextProps, object nextState)</h5><p>在更新发生之前被调用。你可以在这里调用<code>this.setState()</code>。</p><h5 id="componentDidUpdate-object-prevProps-object-prevState"><a href="#componentDidUpdate-object-prevProps-object-prevState" class="headerlink" title="componentDidUpdate(object prevProps, object prevState)"></a>componentDidUpdate(object prevProps, object prevState)</h5><p>在更新发生之后调用。</p><h3 id="卸载组件触发"><a href="#卸载组件触发" class="headerlink" title="卸载组件触发"></a>卸载组件触发</h3><h5 id="componentWillUnmount"><a href="#componentWillUnmount" class="headerlink" title="componentWillUnmount()"></a>componentWillUnmount()</h5><p>在组件移除和销毁之前被调用。清理工作应该放在这里。比如无效的定时器,或者清除在 componentDidMount 中创建的 DOM 元素。</p><h3 id="装载的方法"><a href="#装载的方法" class="headerlink" title="装载的方法"></a>装载的方法</h3><h5 id="getDOMNode"><a href="#getDOMNode" class="headerlink" title="getDOMNode()"></a>getDOMNode()</h5><p>DOMElement 可以在任何挂载的组件上面调用,用于获取一个指向它的渲染 DOM 节点的引用。</p><h5 id="forceUpdate"><a href="#forceUpdate" class="headerlink" title="forceUpdate()"></a>forceUpdate()</h5><p>当你知道一些很深的组件 state 已经改变了的时候,可以在该组件上面调用,而不是使用<code>this.setState()</code>。</p><blockquote><p>完整实例展示</p></blockquote><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> Button = React.createClass({</span><br><span class="line"> getInitialState: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> {</span><br><span class="line"> data: <span class="number">0</span></span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> setNewNumber: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">this</span>.setState({ <span class="attr">data</span>: <span class="keyword">this</span>.state.data + <span class="number">1</span> })</span><br><span class="line"> },</span><br><span class="line"> render: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> (</span><br><span class="line"> <div></span><br><span class="line"> <button onClick={<span class="keyword">this</span>.setNewNumber}>INCREMENT<<span class="regexp">/button></span></span><br><span class="line"><span class="regexp"> <Content myNumber={this.state.data} /</span>></span><br><span class="line"> <<span class="regexp">/div></span></span><br><span class="line"><span class="regexp"> )</span></span><br><span class="line"><span class="regexp"> }</span></span><br><span class="line"><span class="regexp">})</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">var Content = React.createClass({</span></span><br><span class="line"><span class="regexp"> componentWillMount: function() {</span></span><br><span class="line"><span class="regexp"> console.log('Component WILL MOUNT!')</span></span><br><span class="line"><span class="regexp"> },</span></span><br><span class="line"><span class="regexp"> componentDidMount: function() {</span></span><br><span class="line"><span class="regexp"> console.log('Component DID MOUNT!')</span></span><br><span class="line"><span class="regexp"> },</span></span><br><span class="line"><span class="regexp"> componentWillReceiveProps: function(newProps) {</span></span><br><span class="line"><span class="regexp"> console.log('Component WILL RECIEVE PROPS!')</span></span><br><span class="line"><span class="regexp"> },</span></span><br><span class="line"><span class="regexp"> shouldComponentUpdate: function(newProps, newState) {</span></span><br><span class="line"><span class="regexp"> return true</span></span><br><span class="line"><span class="regexp"> },</span></span><br><span class="line"><span class="regexp"> componentWillUpdate: function(nextProps, nextState) {</span></span><br><span class="line"><span class="regexp"> console.log('Component WILL UPDATE!')</span></span><br><span class="line"><span class="regexp"> },</span></span><br><span class="line"><span class="regexp"> componentDidUpdate: function(prevProps, prevState) {</span></span><br><span class="line"><span class="regexp"> console.log('Component DID UPDATE!')</span></span><br><span class="line"><span class="regexp"> },</span></span><br><span class="line"><span class="regexp"> componentWillUnmount: function() {</span></span><br><span class="line"><span class="regexp"> console.log('Component WILL UNMOUNT!')</span></span><br><span class="line"><span class="regexp"> },</span></span><br><span class="line"><span class="regexp"> render: function() {</span></span><br><span class="line"><span class="regexp"> return (</span></span><br><span class="line"><span class="regexp"> <div></span></span><br><span class="line"><span class="regexp"> <h3>{this.props.myNumber}</</span>h3></span><br><span class="line"> <<span class="regexp">/div></span></span><br><span class="line"><span class="regexp"> )</span></span><br><span class="line"><span class="regexp"> }</span></span><br><span class="line"><span class="regexp">})</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">ReactDOM.render(</span></span><br><span class="line"><span class="regexp"> <div></span></span><br><span class="line"><span class="regexp"> <Button /</span>></span><br><span class="line"> <<span class="regexp">/div>,</span></span><br><span class="line"><span class="regexp"> document.getElementById('example')</span></span><br><span class="line"><span class="regexp">)</span></span><br></pre></td></tr></table></figure><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><table><thead><tr><th>生命周期</th><th>调用次数</th><th>能否使用 setSate()</th></tr></thead><tbody><tr><td>getDefaultProps</td><td>1(全局调用一次)</td><td>否</td></tr><tr><td>getInitialState</td><td>1</td><td>否</td></tr><tr><td>componentWillMount</td><td>1</td><td>是</td></tr><tr><td>render</td><td>>=1</td><td>否</td></tr><tr><td>componentDidMount</td><td>1</td><td>是</td></tr><tr><td>componentWillReceiveProps</td><td>>=0</td><td>是</td></tr><tr><td>shouldComponentUpdate</td><td>>=0</td><td>否</td></tr><tr><td>componentWillUpdate</td><td>>=0</td><td>否</td></tr><tr><td>componentDidUpdate</td><td>>=0</td><td>否</td></tr><tr><td>componentWillUnmount</td><td>1</td><td>否</td></tr></tbody></table>]]></content>
<summary type="html">
<p>组件的生命周期包含三个主要部分:</p>
<ul>
<li>挂载: 组件被插入到 DOM 中。</li>
<li>更新: 组件被重新渲染,查明 DOM 是否应该刷新。</li>
<li>移除: 组件从 DOM 中移除。</li>
</ul>
</summary>
<category term="react" scheme="https://lingmissing.github.io/tags/react/"/>
</entry>
<entry>
<title>react-router使用总结</title>
<link href="https://lingmissing.github.io/2016/08/16/react-router%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/"/>
<id>https://lingmissing.github.io/2016/08/16/react-router使用总结/</id>
<published>2016-08-16T03:40:19.000Z</published>
<updated>2019-01-04T03:40:48.142Z</updated>
<content type="html"><![CDATA[<blockquote><p><a href="https://github.com/reactjs/react-router/blob/master/docs/API.md" target="_blank" rel="noopener">react-router API</a></p></blockquote><h2 id="基本用法"><a href="#基本用法" class="headerlink" title="基本用法"></a>基本用法</h2><p>安装命令:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install -S react-router</span><br></pre></td></tr></table></figure><p>使用展示:</p><a id="more"></a><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { Router } <span class="keyword">from</span> <span class="string">'react-router'</span></span><br><span class="line">render(<span class="xml"><span class="tag"><<span class="name">Router</span> /></span>, document.getElementById('app'))</span></span><br></pre></td></tr></table></figure><p>Router 组件本身只是一个容器,真正的路由要通过 Route 组件定义。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { Router, Route, hashHistory } <span class="keyword">from</span> <span class="string">'react-router'</span></span><br><span class="line"></span><br><span class="line">render(</span><br><span class="line"> <Router history={hashHistory}></span><br><span class="line"> <Route path=<span class="string">"/"</span> component={App} /></span><br><span class="line"> <<span class="regexp">/Router>,</span></span><br><span class="line"><span class="regexp"> document.getElementById('app')</span></span><br><span class="line"><span class="regexp">)</span></span><br></pre></td></tr></table></figure><p>代码解释:</p><ul><li>用户访问根路由<code>/</code>(比如<code>http://www.example.com/</code>),组件<code>APP</code>就会加载到 document.getElementById(‘app’)。</li><li><code>Router</code>组件有一个参数<code>history</code>,它的值<code>hashHistory</code>表示,路由的切换由 URL 的<code>hash</code>变化决定,即 URL 的#部分发生变化。举例来说,用户访问<code>http://www.example.com/</code>,实际会看到的是<code>http://www.example.com/#/</code>。</li></ul><h2 id="嵌套路由"><a href="#嵌套路由" class="headerlink" title="嵌套路由"></a>嵌套路由</h2><p><code>Route</code>组件定义了 URL 路径与组件的对应关系。你可以同时使用多个 Route 组件。</p><figure class="highlight javascript"><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"><Router history={hashHistory}></span><br><span class="line"> <Route path=<span class="string">"/"</span> component={App} /></span><br><span class="line"> <Route path=<span class="string">"/repos"</span> component={Repos} /></span><br><span class="line"> <Route path=<span class="string">"/about"</span> component={About} /></span><br><span class="line"><<span class="regexp">/Router></span></span><br></pre></td></tr></table></figure><p>上面代码中,用户访问<code>/repos</code>时,会先加载<code>App</code>组件,然后在它的内部再加载<code>Repos</code>组件。</p><figure class="highlight javascript"><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"><App></span><br><span class="line"> <Repos /></span><br><span class="line"><<span class="regexp">/App></span></span><br></pre></td></tr></table></figure><p>App 组件要写成下面的样子。</p><figure class="highlight javascript"><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="keyword">export</span> <span class="keyword">default</span> React.createClass({</span><br><span class="line"> render() {</span><br><span class="line"> <span class="keyword">return</span> <span class="xml"><span class="tag"><<span class="name">div</span>></span>{this.props.children}<span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure><p>上面代码中,App 组件的<code>this.props.children</code>属性就是子组件。</p><p>子路由也可以不写在<code>Router</code>组件里面,单独传入<code>Router</code>组件的<code>routes</code>属性。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> routes = (</span><br><span class="line"> <Route path=<span class="string">"/"</span> component={App}></span><br><span class="line"> <Route path=<span class="string">"/repos"</span> component={Repos} /></span><br><span class="line"> <Route path=<span class="string">"/about"</span> component={About} /></span><br><span class="line"> <<span class="regexp">/Route></span></span><br><span class="line"><span class="regexp">)</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp">;<Router routes={routes} history={browserHistory} /</span>></span><br></pre></td></tr></table></figure><h2 id="path-属性"><a href="#path-属性" class="headerlink" title="path 属性"></a>path 属性</h2><p><code>Route</code>组件的<code>path</code>属性指定路由的匹配规则。这个属性是可以省略的,这样的话,不管路径是否匹配,总是会加载指定组件。</p><figure class="highlight javascript"><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"><Route path=<span class="string">"inbox"</span> component={Inbox}></span><br><span class="line"> <Route path=<span class="string">"messages/:id"</span> component={Message} /></span><br><span class="line"><<span class="regexp">/Route></span></span><br></pre></td></tr></table></figure><p>上面代码中,当用户访问<code>/inbox/messages/:id</code>时,会加载下面的组件。</p><p>如果省略外层<code>Route</code>的<code>path</code>参数,写成下面的样子。</p><figure class="highlight javascript"><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"><Route component={Inbox}></span><br><span class="line"> <Route path=<span class="string">"inbox/messages/:id"</span> component={Message} /></span><br><span class="line"><<span class="regexp">/Route></span></span><br></pre></td></tr></table></figure><h2 id="通配符"><a href="#通配符" class="headerlink" title="通配符"></a>通配符</h2><figure class="highlight javascript"><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"><Route path=<span class="string">"/hello/:name"</span>></span><br><span class="line"><span class="comment">// 匹配 /hello/michael</span></span><br><span class="line"><span class="comment">// 匹配 /hello/ryan</span></span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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"><Route path=<span class="string">"/hello(/:name)"</span>></span><br><span class="line"><span class="comment">// 匹配 /hello</span></span><br><span class="line"><span class="comment">// 匹配 /hello/michael</span></span><br><span class="line"><span class="comment">// 匹配 /hello/ryan</span></span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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"><Route path=<span class="string">"/files/*.*"</span>></span><br><span class="line"><span class="comment">// 匹配 /files/hello.jpg</span></span><br><span class="line"><span class="comment">// 匹配 /files/hello.html</span></span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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"><Route path=<span class="string">"/files/*"</span>></span><br><span class="line"><span class="comment">// 匹配 /files/</span></span><br><span class="line"><span class="comment">// 匹配 /files/a</span></span><br><span class="line"><span class="comment">// 匹配 /files/a/b</span></span><br></pre></td></tr></table></figure><p>通配符规则:</p><ul><li><code>:paramName</code>匹配 URL 的一个部分,直到遇到下一个/、?、#为止。这个路径参数可以通过 this.props.params.paramName 取出。</li><li><code>()</code>表示 URL 的这个部分是可选的。</li><li><code>*</code>匹配任意字符,直到模式里面的下一个字符为止。匹配方式是非贪婪模式。</li><li><code>**</code>匹配任意字符,直到下一个/、?、#为止。匹配方式是贪婪模式。</li></ul><h2 id="常用组件"><a href="#常用组件" class="headerlink" title="常用组件"></a>常用组件</h2><h4 id="IndexRoute"><a href="#IndexRoute" class="headerlink" title="IndexRoute"></a>IndexRoute</h4><p>上面的代码会发现访问根路径会加载不到子组件。<code>IndexRoute</code>就是解决这个问题,显式指定<code>Home</code>是根路由的子组件,即指定默认情况下加载的子组件。你可以把<code>IndexRoute</code>想象成某个路径的 index.html。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><Router></span><br><span class="line"> <Route path=<span class="string">"/"</span> component={App}></span><br><span class="line"> <IndexRoute component={Home} /></span><br><span class="line"> <Route path=<span class="string">"accounts"</span> component={Accounts} /></span><br><span class="line"> <Route path=<span class="string">"statements"</span> component={Statements} /></span><br><span class="line"> <<span class="regexp">/Route></span></span><br><span class="line"><span class="regexp"></</span>Router></span><br></pre></td></tr></table></figure><blockquote><p><code>IndexRoute</code>组件没有路径参数<code>path</code>。</p></blockquote><h4 id="Redirect"><a href="#Redirect" class="headerlink" title="Redirect"></a>Redirect</h4><p><code><Redirect></code>组件用于路由的跳转,即用户访问一个路由,会自动跳转到另一个路由。</p><figure class="highlight javascript"><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"><Route path=<span class="string">"inbox"</span> component={Inbox}></span><br><span class="line"> {<span class="comment">/* 从 /inbox/messages/:id 跳转到 /messages/:id */</span>}</span><br><span class="line"> <Redirect <span class="keyword">from</span>=<span class="string">"messages/:id"</span> to=<span class="string">"/messages/:id"</span> /></span><br><span class="line"><<span class="regexp">/Route></span></span><br></pre></td></tr></table></figure><h4 id="IndexRedirect"><a href="#IndexRedirect" class="headerlink" title="IndexRedirect"></a>IndexRedirect</h4><p><code>IndexRedirect</code>组件用于访问根路由的时候,将用户重定向到某个子组件。</p><figure class="highlight javascript"><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"><Route path=<span class="string">"/"</span> component={App}></span><br><span class="line"> <IndexRedirect to=<span class="string">"/welcome"</span> /></span><br><span class="line"> <Route path=<span class="string">"welcome"</span> component={Welcome} /></span><br><span class="line"> <Route path=<span class="string">"about"</span> component={About} /></span><br><span class="line"><<span class="regexp">/Route></span></span><br></pre></td></tr></table></figure><h4 id="RouterContext"><a href="#RouterContext" class="headerlink" title="RouterContext"></a>RouterContext</h4><ul><li><p>push(pathOrLoc)</p><pre><code><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">router.push(<span class="string">'/users/12'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// or with a location descriptor object</span></span><br><span class="line">router.push({</span><br><span class="line"> pathname: <span class="string">'/users/12'</span>,</span><br><span class="line"> query: { <span class="attr">modal</span>: <span class="literal">true</span> },</span><br><span class="line"> state: { <span class="attr">fromDashboard</span>: <span class="literal">true</span> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure></code></pre></li><li><p>replace(pathOrLoc)</p></li><li>go(n)</li><li>goBack()</li><li>goForward()</li><li>setRouteLeaveHook(route, hook)</li></ul><h2 id="Link"><a href="#Link" class="headerlink" title="Link"></a>Link</h2><p><code>Link</code>组件用于取代<code><a></code>元素,生成一个链接,允许用户点击后跳转到另一个路由。它基本上就是<code><a></code>元素的<code>React 版本,可以接收Router</code>的状态。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">render() {</span><br><span class="line"> <span class="keyword">return</span> <span class="xml"><span class="tag"><<span class="name">div</span>></span></span></span><br><span class="line"> <ul role="nav"></span><br><span class="line"> <li><Link to="/about">About</Link></li></span><br><span class="line"> <li><Link to="/repos">Repos</Link></li></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">ul</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>如果希望当前的路由与其他路由有不同样式,这时可以使用<code>Link</code>组件的<code>activeStyle</code>属性</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><Link to=<span class="string">"/about"</span> activeStyle={{<span class="attr">color</span>: <span class="string">'red'</span>}}>About<<span class="regexp">/Link></span></span><br><span class="line"><span class="regexp"><Link to="/</span>repos<span class="string">" activeStyle={{color: 'red'}}>Repos</Link></span></span><br></pre></td></tr></table></figure><p>另一种做法是,使用<code>activeClassName</code>指定当前路由的<code>Class</code>。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><Link to=<span class="string">"/about"</span> activeClassName=<span class="string">"active"</span>>About<<span class="regexp">/Link></span></span><br><span class="line"><span class="regexp"><Link to="/</span>repos<span class="string">" activeClassName="</span>active<span class="string">">Repos</Link></span></span><br></pre></td></tr></table></figure><h2 id="IndexLink"><a href="#IndexLink" class="headerlink" title="IndexLink"></a>IndexLink</h2><p>如果链接到根路由<code>/</code>,不要使用<code>Link</code>组件,而要使用<code>IndexLink</code>组件。</p><p>这是因为对于根路由来说,<code>activeStyle</code>和<code>activeClassName</code>会失效,或者说总是生效,因为<code>/</code>会匹配任何子路由。而 IndexLink 组件会使用路径的精确匹配。</p><figure class="highlight javascript"><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"><IndexLink to=<span class="string">"/"</span> activeClassName=<span class="string">"active"</span>></span><br><span class="line"> Home</span><br><span class="line"><<span class="regexp">/IndexLink></span></span><br></pre></td></tr></table></figure><p>另一种方法是使用<code>Link</code>组件的<code>onlyActiveOnIndex</code>属性,也能达到同样效果。</p><figure class="highlight javascript"><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"><Link to=<span class="string">"/"</span> activeClassName=<span class="string">"active"</span> onlyActiveOnIndex={<span class="literal">true</span>}></span><br><span class="line"> Home</span><br><span class="line"><<span class="regexp">/Link></span></span><br></pre></td></tr></table></figure><p>实际上,<code>IndexLink</code>就是对<code>Link</code>组件的<code>onlyActiveOnIndex</code>属性的包装。</p><h2 id="history"><a href="#history" class="headerlink" title="history"></a>history</h2><p><code>Router</code>组件的<code>history</code>属性,用来监听浏览器地址栏的变化,并将 URL 解析成一个地址对象,供 React Router 匹配。</p><ul><li><code>hashHistory</code> - 如果设为<code>hashHistory</code>,路由将通过 URL 的 hash 部分(#)切换,URL 的形式类似 example.com/#/some/path。</li><li><code>browserHistory</code> - 如果设为<code>browserHistory</code>,浏览器的路由就不再通过 Hash 完成了,而显示正常的路径 example.com/some/path,背后调用的是浏览器的 History API - 种情况需要对服务器改造。否则用户直接向服务器请求某个子路由,会显示网页找不到的 404 错误。</li><li><code>createMemoryHistory</code> - <code>createMemoryHistory</code>主要用于服务器渲染。它创建一个内存中的 history 对象,不与浏览器 URL 互动。<br><code>javascript const history = createMemoryHistory(location)</code></li><li><code>useRouterHistory(createHistory)</code></li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> createHashHistory <span class="keyword">from</span> <span class="string">'history/lib/createHashHistory'</span></span><br><span class="line"><span class="keyword">const</span> history = useRouterHistory(createHashHistory)({ <span class="attr">queryKey</span>: <span class="literal">false</span> })</span><br></pre></td></tr></table></figure><h2 id="表单处理"><a href="#表单处理" class="headerlink" title="表单处理"></a>表单处理</h2><p><code>Link</code>组件用于正常的用户点击跳转,但是有时还需要表单跳转、点击按钮跳转等操作。这些情况怎么跟 React Router 对接呢?</p><figure class="highlight javascript"><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"><form onSubmit={<span class="keyword">this</span>.handleSubmit}></span><br><span class="line"> <input type=<span class="string">"text"</span> placeholder=<span class="string">"userName"</span> /></span><br><span class="line"> <input type=<span class="string">"text"</span> placeholder=<span class="string">"repo"</span> /></span><br><span class="line"> <button type=<span class="string">"submit"</span>>Go<<span class="regexp">/button></span></span><br><span class="line"><span class="regexp"></</span>form></span><br></pre></td></tr></table></figure><p>第一种方法是使用<code>browserHistory.push</code></p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { browserHistory } <span class="keyword">from</span> <span class="string">'react-router'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// ...</span></span><br><span class="line"> handleSubmit(event) {</span><br><span class="line"> event.preventDefault()</span><br><span class="line"> <span class="keyword">const</span> userName = event.target.elements[<span class="number">0</span>].value</span><br><span class="line"> <span class="keyword">const</span> repo = event.target.elements[<span class="number">1</span>].value</span><br><span class="line"> <span class="keyword">const</span> path = <span class="string">`/repos/<span class="subst">${userName}</span>/<span class="subst">${repo}</span>`</span></span><br><span class="line"> browserHistory.push(path)</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>第二种方法是使用<code>context</code>对象。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> React.createClass({</span><br><span class="line"> <span class="comment">// ask for `router` from context</span></span><br><span class="line"> contextTypes: {</span><br><span class="line"> router: React.PropTypes.object</span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line"> handleSubmit(event) {</span><br><span class="line"> <span class="comment">// ...</span></span><br><span class="line"> <span class="keyword">this</span>.context.router.push(path)</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure><h2 id="常见配置方案"><a href="#常见配置方案" class="headerlink" title="常见配置方案"></a>常见配置方案</h2><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">React.render(</span><br><span class="line"> <Router></span><br><span class="line"> <Route path=<span class="string">"/"</span> component={App}></span><br><span class="line"> <Route path=<span class="string">"about"</span> component={About} /></span><br><span class="line"> <Route path=<span class="string">"inbox"</span> component={Inbox}></span><br><span class="line"> <Route path=<span class="string">"messages/:id"</span> component={Message} /></span><br><span class="line"> <<span class="regexp">/Route></span></span><br><span class="line"><span class="regexp"> </</span>Route></span><br><span class="line"> <<span class="regexp">/Router>,</span></span><br><span class="line"><span class="regexp"> document.body</span></span><br><span class="line"><span class="regexp">)</span></span><br></pre></td></tr></table></figure><table><thead><tr><th>URL</th><th>组件</th></tr></thead><tbody><tr><td>/</td><td>APP</td></tr><tr><td>/about</td><td>App -> About</td></tr><tr><td>/inbox</td><td>App -> Inbox</td></tr><tr><td>/inbox/messages/:id</td><td>App -> Inbox -> Message</td></tr></tbody></table><h4 id="添加首页"><a href="#添加首页" class="headerlink" title="添加首页"></a>添加首页</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">React.render(</span><br><span class="line"> <Router></span><br><span class="line"> <Route path=<span class="string">"/"</span> component={App}></span><br><span class="line"> {<span class="comment">/* 当 url 为/时渲染 Dashboard */</span>}</span><br><span class="line"> <IndexRoute component={Dashboard} /></span><br><span class="line"> <Route path=<span class="string">"about"</span> component={About} /></span><br><span class="line"> <Route path=<span class="string">"inbox"</span> component={Inbox}></span><br><span class="line"> <Route path=<span class="string">"messages/:id"</span> component={Message} /></span><br><span class="line"> <<span class="regexp">/Route></span></span><br><span class="line"><span class="regexp"> </</span>Route></span><br><span class="line"> <<span class="regexp">/Router>,</span></span><br><span class="line"><span class="regexp"> document.body</span></span><br><span class="line"><span class="regexp">)</span></span><br></pre></td></tr></table></figure><table><thead><tr><th>URL</th><th>组件</th></tr></thead><tbody><tr><td>/</td><td>App -> Dashboard</td></tr><tr><td>/about</td><td>App -> About</td></tr><tr><td>/inbox</td><td>App -> Inbox</td></tr><tr><td>/inbox/messages/:id</td><td>App -> Inbox -> Message</td></tr></tbody></table><h4 id="让-UI-从-URL-中解耦出来"><a href="#让-UI-从-URL-中解耦出来" class="headerlink" title="让 UI 从 URL 中解耦出来"></a>让 UI 从 URL 中解耦出来</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">React.render(</span><br><span class="line"> <Router></span><br><span class="line"> <Route path=<span class="string">"/"</span> component={App}></span><br><span class="line"> <IndexRoute component={Dashboard} /></span><br><span class="line"> <Route path=<span class="string">"about"</span> component={About} /></span><br><span class="line"> <Route path=<span class="string">"inbox"</span> component={Inbox}></span><br><span class="line"> {<span class="comment">/* 使用 /messages/:id 替换 messages/:id */</span>}</span><br><span class="line"> <Route path=<span class="string">"/messages/:id"</span> component={Message} /></span><br><span class="line"> <<span class="regexp">/Route></span></span><br><span class="line"><span class="regexp"> </</span>Route></span><br><span class="line"> <<span class="regexp">/Router>,</span></span><br><span class="line"><span class="regexp"> document.body</span></span><br><span class="line"><span class="regexp">)</span></span><br></pre></td></tr></table></figure><table><thead><tr><th>URL</th><th>组件</th></tr></thead><tbody><tr><td>/</td><td>App -> Dashboard</td></tr><tr><td>/about</td><td>App -> About</td></tr><tr><td>/inbox</td><td>App -> Inbox</td></tr><tr><td>/messages/:id</td><td>App -> Inbox -> Message</td></tr></tbody></table><h4 id="兼容旧的-URL"><a href="#兼容旧的-URL" class="headerlink" title="兼容旧的 URL"></a>兼容旧的 URL</h4><p>现在任何人访问 /inbox/messages/5 都会看到一个错误页面。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { Redirect } <span class="keyword">from</span> <span class="string">'react-router'</span></span><br><span class="line"></span><br><span class="line">React.render(</span><br><span class="line"> <Router></span><br><span class="line"> <Route path=<span class="string">"/"</span> component={App}></span><br><span class="line"> <IndexRoute component={Dashboard} /></span><br><span class="line"> <Route path=<span class="string">"about"</span> component={About} /></span><br><span class="line"> <Route path=<span class="string">"inbox"</span> component={Inbox}></span><br><span class="line"> <Route path=<span class="string">"/messages/:id"</span> component={Message} /></span><br><span class="line"></span><br><span class="line"> {<span class="comment">/* 跳转 /inbox/messages/:id 到 /messages/:id */</span>}</span><br><span class="line"> <Redirect <span class="keyword">from</span>=<span class="string">"messages/:id"</span> to=<span class="string">"/messages/:id"</span> /></span><br><span class="line"> <<span class="regexp">/Route></span></span><br><span class="line"><span class="regexp"> </</span>Route></span><br><span class="line"> <<span class="regexp">/Router>,</span></span><br><span class="line"><span class="regexp"> document.body</span></span><br><span class="line"><span class="regexp">)</span></span><br></pre></td></tr></table></figure><h4 id="替换的配置方式"><a href="#替换的配置方式" class="headerlink" title="替换的配置方式"></a>替换的配置方式</h4><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> routeConfig = [</span><br><span class="line"> {</span><br><span class="line"> path: <span class="string">'/'</span>,</span><br><span class="line"> component: App,</span><br><span class="line"> indexRoute: { <span class="attr">component</span>: Dashboard },</span><br><span class="line"> childRoutes: [</span><br><span class="line"> { <span class="attr">path</span>: <span class="string">'about'</span>, <span class="attr">component</span>: About },</span><br><span class="line"> {</span><br><span class="line"> path: <span class="string">'inbox'</span>,</span><br><span class="line"> component: Inbox,</span><br><span class="line"> childRoutes: [</span><br><span class="line"> { <span class="attr">path</span>: <span class="string">'/messages/:id'</span>, <span class="attr">component</span>: Message },</span><br><span class="line"> {</span><br><span class="line"> path: <span class="string">'messages/:id'</span>,</span><br><span class="line"> onEnter: <span class="function"><span class="keyword">function</span>(<span class="params">nextState, replaceState</span>) </span>{</span><br><span class="line"> replaceState(<span class="literal">null</span>, <span class="string">'/messages/'</span> + nextState.params.id)</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><br><span class="line"> }</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line">React.render(<span class="xml"><span class="tag"><<span class="name">Router</span> <span class="attr">routes</span>=<span class="string">{routeConfig}</span> /></span>, document.body)</span></span><br></pre></td></tr></table></figure><blockquote><p>转载自<a href="http://www.ruanyifeng.com/blog/2016/05/react_router.html" target="_blank" rel="noopener">react router 使用教程</a></p></blockquote>]]></content>
<summary type="html">
<blockquote>
<p><a href="https://github.com/reactjs/react-router/blob/master/docs/API.md" target="_blank" rel="noopener">react-router API</a></p>
</blockquote>
<h2 id="基本用法"><a href="#基本用法" class="headerlink" title="基本用法"></a>基本用法</h2><p>安装命令:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install -S react-router</span><br></pre></td></tr></table></figure>
<p>使用展示:</p>
</summary>
<category term="react" scheme="https://lingmissing.github.io/tags/react/"/>
<category term="react-router" scheme="https://lingmissing.github.io/tags/react-router/"/>
</entry>
<entry>
<title>angularJs之过滤器</title>
<link href="https://lingmissing.github.io/2016/07/14/angularJs%E4%B9%8B%E8%BF%87%E6%BB%A4%E5%99%A8/"/>
<id>https://lingmissing.github.io/2016/07/14/angularJs之过滤器/</id>
<published>2016-07-14T02:12:06.000Z</published>
<updated>2019-01-04T03:36:10.059Z</updated>
<content type="html"><![CDATA[<h3 id="filter的使用方法"><a href="#filter的使用方法" class="headerlink" title="filter的使用方法"></a>filter的使用方法</h3><ul><li>在模板中使用<code>filter</code></li></ul><p>我们可以直接使用<code>filter</code>,跟在表达式后面用 | 分割</p><pre><code>{{ expression | filter }}</code></pre><p>也可以多个<code>filter</code>连用,上一个<code>filter</code>的输出将作为下一个<code>filter</code>的输入</p><a id="more"></a><pre><code>{{ expression | filter1 | filter2 | ... }}</code></pre><p><code>filter</code>可以接收参数,参数用 : 进行分割</p><pre><code>{{ expression | filter:argument1:argument2:... }}</code></pre><p>除了对数据进行格式化,我们还可以在指令中使用<code>filter</code>,例如先对数组<code>array</code>进行过滤处理,然后再循环输出:</p><pre><code><span ng-repeat="a in array | filter "></code></pre><ul><li>在<code>controller</code>和<code>service</code>中使用<code>filter</code></li></ul><p>我们的js代码中也可以使用过滤器,方式就是我们熟悉的依赖注入,例如我要在<code>controller</code>中使用<code>currency</code>过滤器,只需将它注入到该<code>controller</code>中即可,代码如下:</p><figure class="highlight javascript"><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">app.controller(<span class="string">'testC'</span>,<span class="function"><span class="keyword">function</span>(<span class="params">$scope,currencyFilter</span>)</span>{</span><br><span class="line"> $scope.num = currencyFilter(<span class="number">123534</span>); </span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>在模板中使用<code></code>就可以直接输出$123,534.00了!在服务中使用<code>filter</code>也是同样的道理。</p><p>此时你可能会有疑惑,如果我要在<code>controller</code>中使用多个<code>filter</code>,难道要一个一个注入吗?ng提供了一个<code>$filter</code>服务可以来调用所需的<code>filter</code>,你只需注入一个<code>$filter</code>就够了,使用方法如下:</p><figure class="highlight javascript"><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">app.controller(<span class="string">'testC'</span>,<span class="function"><span class="keyword">function</span>(<span class="params">$scope,$filter</span>)</span>{</span><br><span class="line"> $scope.num = $filter(<span class="string">'currency'</span>)(<span class="number">123534</span>);</span><br><span class="line"> $scope.date = $filter(<span class="string">'date'</span>)(<span class="keyword">new</span> <span class="built_in">Date</span>()); </span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="内置过滤器"><a href="#内置过滤器" class="headerlink" title="内置过滤器"></a>内置过滤器</h3><ul><li><code>currency</code> (货币处理)</li></ul><p>使用<code>currency</code>可以将数字格式化为货币,默认是美元符号,你可以自己传入所需的符号,例如我传入人民币:</p><pre><code>{{num | currency : '¥'}}</code></pre><ul><li><code>date</code> (日期格式化)</li></ul><p>原生的js对日期的格式化能力有限,ng提供的date过滤器基本可以满足一般的格式化要求。用法如下:</p><pre><code>{{date | date : 'yyyy-MM-dd hh:mm:ss EEEE'}}</code></pre><p> 参数用来指定所要的格式,y M d h m s E 分别表示 年 月 日 时 分 秒 星期,你可以自由组合它们。也可以使用不同的个数来限制格式化的位数。另外参数也可以使用特定的描述性字符串,例如“shortTime”将会把时间格式为12:05 pm这样的。ng提供了八种描述性的字符串,个人觉得这些有点多余,我完全可以根据自己的意愿组合出想要的格式,不愿意去记这么多单词~</p><ul><li><code>filter</code>(匹配子串)</li></ul><p> 这个名叫<code>filter</code>的<code>filter</code>(不得不说这名字起的,真让人容易混淆——!)用来处理一个数组,然后可以过滤出含有某个子串的元素,作为一个子数组来返回。可以是字符串数组,也可以是对象数组。如果是对象数组,可以匹配属性的值。它接收一个参数,用来定义子串的匹配规则。下面举个例子说明一下参数的用法,我用现在特别火的几个孩子定义了一个数组:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">$scope.childrenArray = [</span><br><span class="line"> {<span class="attr">name</span>:<span class="string">'kimi'</span>,<span class="attr">age</span>:<span class="number">3</span>},</span><br><span class="line"> {<span class="attr">name</span>:<span class="string">'cindy'</span>,<span class="attr">age</span>:<span class="number">4</span>},</span><br><span class="line"> {<span class="attr">name</span>:<span class="string">'anglar'</span>,<span class="attr">age</span>:<span class="number">4</span>},</span><br><span class="line"> {<span class="attr">name</span>:<span class="string">'shitou'</span>,<span class="attr">age</span>:<span class="number">6</span>},</span><br><span class="line"> {<span class="attr">name</span>:<span class="string">'tiantian'</span>,<span class="attr">age</span>:<span class="number">5</span>}</span><br><span class="line"> ];</span><br><span class="line">$scope.func = <span class="function"><span class="keyword">function</span>(<span class="params">e</span>)</span>{<span class="keyword">return</span> e.age><span class="number">4</span>;}</span><br><span class="line"></span><br><span class="line">{{ childrenArray | filter : <span class="string">'a'</span> }} <span class="comment">//匹配属性值中含有a的</span></span><br><span class="line">{{ childrenArray | filter : <span class="number">4</span> }} <span class="comment">//匹配属性值中含有4的</span></span><br><span class="line">{{ childrenArray | filter : {<span class="attr">name</span> : <span class="string">'i'</span>} }} <span class="comment">//参数是对象,匹配name属性中含有i的</span></span><br><span class="line">{{childrenArray | filter : func }} <span class="comment">//参数是函数,指定返回age>4的</span></span><br></pre></td></tr></table></figure><ul><li><code>json</code>(格式化json对象)</li></ul><p> <code>json</code>过滤器可以把一个js对象格式化为<code>json</code>字符串,没有参数。这东西有什么用呢,我一般也不会在页面上输出一个json串啊,官网说它可以用来进行调试,嗯,是个不错的选择。或者,也可以用在js中使用,作用就和我们熟悉的<code>JSON.stringify()</code>一样。用法超级简单:</p><pre><code>{{ jsonTest | json}}</code></pre><ul><li><code>limitTo</code>(限制数组长度或字符串长度)</li></ul><p> <code>limitTo</code>过滤器用来截取数组或字符串,接收一个参数用来指定截取的长度,如果参数是负值,则从数组尾部开始截取。个人觉得这个<code>filter</code>有点鸡肋,首先只能从数组或字符串的开头/尾部进行截取,其次,js原生的函数就可以代替它了,看看怎么用吧:</p><pre><code>{{ childrenArray | limitTo : 2 }} //将会显示数组中的前两项</code></pre><ul><li><code>lowercase</code>(小写)</li></ul><p> 把数据转化为全部小写。太简单了,不多解释。同样是很鸡肋的一个filter,没有参数,只能把整个字符串变为小写,不能指定字母。</p><ul><li><p><code>uppercase</code>(大写)<br> 同上。</p></li><li><p><code>number</code>(格式化数字)</p></li></ul><p> <code>number</code>过滤器可以为一个数字加上千位分割,像这样,123,456,789。同时接收一个参数,可以指定float类型保留几位小数:</p><pre><code>{{ num | number : 2 }}</code></pre><ul><li><code>orderBy</code>(排序)</li></ul><p> <code>orderBy</code>过滤器可以将一个数组中的元素进行排序,接收一个参数来指定排序规则,参数可以是一个字符串,表示以该属性名称进行排序。可以是一个函数,定义排序属性。还可以是一个数组,表示依次按数组中的属性值进行排序(若按第一项比较的值相等,再按第二项比较),还是拿上面的孩子数组举例:</p><figure class="highlight html"><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="tag"><<span class="name">div</span>></span>{{ childrenArray | orderBy : 'age' }}<span class="tag"></<span class="name">div</span>></span> //按age属性值进行排序,若是-age,则倒序</span><br><span class="line"><span class="tag"><<span class="name">div</span>></span>{{ childrenArray | orderBy : orderFunc }}<span class="tag"></<span class="name">div</span>></span> //按照函数的返回值进行排序</span><br><span class="line"><span class="tag"><<span class="name">div</span>></span>{{ childrenArray | orderBy : ['age','name'] }}<span class="tag"></<span class="name">div</span>></span> //如果age相同,按照name进行排序</span><br></pre></td></tr></table></figure><p> </p><h3 id="自定义过滤器"><a href="#自定义过滤器" class="headerlink" title="自定义过滤器"></a>自定义过滤器</h3><p>filter的自定义方式也很简单,使用<code>module</code>的<code>filter</code>方法,返回一个函数,该函数接收输入值,并返回处理后的结果。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line">app.filter(<span class="string">'odditems'</span>,<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">inputArray</span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> array = [];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i<inputArray.length;i++){</span><br><span class="line"> <span class="keyword">if</span>(i%<span class="number">2</span>!==<span class="number">0</span>){</span><br><span class="line"> array.push(inputArray[i]);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> array;</span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure><p>格式就是这样,你的处理逻辑就写在内部的那个闭包函数中。你也可以让自己的过滤器接收参数,参数就定义在<code>return</code>的那个函数中,作为第二个参数,或者更多个参数也可以。</p><p>下面看一个完整案例:</p><figure class="highlight html"><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="tag"><<span class="name">div</span> <span class="attr">ng-controller</span>=<span class="string">"myAppCtrl"</span>></span></span><br><span class="line"> name:{{ name }}<span class="tag"><<span class="name">br</span>></span></span><br><span class="line"> reverse name:{{ name | reverse }}<span class="tag"><<span class="name">br</span>></span></span><br><span class="line"> reverse&uppercase name:{{ name | reverse:true }}</span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myAppModule = angular.module(<span class="string">"myApp"</span>,[]);</span><br><span class="line"></span><br><span class="line">myAppModule.controller(<span class="string">"myAppCtrl"</span>,[<span class="string">"$scope"</span>,<span class="function"><span class="keyword">function</span>(<span class="params">$scope</span>)</span>{</span><br><span class="line"> $scope.name = <span class="string">"xingoo"</span>;</span><br><span class="line">}]);</span><br><span class="line"></span><br><span class="line">myAppModule.filter(<span class="string">"reverse"</span>,<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">input,uppercase</span>)</span>{</span><br><span class="line"> <span class="keyword">var</span> out = <span class="string">""</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span> ; i<input.length; i++){</span><br><span class="line"> out = input.charAt(i)+out;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(uppercase){</span><br><span class="line"> out = out.toUpperCase();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> out;</span><br><span class="line"> }</span><br><span class="line">});</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h3 id="filter的使用方法"><a href="#filter的使用方法" class="headerlink" title="filter的使用方法"></a>filter的使用方法</h3><ul>
<li>在模板中使用<code>filter</code></li>
</ul>
<p>我们可以直接使用<code>filter</code>,跟在表达式后面用 | 分割</p>
<pre><code>{{ expression | filter }}
</code></pre><p>也可以多个<code>filter</code>连用,上一个<code>filter</code>的输出将作为下一个<code>filter</code>的输入</p>
</summary>
<category term="angular" scheme="https://lingmissing.github.io/tags/angular/"/>
</entry>
</feed>