-
Notifications
You must be signed in to change notification settings - Fork 1
/
feed.xml
1445 lines (1137 loc) · 173 KB
/
feed.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
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Elegenthus's blog</title>
<link>https://Elegenthus.github.io/</link>
<description>Recent content on Elegenthus's blog</description>
<generator>Hugo -- gohugo.io</generator>
<language>zh-CN</language>
<lastBuildDate>Sat, 15 Jul 2017 15:57:22 +0800</lastBuildDate>
<atom:link href="https://Elegenthus.github.io/feed/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>桂声前端部署踩坑之旅</title>
<link>https://elegenthus.github.io/post/deploy/</link>
<pubDate>Sat, 15 Jul 2017 15:57:22 +0800</pubDate>
<guid>https://elegenthus.github.io/post/deploy/</guid>
<description>
<p>这两天试着将<a href="https://github.com/hdgs/guisheng_fe">华大桂声的前端代码</a>部署到服务器上,短短几句代码居然历时两天,谨以此文记录两天以来踩的大大小小的坑。</p>
<hr />
<h2 id="本地构建镜像:0814af543608f4fd171b2e9cf43d9917">本地构建镜像</h2>
<p>在将node应用部署到服务器上之前,首先在本地尝试构建docker镜像,这主要是为了检查部署代码是否存在问题</p>
<h3 id="1-1-安装docker:0814af543608f4fd171b2e9cf43d9917">1.1 安装docker</h3>
<p><a href="https://brew.sh">Homebrew</a> 的 <a href="https://caskroom.github.io">Cask</a> 已经支持 Docker for Mac,因此可以很方便的使用 Homebrew Cask 来进行安装:
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">brew</span> <span class="nx">cask</span> <span class="nx">install</span> <span class="nx">docker</span>
</code></pre></div>
</p>
<h3 id="1-2-创建node应用:0814af543608f4fd171b2e9cf43d9917">1.2 创建node应用</h3>
<h4 id="1-2-1-package-json:0814af543608f4fd171b2e9cf43d9917">1.2.1 package.json</h4>
<p>在项目根目录下创建<code>server</code>文件夹,接着在<code>server</code>目录下创建<code>package.json</code>,以定义node应用中所需要的各种模块以及相关的配置信息,可用<code>npm init</code>进行交互式问答生成,这里给出其中部分信息
<div class="highlight"><pre><code class="language-JSON" data-lang="JSON"><span></span><span class="p">{</span>
<span class="nt">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;guisheng&quot;</span><span class="p">,</span>
<span class="nt">&quot;version&quot;</span><span class="p">:</span> <span class="s2">&quot;1.0.0&quot;</span><span class="p">,</span>
<span class="nt">&quot;description&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="nt">&quot;main&quot;</span><span class="p">:</span> <span class="s2">&quot;index.js&quot;</span><span class="p">,</span>
<span class="nt">&quot;scripts&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;start&quot;</span><span class="p">:</span> <span class="s2">&quot;node index.js&quot;</span><span class="p">,</span>
<span class="nt">&quot;test&quot;</span><span class="p">:</span> <span class="s2">&quot;echo \&quot;Error: no test specified\&quot; &amp;&amp; exit 1&quot;</span><span class="p">,</span>
<span class="nt">&quot;build&quot;</span><span class="p">:</span> <span class="s2">&quot;rm -rf dist/* &amp;&amp; webpack --config webpack.build.config.js&quot;</span>
<span class="p">},</span>
<span class="err">...</span>
<span class="nt">&quot;dependencies&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="nt">&quot;koa&quot;</span><span class="p">:</span> <span class="s2">&quot;^2.2.0&quot;</span><span class="p">,</span>
<span class="nt">&quot;koa-router&quot;</span><span class="p">:</span> <span class="s2">&quot;^7.2.0&quot;</span><span class="p">,</span>
<span class="nt">&quot;koa-send&quot;</span><span class="p">:</span> <span class="s2">&quot;^4.1.0&quot;</span><span class="p">,</span>
<span class="nt">&quot;koa-useragent&quot;</span><span class="p">:</span> <span class="s2">&quot;^1.0.0&quot;</span><span class="p">,</span>
<span class="nt">&quot;swig&quot;</span><span class="p">:</span> <span class="s2">&quot;^1.4.2&quot;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h4 id="1-2-2-node-js:0814af543608f4fd171b2e9cf43d9917">1.2.2 node.js</h4>
<p>然后在node.js文件中实现View层(传统后端MVC中的View),主要负责渲染同步路由的模板。此处选用koa2作为Web框架,部分代码如下:</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">const</span> <span class="nx">send</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koa-send&#39;</span><span class="p">);</span>
<span class="kr">const</span> <span class="nx">Koa</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koa&#39;</span><span class="p">);</span>
<span class="kr">const</span> <span class="nx">Router</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koa-router&#39;</span><span class="p">);</span>
<span class="kr">const</span> <span class="nx">userAgent</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;koa-useragent&#39;</span><span class="p">);</span>
<span class="kr">const</span> <span class="nx">path</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;path&#39;</span><span class="p">)</span>
<span class="kr">const</span> <span class="nx">swig</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;swig&#39;</span><span class="p">);</span>
<span class="kr">const</span> <span class="nx">router</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Router</span><span class="p">();</span>
<span class="kr">const</span> <span class="nx">app</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Koa</span><span class="p">();</span>
<span class="c1">//HTML文件位于../dist/template中</span>
<span class="kr">const</span> <span class="nx">templateRoot</span> <span class="o">=</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span> <span class="s2">&quot;../dist/template&quot;</span><span class="p">)</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">userAgent</span><span class="p">);</span>
<span class="nx">router</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="nx">next</span><span class="p">){</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">ctx</span><span class="p">.</span><span class="nx">userAgent</span><span class="p">)</span>
<span class="kd">let</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">swig</span><span class="p">.</span><span class="nx">compileFile</span><span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">templateRoot</span><span class="p">,</span> <span class="s2">&quot;index.html&quot;</span><span class="p">));</span>
<span class="nx">ctx</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">template</span><span class="p">({})</span>
<span class="p">});</span>
<span class="nx">router</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/profile/:id&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="nx">next</span><span class="p">){</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">ctx</span><span class="p">.</span><span class="nx">userAgent</span><span class="p">)</span>
<span class="kd">let</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">swig</span><span class="p">.</span><span class="nx">compileFile</span><span class="p">(</span><span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">templateRoot</span><span class="p">,</span> <span class="s2">&quot;profile.html&quot;</span><span class="p">));</span>
<span class="nx">ctx</span><span class="p">.</span><span class="nx">body</span> <span class="o">=</span> <span class="nx">template</span><span class="p">({})</span>
<span class="p">});</span>
<span class="c1">//将../dist下的文件放到/static/中</span>
<span class="nx">router</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="sr">/^\/static(?:\/|$)/</span><span class="p">,</span> <span class="nx">async</span> <span class="p">(</span><span class="nx">ctx</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">filePath</span> <span class="o">=</span> <span class="nx">ctx</span><span class="p">.</span><span class="nx">path</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/static\//</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="nx">await</span> <span class="nx">send</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="nx">filePath</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">root</span><span class="o">:</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span> <span class="s2">&quot;../dist&quot;</span><span class="p">)</span>
<span class="p">});</span>
<span class="p">})</span>
<span class="nx">app</span>
<span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">router</span><span class="p">.</span><span class="nx">routes</span><span class="p">())</span>
<span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">router</span><span class="p">.</span><span class="nx">allowedMethods</span><span class="p">());</span>
<span class="nx">app</span><span class="p">.</span><span class="nx">listen</span><span class="p">(</span><span class="mi">3000</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;listening on port 3000&#39;</span><span class="p">);</span>
</code></pre></div>
<h4 id="1-2-3-dockerfile:0814af543608f4fd171b2e9cf43d9917">1.2.3 Dockerfile</h4>
<p>一份Dockerfile文件可以帮助我们构建部署镜像,因此我们需要在项目根目录下创建一个Dockerfile文件</p>
<p><div class="highlight"><pre><code class="language-Dockerfile" data-lang="Dockerfile"><span></span><span class="k">FROM</span><span class="s"> node:latest</span>
<span class="c"># Create app directory</span>
<span class="k">RUN</span> mkdir -p /usr/src/app
<span class="k">WORKDIR</span><span class="s"> /usr/src/app</span>
COPY . /usr/src/app
<span class="c"># Build static file</span>
<span class="k">RUN</span> npm install --registry<span class="o">=</span>https://registry.npm.taobao.org
<span class="k">RUN</span> npm run build
<span class="k">WORKDIR</span><span class="s"> /usr/src/app/server</span>
<span class="c"># Build server file</span>
<span class="k">RUN</span> npm install --registry<span class="o">=</span>https://registry.npm.taobao.org
<span class="c"># Bundle app source</span>
<span class="k">EXPOSE</span><span class="s"> 3000</span>
<span class="k">CMD</span><span class="s"> [ &quot;npm&quot;, &quot;start&quot; ]</span>
</code></pre></div>
</p>
<p>Dockerfile的具体的写法可以参考官方文档。此处的Dockerfile的作用主要是,构建了静态文件,然后启动了node服务进程。</p>
<h3 id="1-3-创建镜像:0814af543608f4fd171b2e9cf43d9917">1.3 创建镜像</h3>
<p>通过运行下面👇这条指令,创建一个名为<code>name/application</code>的镜像,可以根据需要修改<code>name/application</code>,但是不要忘记后面的<code>.</code>,它表明根据当前目录下的Dockerfile构建镜像
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">docker</span> <span class="nx">build</span> <span class="o">-</span><span class="nx">t</span> <span class="nx">name</span><span class="o">/</span><span class="nx">application</span> <span class="p">.</span>
</code></pre></div>
如果最后看到<code>successful</code>的提示,那就代表镜像构建成功,可以进行下一步啦</p>
<h4 id="ps-可能失败原因如下:0814af543608f4fd171b2e9cf43d9917">ps:可能失败原因如下:</h4>
<ul>
<li>网络故障,那么可以等网好一点再试一次</li>
<li>代码错误,此时则注意看报错信息,根据报错信息修改</li>
<li>Docker版本太低,先使用<code>docker -v</code>查看版本,根据需要升级Docker版本</li>
</ul>
<h3 id="1-4-部署测试应用:0814af543608f4fd171b2e9cf43d9917">1.4 部署测试应用</h3>
<p>现在一切就绪,在本地运行镜像试试看,此处我继续选择将镜像映射到3000端口
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">docker</span> <span class="nx">run</span> <span class="o">-</span><span class="nx">p</span> <span class="mi">3000</span><span class="o">:</span><span class="mi">3000</span> <span class="o">-</span><span class="nx">d</span> <span class="nx">name</span><span class="o">/</span><span class="nx">application</span>
</code></pre></div>
之后可以从使用 <code>curl</code> 输出页面上的数据,本地测试成功后我们就可以将应用部署到服务器上了。</p>
<h2 id="在阿里云镜像仓库build镜像:0814af543608f4fd171b2e9cf43d9917">在阿里云镜像仓库Build镜像</h2>
<p>在直接登录服务器使用Docker Build镜像时,在因为网络问题失败N次之后,高人指点我去阿里云镜像仓库Build镜像。</p>
<p>为了方便ECS用户使用Docker官方镜像,阿里云同步Docker官方镜像库的最新版本到国内服务器,使得ECS用户可以通过内网连接该服务器。</p>
<p>在登录阿里云账号后,进入管理控制台,找到容器仓库中的镜像,进入镜像仓库控制台,创建镜像仓库,根据提示一步一步创建namespace等,配置的时候选择关联github,这样以后每次我们推送代码至github,阿里云就会自动帮我们构建镜像了。然后开始管理自己刚刚创建的镜像,进入构建页面立即构建,接着就可以在构建日志中查看构建状态了。</p>
<h4 id="ps-可能存在的坑:0814af543608f4fd171b2e9cf43d9917">ps:可能存在的坑</h4>
<p>如果一次构建失败了,查看日志寻找错误,然后重推一次代码到github,重新构建一般就能成功。</p>
<h2 id="进入服务器部署:0814af543608f4fd171b2e9cf43d9917">进入服务器部署</h2>
<p>然后就可以登录服务器部署了。</p>
<h3 id="3-1-clone仓库:0814af543608f4fd171b2e9cf43d9917">3.1 clone仓库</h3>
<p>在登录服务器后,从github上将项目clone至服务器上,接下来可以按照镜像仓库里的操作指南进行</p>
<p>在服务器上登录阿里云docker registry
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">sudo</span> <span class="nx">docker</span> <span class="nx">login</span> <span class="o">--</span><span class="nx">username</span><span class="o">=</span><span class="nx">你的账号名</span> <span class="nx">registry</span><span class="p">.</span><span class="nx">cn</span><span class="o">-</span><span class="nx">shenzhen</span><span class="p">.</span><span class="nx">aliyuncs</span><span class="p">.</span><span class="nx">com</span>
</code></pre></div>
登录registry的用户名是你的阿里云账号全名,密码是你开通namespace时设置的密码。</p>
<h3 id="3-2-从registry中拉取镜像:0814af543608f4fd171b2e9cf43d9917">3.2 从registry中拉取镜像:</h3>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">sudo</span> <span class="nx">docker</span> <span class="nx">pull</span> <span class="nx">registry</span><span class="p">.</span><span class="nx">cn</span><span class="o">-</span><span class="nx">shenzhen</span><span class="p">.</span><span class="nx">aliyuncs</span><span class="p">.</span><span class="nx">com</span><span class="o">/</span><span class="nx">仓库名称</span><span class="o">:</span><span class="p">[</span><span class="nx">镜像版本号</span><span class="p">]</span>
</code></pre></div>
这里的镜像版本号如果没有使用tag指明,一般就是<code>latest</code>,也可以在构建日志中查看得知。</p>
<h3 id="3-3-查看镜像号:0814af543608f4fd171b2e9cf43d9917">3.3 查看镜像号</h3>
<p>拉取镜像后,查看新拉取的镜像号
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span> <span class="nx">docker</span> <span class="nx">images</span>
</code></pre></div>
</p>
<h3 id="3-4-运行镜像:0814af543608f4fd171b2e9cf43d9917">3.4 运行镜像</h3>
<p>然后运行镜像,根据需要选择映射的端口号,此处我仍映射在3000端口
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">docker</span> <span class="nx">run</span> <span class="o">-</span><span class="nx">p</span> <span class="mi">3000</span><span class="o">:</span><span class="mi">3000</span> <span class="o">-</span><span class="nx">d</span> <span class="nx">镜像号</span>
</code></pre></div>
</p>
<p>成功后就可以在浏览器上通过<code>http://[SERVER_IP]:3000</code>访问你所部署的应用啦</p>
<h4 id="ps-可能遇到的坑:0814af543608f4fd171b2e9cf43d9917">ps: 可能遇到的坑:</h4>
<p>有的时候会需要修改代码重新构建镜像,在将镜像pull下来之后,应先停掉原来运行的容器</p>
<h5 id="①-查看容器号:0814af543608f4fd171b2e9cf43d9917">① 查看容器号</h5>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">docker</span> <span class="nx">ps</span>
</code></pre></div>
</p>
<h5 id="②-停止容器:0814af543608f4fd171b2e9cf43d9917">② 停止容器</h5>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">docker</span> <span class="nx">stop</span> <span class="nx">容器号</span>
</code></pre></div>
</p>
<p>然后继续运行镜像就可以啦</p>
<h2 id="总结:0814af543608f4fd171b2e9cf43d9917">总结</h2>
<p>到这里桂生前端部署初尝试就结束啦,记录下来希望能对大家也有所裨益。</p>
<h1 id="参考文献:0814af543608f4fd171b2e9cf43d9917">参考文献</h1>
<ul>
<li><a href="https://zxc0328.github.io/2017/06/05/fe-microservice/">前端微服务实践-以木犀通行证为例</a></li>
<li><a href="https://www.vultr.com/docs/deploy-a-node-js-application-using-docker">Deploy a Node.js Application Using Docker</a></li>
<li><a href="https://yeasy.gitbooks.io/docker_practice/content/install/mac.html">macOS 操作系统安装 Docker</a></li>
</ul>
</description>
</item>
<item>
<title>Manipulating Bits</title>
<link>https://elegenthus.github.io/post/Manipulating%20Bits/</link>
<pubDate>Mon, 13 Mar 2017 22:14:14 +0800</pubDate>
<guid>https://elegenthus.github.io/post/Manipulating%20Bits/</guid>
<description>
<p>《深入了解计算机》第二章习题</p>
<hr />
<p>此次DataLab的目的呢,是通过编写一系列函数来熟悉整数、浮点数以及位操作。你会解决一系列的编程<code>puzzle</code>,在你思考的这个过程中,将对位操作有更深刻的理解。关于我的理解可戳<a href="https://github.com/Elegenthus/CSLab/blob/master/datalab-handout/bits.c">这里</a></p>
<h2 id="任务目标:f6cdf44a038c2d7cebd9122295ca2169">任务目标</h2>
<p>首先来看我们需要解决的<code>puzzle</code>有哪些:</p>
<table>
<thead>
<tr>
<th align="center">名称</th>
<th align="center">描述</th>
<th align="center">难度</th>
<th align="center">指令数目</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">bitAnd(x,y)</td>
<td align="center">只用|和 ~ 实现 x&amp;y</td>
<td align="center">1</td>
<td align="center">8</td>
</tr>
<tr>
<td align="center">getByte(x,n)</td>
<td align="center">从数x中提取第n个字节</td>
<td align="center">2</td>
<td align="center">6</td>
</tr>
<tr>
<td align="center">logicalShift(x,n)</td>
<td align="center">将数x逻辑右移n位</td>
<td align="center">3</td>
<td align="center">20</td>
</tr>
<tr>
<td align="center">bitCount(x)</td>
<td align="center">返回二进制数中1的个数</td>
<td align="center">4</td>
<td align="center">40</td>
</tr>
<tr>
<td align="center">bang(x)</td>
<td align="center">不使用!而计算!x</td>
<td align="center">4</td>
<td align="center">12</td>
</tr>
<tr>
<td align="center">tmin()</td>
<td align="center">返回所能表示的最小整数</td>
<td align="center">1</td>
<td align="center">4</td>
</tr>
<tr>
<td align="center"><em>fitsBits(x,n)</em></td>
<td align="center">如果x可以表示为n位二<br>进制补码形式,则返回1</td>
<td align="center">2</td>
<td align="center">15</td>
</tr>
<tr>
<td align="center">divpwr2(x,n)</td>
<td align="center">计算x/(2^n)</td>
<td align="center">2</td>
<td align="center">15</td>
</tr>
<tr>
<td align="center">negate(x)</td>
<td align="center">返回-x</td>
<td align="center">2</td>
<td align="center">5</td>
</tr>
<tr>
<td align="center">isPositive(x)</td>
<td align="center">x&gt;0返回1,x&lt;=0返回0</td>
<td align="center">3</td>
<td align="center">8</td>
</tr>
<tr>
<td align="center">isLessOrEqual(x,y)</td>
<td align="center">x&lt;=y返回1否则返回0</td>
<td align="center">3</td>
<td align="center">24</td>
</tr>
<tr>
<td align="center">ilog2(x)</td>
<td align="center">返回不超过以2为底<br>x对数的最小整数</td>
<td align="center">4</td>
<td align="center">90</td>
</tr>
<tr>
<td align="center">float_neg(uf)</td>
<td align="center">返回和浮点数参数-f相<br>等的二进制数,返回参<br>数本身当参数是NaN时</td>
<td align="center">2</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">float_i2f(x)</td>
<td align="center">实现(float)x,<br>返回x对应浮点数的<br>二进制表示形式</td>
<td align="center">4</td>
<td align="center">30</td>
</tr>
<tr>
<td align="center">float_twice(uf)</td>
<td align="center">返回以unsinged表<br>示的浮点数二倍<br>的二进制形式</td>
<td align="center">4</td>
<td align="center">30</td>
</tr>
</tbody>
</table>
<h2 id="上手指南:f6cdf44a038c2d7cebd9122295ca2169">上手指南</h2>
<p>首先,一共有15个需要补充的函数,全部在bits.c文件中进行编写</p>
<ul>
<li>运行 <code>make btest</code> 编译函数</li>
<li>使用 <code>dlc compiler (./dlc)</code> 自动检测你的代码是否符合规定</li>
<li>运行 <code>./btest</code> 检测函数是否编写成功</li>
<li>使用 <code>./ishow n</code> 查看n的十六进制,有符号整型和无符号整型形式</li>
<li>使用 <code>./fshow n</code> 查看n的浮点数表示形式</li>
</ul>
<p>小技巧</p>
<ul>
<li>x * 8 =&gt; x&lt;&lt;3</li>
<li>!(x ^ y) =&gt; x == y</li>
<li>-x =&gt; ~x + 1</li>
<li>x != 0 =&gt; (!!x)为真</li>
<li>&hellip;&hellip;</li>
</ul>
<h2 id="题目及其解法:f6cdf44a038c2d7cebd9122295ca2169">题目及其解法</h2>
<h3 id="bitand-x-y:f6cdf44a038c2d7cebd9122295ca2169">bitAnd(x,y)</h3>
<ul>
<li>题目要求 :只用 | 和 ~ 实现 x&amp;y</li>
<li>允许操作:~ |</li>
<li>操作数限制:8</li>
<li>分值:1</li>
<li>使用样例:bitAnd(6, 5) = 4</li>
</ul>
<p>此题运用摩根定律可以解决 :</p>
<p><code>x&amp;y = ~(~(x&amp;y)) = ~((~x)|(~y))</code></p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">bitAnd</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">,</span> <span class="kr">int</span> <span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="o">~</span><span class="p">((</span><span class="o">~</span><span class="nx">x</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="o">~</span><span class="nx">y</span><span class="p">));</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="getbyte-x-y:f6cdf44a038c2d7cebd9122295ca2169">getByte(x,y)</h3>
<ul>
<li>题目要求 :从数x中提取从右数的第n个字节 <em>(0&lt;= n &lt;=3)</em></li>
<li>允许操作:! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</li>
<li>操作数限制:6</li>
<li>分值:2</li>
<li>使用样例:getByte(0x12345678,1) = 0x56</li>
</ul>
<p>此题解题思路即为将x右移n个字节,最后返回低八位所得结果。
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">getByte</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">,</span> <span class="kr">int</span> <span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//n * 8</span>
<span class="nx">n</span> <span class="o">=</span> <span class="nx">n</span><span class="o">&lt;&lt;</span><span class="mi">3</span><span class="p">;</span>
<span class="c1">//x右移8*n位</span>
<span class="nx">x</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="nx">n</span><span class="p">;</span>
<span class="c1">//保留最后8位</span>
<span class="k">return</span> <span class="mh">0xff</span> <span class="o">&amp;</span> <span class="nx">x</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h3 id="logicalshift-x-n:f6cdf44a038c2d7cebd9122295ca2169">logicalShift(x,n)</h3>
<ul>
<li>题目要求 :将数x逻辑右移n位 <em>(0 &lt;= n &lt;= 31)</em></li>
<li>允许操作:! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</li>
<li>操作数限制:20</li>
<li>分值:3</li>
<li>使用样例:logicalShift(0x87654321,4) = 0x08765432</li>
</ul>
<p>此题思路为将x右移n位后,清零高n位。</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">logicalShift</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">,</span> <span class="kr">int</span> <span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">x</span><span class="o">&gt;&gt;</span><span class="nx">n</span><span class="p">)</span><span class="o">&amp;</span><span class="p">(</span><span class="o">~</span><span class="p">((</span><span class="mi">1</span><span class="o">&lt;&lt;</span><span class="mi">31</span><span class="p">)</span><span class="o">&gt;&gt;</span><span class="nx">n</span><span class="o">&lt;&lt;</span><span class="mi">1</span><span class="p">));</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="bitcount-x:f6cdf44a038c2d7cebd9122295ca2169">bitCount(x)</h3>
<ul>
<li>题目要求 :返回x对应二进制数中1的个数</li>
<li>允许操作:! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</li>
<li>操作数限制:20</li>
<li>分值:4</li>
<li>使用样例:bitCount(5) = 2, bitCount(7) = 3</li>
</ul>
<p>首先将32位数分为8组,对于每四位数,通过三次移位运算统计每组数中1的个数,然后将前16位与后16位相加,将1的个数浓缩在16位中,再以同样的方法将1的个数整理到4位中,得到最后结果。</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">bitCount</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//Integer constants 0 through 255 (0xFF)</span>
<span class="c1">//令 i = 0x11111111</span>
<span class="kr">int</span> <span class="nx">sum</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kr">int</span> <span class="nx">i</span> <span class="o">=</span> <span class="mh">0x11</span><span class="o">|</span> <span class="p">(</span><span class="mh">0x11</span> <span class="o">&lt;&lt;</span> <span class="mi">8</span><span class="p">);</span>
<span class="nx">i</span> <span class="o">=</span> <span class="nx">i</span> <span class="o">|</span><span class="p">(</span><span class="nx">i</span> <span class="o">&lt;&lt;</span> <span class="mi">16</span><span class="p">);</span>
<span class="c1">//对于每四位,通过不停的移位运算将前三位的1加到第四位上</span>
<span class="nx">sum</span> <span class="o">+=</span> <span class="nx">x</span> <span class="o">&amp;</span> <span class="nx">i</span><span class="p">;</span>
<span class="nx">sum</span> <span class="o">+=</span> <span class="p">(</span><span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="nx">i</span><span class="p">;</span>
<span class="nx">sum</span> <span class="o">+=</span> <span class="p">(</span><span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="mi">2</span><span class="p">)</span> <span class="o">&amp;</span> <span class="nx">i</span><span class="p">;</span>
<span class="nx">sum</span> <span class="o">+=</span> <span class="p">(</span><span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">&amp;</span> <span class="nx">i</span><span class="p">;</span>
<span class="c1">//令i = 0xffff;</span>
<span class="nx">i</span> <span class="o">=</span> <span class="mh">0xff</span> <span class="o">|</span> <span class="p">(</span><span class="mh">0xff</span><span class="o">&lt;&lt;</span><span class="mi">8</span><span class="p">);</span>
<span class="c1">//将前16位与后16位相加</span>
<span class="nx">sum</span> <span class="o">=</span> <span class="p">(</span><span class="nx">sum</span> <span class="o">&gt;&gt;</span> <span class="mi">16</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="nx">i</span> <span class="o">&amp;</span> <span class="nx">sum</span><span class="p">);</span>
<span class="c1">//令i = 0x0f0f</span>
<span class="c1">//整理每8位之和</span>
<span class="nx">i</span> <span class="o">=</span> <span class="mh">0x0f</span> <span class="o">|</span> <span class="p">(</span><span class="mh">0x0f</span><span class="o">&lt;&lt;</span><span class="mi">8</span><span class="p">);</span>
<span class="nx">sum</span> <span class="o">=</span> <span class="p">((</span><span class="nx">sum</span> <span class="o">&gt;&gt;</span> <span class="mi">4</span><span class="p">)</span> <span class="o">&amp;</span> <span class="nx">i</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="nx">sum</span> <span class="o">&amp;</span> <span class="nx">i</span><span class="p">);</span>
<span class="c1">//将前8位与后8位相加</span>
<span class="nx">i</span> <span class="o">=</span> <span class="mh">0xff</span><span class="p">;</span>
<span class="nx">sum</span> <span class="o">=</span> <span class="p">(</span><span class="nx">sum</span> <span class="o">&gt;&gt;</span> <span class="mi">8</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="nx">i</span> <span class="o">&amp;</span> <span class="nx">sum</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">sum</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<h3 id="bang-x:f6cdf44a038c2d7cebd9122295ca2169">bang(x)</h3>
<ul>
<li>题目要求 :不使用!而计算!x</li>
<li>允许操作:~ &amp; ^ | + &lt;&lt; &gt;&gt;</li>
<li>操作数限制:12</li>
<li>分值:4</li>
<li>使用样例:bang(3) = 0, bang(0) = 1</li>
</ul>
<p>此题运用到了一个小技巧,非零数的相反数符号和自身不同,而零的相反数还是零。首先求出x的相反数,再左移取得符号位,与原数符号做按位或运算,若是符号相同得到0,不同得到-1。</p>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">bang</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//求x的相反数,利用0的相反数还是0,非零的数与其相反数符号不同的性质</span>
<span class="kr">int</span> <span class="nx">opposite_x</span> <span class="o">=</span> <span class="o">~</span><span class="nx">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="c1">//符号相同得到0,不同得到-1</span>
<span class="kr">int</span> <span class="nx">bits</span> <span class="o">=</span> <span class="p">(</span><span class="nx">opposite_x</span> <span class="o">&gt;&gt;</span> <span class="mi">31</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="mi">31</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">bits</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h3 id="tmin:f6cdf44a038c2d7cebd9122295ca2169">tmin()</h3>
<ul>
<li>题目要求 :返回所能表示的最小整数</li>
<li>允许操作:! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</li>
<li>操作数限制:4</li>
<li>分值:1</li>
<li>使用样例:tmin() = 0x80000000</li>
</ul>
<p>此题考查补码所能表示的最小数。</p>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">tmin</span><span class="p">(</span><span class="k">void</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">1</span><span class="o">&lt;&lt;</span><span class="mi">31</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h3 id="fitsbits-x-n:f6cdf44a038c2d7cebd9122295ca2169">fitsBits(x,n)</h3>
<ul>
<li>题目要求 :如果x可以表示为n位二进制补码形式,则返回1,否则返回0</li>
<li>允许操作:! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</li>
<li>操作数限制:15</li>
<li>分值:2</li>
<li>使用样例:fitsBits(5,3) = 0, fitsBits(-4,3) = 1</li>
</ul>
<p>若将x左移32-n位再右移回去,若得到的结果与原来的结果相同,则证明x可以用n位二进制补码形式表示。<br>
ps:</p>
<ul>
<li>需注意n位补码可以表示的数值范围为[-2^(n-1) , 2^(n-1) - 1] <br></li>
<li>由于系统编译器对于测试代码优化版本的问题,会产生 fitsBits(0x80000000,32) = 0 的测试错误,此时我们可以手动降低编译优化版本,具体的原理可戳<a href="http://stackoverflow.com/questions/14792521/bitwise-operations-and-shifts">这里</a></li>
</ul>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">fitsBits</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">,</span> <span class="kr">int</span> <span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
<span class="kr">int</span> <span class="nx">c</span> <span class="o">=</span> <span class="o">~</span><span class="nx">n</span> <span class="o">+</span> <span class="mi">33</span><span class="p">;</span>
<span class="kr">int</span> <span class="nx">changedX</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">&lt;&lt;</span> <span class="nx">c</span><span class="p">;</span>
<span class="kr">int</span> <span class="nx">changedY</span> <span class="o">=</span> <span class="nx">changedX</span><span class="o">&gt;&gt;</span> <span class="nx">c</span><span class="p">;</span>
<span class="k">return</span> <span class="o">!</span><span class="p">(</span><span class="nx">changedY</span> <span class="o">^</span> <span class="nx">x</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h3 id="divpwr2-x-n:f6cdf44a038c2d7cebd9122295ca2169">divpwr2(x,n)</h3>
<ul>
<li>题目要求 :计算x/(2^n)</li>
<li>允许操作:! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</li>
<li>操作数限制:15</li>
<li>分值:2</li>
<li>使用样例:divpwr2(15,1) = 7, divpwr2(-33,4) = -2</li>
</ul>
<p>x/(2^n)其实就是将x右移n位,但是在有余数的情况下应该向0取整,整数通过移位能很好地解决这一问题,但是对于负数而言,则应该加1。所以我们用t存取x的符号,tt存取x的后n位数,当负数除不尽有余数时,结果加1。</p>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">divpwr2</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">,</span> <span class="kr">int</span> <span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//取符号</span>
<span class="kr">int</span> <span class="nx">t</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="mi">31</span><span class="p">;</span>
<span class="kr">int</span> <span class="nx">tmp</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="nx">n</span><span class="p">)</span> <span class="o">+</span> <span class="o">~</span><span class="mi">0</span><span class="p">;</span>
<span class="c1">//取后n位 </span>
<span class="kr">int</span> <span class="nx">tt</span> <span class="o">=</span> <span class="nx">tmp</span> <span class="o">&amp;</span> <span class="nx">x</span><span class="p">;</span>
<span class="c1">//取后n位是否有数</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="nx">n</span><span class="p">)</span> <span class="o">+</span> <span class="p">((</span><span class="o">!!</span><span class="nx">tt</span><span class="p">)</span> <span class="o">&amp;</span> <span class="nx">t</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h3 id="negate-x:f6cdf44a038c2d7cebd9122295ca2169">negate(x)</h3>
<ul>
<li>题目要求 :返回-x</li>
<li>允许操作:! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</li>
<li>操作数限制:5</li>
<li>分值:2</li>
<li>使用样例:negate(1) = -1.</li>
</ul>
<p>[-x]反 = ~[x]反 <br>
=&gt; [-x]反 + 1 = ~[x]反 + 1 <br>
=&gt; [-x]补 = ~[x]反 + 1</p>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">negate</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="o">~</span><span class="nx">x</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h3 id="ispositive-x:f6cdf44a038c2d7cebd9122295ca2169">isPositive(x)</h3>
<ul>
<li>题目要求 :x&gt;0返回1,x&lt;=0返回0</li>
<li>允许操作:! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</li>
<li>操作数限制:8</li>
<li>分值:3</li>
<li>使用样例:isPositive(-1) = 0.</li>
</ul>
<p>取m记录x的符号位,(!!x)判断x是否不为零</p>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">isPositive</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">)</span> <span class="p">{</span>
<span class="kr">int</span> <span class="nx">m</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="mi">31</span><span class="p">;</span>
<span class="k">return</span> <span class="o">!</span><span class="nx">m</span> <span class="o">&amp;</span> <span class="p">(</span><span class="o">!!</span><span class="nx">x</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h3 id="islessorequal-x-y:f6cdf44a038c2d7cebd9122295ca2169">isLessOrEqual(x,y)</h3>
<ul>
<li>题目要求 :x&lt;=y返回1否则返回0</li>
<li>允许操作:! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</li>
<li>操作数限制:24</li>
<li>分值:3</li>
<li>使用样例:isLessOrEqual(4,5) = 1</li>
</ul>
<p>返回1的情况有两种:<br>
①x为负数而y为正数 <br>
②x、y符号相同且 x-y &lt;= 0</p>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">isLessOrEqual</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">,</span> <span class="kr">int</span> <span class="nx">y</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//y-x</span>
<span class="kr">int</span> <span class="nx">m</span> <span class="o">=</span> <span class="p">(</span><span class="o">~</span><span class="nx">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="nx">y</span><span class="p">;</span>
<span class="c1">//取x,y符号</span>
<span class="kr">int</span> <span class="nx">p</span> <span class="o">=</span> <span class="o">!!</span><span class="p">(</span><span class="nx">x</span><span class="o">&gt;&gt;</span><span class="mi">31</span><span class="p">);</span>
<span class="kr">int</span> <span class="nx">q</span> <span class="o">=</span> <span class="o">!!</span><span class="p">(</span><span class="nx">y</span><span class="o">&gt;&gt;</span><span class="mi">31</span><span class="p">);</span>
<span class="k">return</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">m</span><span class="o">&gt;&gt;</span><span class="mi">31</span><span class="p">)</span><span class="o">&amp;</span><span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="nx">p</span><span class="o">^</span><span class="nx">q</span><span class="p">)))</span> <span class="o">|</span> <span class="p">(</span><span class="nx">p</span><span class="o">&amp;!</span><span class="nx">q</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h3 id="ilog2-x:f6cdf44a038c2d7cebd9122295ca2169">ilog2(x)</h3>
<ul>
<li>题目要求 :返回不超过以2为底x对数的最小整数</li>
<li>允许操作:! ~ &amp; ^ | + &lt;&lt; &gt;&gt;</li>
<li>操作数限制:90</li>
<li>分值:4</li>
<li>使用样例:ilog2(16) = 4</li>
</ul>
<p>寻找不超过以2为底x对数的最小整数就是寻找x的二进制形式中最高位1出现的位置。</p>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">int</span> <span class="nx">ilog2</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//记录最高位1的位置</span>
<span class="kr">int</span> <span class="nx">result1</span><span class="p">,</span><span class="nx">result2</span><span class="p">,</span><span class="nx">result3</span><span class="p">,</span><span class="nx">result4</span><span class="p">,</span><span class="nx">result5</span><span class="p">,</span><span class="nx">flag</span><span class="p">;</span>
<span class="c1">//判断高16位是否有1出现</span>
<span class="nx">flag</span> <span class="o">=</span> <span class="o">!!</span><span class="p">(</span><span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="mi">16</span><span class="p">);</span>
<span class="c1">//出现1则确定最终结果数量级必然大于16</span>
<span class="nx">result1</span> <span class="o">=</span> <span class="nx">flag</span> <span class="o">&lt;&lt;</span> <span class="mi">4</span><span class="p">;</span>
<span class="c1">//继续判断高8位是否有1出现,以此类推</span>
<span class="nx">x</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="nx">result1</span><span class="p">;</span>
<span class="nx">flag</span> <span class="o">=</span> <span class="o">!!</span><span class="p">(</span><span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="mi">8</span><span class="p">);</span>
<span class="nx">result2</span> <span class="o">=</span> <span class="nx">flag</span> <span class="o">&lt;&lt;</span> <span class="mi">3</span><span class="p">;</span>
<span class="nx">x</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="nx">result2</span><span class="p">;</span>
<span class="nx">flag</span> <span class="o">=</span> <span class="o">!!</span><span class="p">(</span><span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="mi">4</span><span class="p">);</span>
<span class="nx">result3</span> <span class="o">=</span> <span class="nx">flag</span> <span class="o">&lt;&lt;</span> <span class="mi">2</span><span class="p">;</span>
<span class="nx">x</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="nx">result3</span><span class="p">;</span>
<span class="nx">flag</span> <span class="o">=</span> <span class="o">!!</span><span class="p">(</span><span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="mi">2</span><span class="p">);</span>
<span class="nx">result4</span> <span class="o">=</span> <span class="nx">flag</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">;</span>
<span class="nx">x</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="nx">result4</span><span class="p">;</span>
<span class="nx">flag</span> <span class="o">=</span> <span class="o">!!</span><span class="p">(</span><span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">);</span>
<span class="nx">result5</span> <span class="o">=</span> <span class="nx">flag</span> <span class="o">&lt;&lt;</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">x</span> <span class="o">=</span> <span class="nx">x</span> <span class="o">&gt;&gt;</span> <span class="nx">result5</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">result5</span> <span class="o">+</span> <span class="nx">result4</span> <span class="o">+</span> <span class="nx">result3</span> <span class="o">+</span> <span class="nx">result2</span> <span class="o">+</span> <span class="nx">result1</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h3 id="float-neg-uf:f6cdf44a038c2d7cebd9122295ca2169">float_neg(uf)</h3>
<ul>
<li>题目要求 :返回和浮点数参数-f相等的二进制数,返回参数本身当参数是NaN时</li>
<li>允许操作:包括任何整型/无符号整型操作,||,&amp;&amp;以及if,while</li>
<li>操作数限制:10</li>
<li>分值:2</li>
<li>使用样例:float_neg(0) = 0x80000000</li>
</ul>
<p>对于一个浮点数来说,指数部分全为1时,若尾数部分不全为0(不需要考虑符号位),则表示这个数不是一个数(NaN),在排除了NaN的情况后,只需将符号位取反即可。</p>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">unsigned</span> <span class="nx">float_neg</span><span class="p">(</span><span class="nx">unsigned</span> <span class="nx">uf</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">unsigned</span> <span class="nx">temp</span><span class="p">;</span>
<span class="c1">//最高位取反</span>
<span class="nx">temp</span> <span class="o">=</span> <span class="nx">uf</span> <span class="o">^</span> <span class="mh">0x80000000</span><span class="p">;</span>
<span class="c1">//E全为1。这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);</span>
<span class="c1">//如果有效数字M不全为0,表示这个数不是一个数(NaN),符号位无关紧要。</span>
<span class="c1">//最高位清零</span>
<span class="kr">int</span> <span class="nx">t</span> <span class="o">=</span> <span class="nx">uf</span> <span class="o">&amp;</span> <span class="mh">0x7fffffff</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="nx">t</span> <span class="o">&gt;</span> <span class="mh">0x7f800000</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">uf</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">temp</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h3 id="float-i2f-x:f6cdf44a038c2d7cebd9122295ca2169">float_i2f(x)</h3>
<ul>
<li>题目要求 :实现(float)x,返回x对应浮点数的二进制表示形式</li>
<li>允许操作:包括任何整型/无符号整型操作,||,&amp;&amp;以及if,while</li>
<li>操作数限制:30</li>
<li>分值:4</li>
<li>使用样例:float_i2f(0x800000) = 0x4b000000</li>
</ul>
<p>此题考查对于IEEE二进制浮点数算术标准(IEEE 754)的掌握<br></p>
<ul>
<li>用s来保存符号位</li>
<li>exp记录最高位的位置,即记录指数</li>
<li>franc记录尾数
<br></li>
</ul>
<p>最后返回x对应的浮点数的32位754标准的二进制存储格式。</p>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">unsigned</span> <span class="nx">float_i2f</span><span class="p">(</span><span class="kr">int</span> <span class="nx">x</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">unsigned</span> <span class="nx">s</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">exp</span> <span class="o">=</span> <span class="mi">31</span><span class="p">,</span> <span class="nx">frac</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">d</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">x</span> <span class="o">==</span> <span class="mh">0x00000000</span><span class="nx">u</span><span class="p">)</span> <span class="k">return</span> <span class="mh">0x00000000</span><span class="nx">u</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">x</span> <span class="o">&amp;</span> <span class="mh">0x80000000</span><span class="nx">u</span><span class="p">)</span> <span class="p">{</span> <span class="nx">s</span> <span class="o">=</span> <span class="mh">0x80000000</span><span class="nx">u</span><span class="p">;</span> <span class="nx">x</span> <span class="o">=</span> <span class="o">-</span><span class="nx">x</span><span class="p">;</span> <span class="p">}</span>
<span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">x</span> <span class="o">&amp;</span> <span class="mh">0x80000000</span><span class="nx">u</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span>
<span class="c1">//exp记录最高位的位置</span>
<span class="nx">exp</span> <span class="o">-=</span> <span class="mi">1</span><span class="p">;</span>
<span class="nx">x</span> <span class="o">&lt;&lt;=</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">//最后舍掉的8位若最高位为1且低七位仍有数,要进位</span>
<span class="k">if</span> <span class="p">((</span><span class="nx">x</span> <span class="o">&amp;</span> <span class="mh">0x000001ff</span><span class="p">)</span> <span class="o">==</span> <span class="mh">0x180</span><span class="p">)</span> <span class="nx">d</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">((</span><span class="nx">x</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mh">0x80</span><span class="p">)</span> <span class="nx">d</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="c1">//franc记录尾数</span>
<span class="nx">frac</span> <span class="o">=</span> <span class="p">((</span><span class="nx">x</span> <span class="o">&amp;</span> <span class="mh">0x7fffffff</span><span class="nx">u</span><span class="p">)</span> <span class="o">&gt;&gt;</span> <span class="mi">8</span><span class="p">)</span> <span class="o">+</span> <span class="nx">d</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">s</span> <span class="o">+</span> <span class="p">((</span><span class="nx">exp</span> <span class="o">+</span> <span class="mi">127</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="mi">23</span><span class="p">)</span> <span class="o">+</span> <span class="nx">frac</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h3 id="float-twice-uf:f6cdf44a038c2d7cebd9122295ca2169">float_twice(uf)</h3>
<ul>
<li>题目要求 :返回以unsinged表示的浮点数二倍的二进制形式</li>
<li>允许操作:包括任何整型/无符号整型操作,||,&amp;&amp;以及if,while</li>
<li>操作数限制:30</li>
<li>分值:4</li>
<li>使用样例:float_twice(0x7f800000) = 0x7f800000</li>
</ul>
<p>返回结果:</p>
<ul>
<li>若数为NaN,仍返回其本身</li>
<li>溢出情况0x80000000时返回0x80000000</li>
<li>若指数尚为0时,通过左移得到二倍形式</li>
<li>否则在指数位上加1,即加上0x00800000</li>
</ul>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">unsigned</span> <span class="nx">float_twice</span><span class="p">(</span><span class="nx">unsigned</span> <span class="nx">uf</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// 若是指数为0情况</span>
<span class="k">if</span><span class="p">((</span><span class="nx">uf</span> <span class="o">&amp;</span> <span class="mh">0x7F800000</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">uf</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="mh">0x80000000</span> <span class="o">&amp;</span> <span class="nx">uf</span><span class="p">);</span><span class="c1">//特殊情况0x80000000</span>
<span class="c1">//若数为NaN</span>
<span class="k">else</span> <span class="k">if</span><span class="p">((</span><span class="nx">uf</span> <span class="o">&amp;</span> <span class="mh">0x7fffffff</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mh">0x7f800000</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">uf</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">uf</span> <span class="o">+</span> <span class="mh">0x00800000</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
</p>
<h2 id="总结:f6cdf44a038c2d7cebd9122295ca2169">总结</h2>
<p>本次DataLab在种种运算符限制下实现了一些基本操作,相信做完的你对数据的理解又加深啦~</p>
</description>
</item>
<item>
<title>如何在页面中引入SVG图标</title>
<link>https://elegenthus.github.io/post/svg/</link>
<pubDate>Tue, 20 Dec 2016 18:39:58 +0800</pubDate>
<guid>https://elegenthus.github.io/post/svg/</guid>
<description>
<p>最近在写项目的时候,碰到页面上一些高清图标需要用svg格式引入,这篇文章将会总结一下怎样在页面中使用SVG图标。</p>
<h2 id="svg的简介:71678e3b902faa943f79c02db17483db">SVG的简介</h2>
<p>SVG是一种可缩放矢量图形(英语:Scalable Vector Graphics,SVG)是基于可扩展标记语言(XML),用于描述二维矢量图形的图形格式。SVG由W3C制定,是一个开放标准。<br>
简单的理解它是图形的另一种格式,例如它和常见的图片格式.png、.jpg、.gif等是一类。
关于SVG的一些具体的使用示例可以戳这篇<a href="https://aotu.io/notes/2016/11/22/SVG_Web_Animation/">三看 SVG Web 动效</a></p>
<h2 id="在页面中引入svg图标:71678e3b902faa943f79c02db17483db">在页面中引入SVG图标</h2>
<h3 id="对svg进行-瘦身:71678e3b902faa943f79c02db17483db">对SVG进行“瘦身”</h3>
<p>在拿到设计师给的SVG图片之后,我们先对它进行一点小小的修改,保留<code>svg</code>标签内的<code>viewBox</code>属性,以及路径<code>path</code>的代码段,并用模板标签<code>symbol</code>来替换<code>svg</code>标签,得到的效果大致如下</p>
<div class="highlight"><pre><code class="language-html" data-lang="html"><span></span><span class="p">&lt;</span><span class="nt">svg</span> <span class="na">style</span><span class="o">=</span><span class="s">&quot;display: none&quot;</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">symbol</span> <span class="na">viewBox</span><span class="o">=</span><span class="s">&quot;0 0 145.5 121.5&quot;</span> <span class="na">id</span><span class="o">=</span><span class="s">&quot;share&quot;</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">path</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;st0&quot;</span> <span class="na">d</span><span class="o">=</span><span class="s">&quot;M88.9,0l56.6,56.7l-56.6,56.7V81c0,0-56.1-6.2-88.9,40.5c0,0,10.3-89.1,88.9-89.1V0z&quot;</span> <span class="p">/&gt;</span>
<span class="p">&lt;/</span><span class="nt">symbol</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
</code></pre></div>
<p>然后将其插进html页面中的<code>svg</code>标签内,你可以为svg标签设置内联样式<code>display: none</code>这样它就不会在页面中显示了<br>
对了,不要忘记在<code>symbol</code>标签内添加相应的id属性,方便在页面中相应位置进行引用</p>
<h3 id="在相应位置以-code-svg-code-标签引入svg:71678e3b902faa943f79c02db17483db">在相应位置以<code>svg</code>标签引入SVG</h3>
<p>用<code>use</code>引用上文中的<code>symbol</code>集合,<code>xlink:href</code> 属性指定引用的<code>id</code></p>
<p><div class="highlight"><pre><code class="language-html" data-lang="html"><span></span><span class="p">&lt;</span><span class="nt">svg</span> <span class="na">viewBox</span><span class="o">=</span><span class="s">&quot;0 0 200 200&quot;</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">use</span> <span class="na">xmlns:xlink</span><span class="o">=</span><span class="s">&quot;http://www.w3.org/1999/xlink&quot;</span> <span class="na">xlink:href</span><span class="o">=</span><span class="s">&quot;#commit&quot;</span><span class="p">&gt;&lt;/</span><span class="nt">use</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
</code></pre></div>
</p>
<p>以上就是在页面中引入SVG的总结。</p>
</description>
</item>
<item>
<title>使用Vue Directive封装DOM操作</title>
<link>https://elegenthus.github.io/post/VueDirectivesTest/</link>
<pubDate>Sun, 20 Nov 2016 16:19:56 +0800</pubDate>
<guid>https://elegenthus.github.io/post/VueDirectivesTest/</guid>
<description>
<p>这篇文章是关于Vue Directive的介绍,后面会介绍一个使用的小例子。</p>
<hr />
<h2 id="1-vue-directive的简介-br:8fb70ceb80e0e159e41b00203ce25900">1.Vue Directive的简介 <br></h2>
<p>directive在Vue中十分常见,Vue提供的许多指令如 <code>v-on</code> 、 <code>v-show</code> 使得Vue的功能更加强大,可是仍然有一些操作指令是Vue没有提供的,不过Vue提供了自定义directive的属性方法来满足这一需求。其实,Vue Directive就是一种特殊的HTML元素属性。<br>
Vue提供了两中注册方法,一种是全局注册,在Vue.directive中定义组件的名字和相关指令操作</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span> <span class="nx">Vue</span><span class="p">.</span><span class="nx">directive</span><span class="p">(</span><span class="s1">&#39;指令的名字&#39;</span><span class="p">,</span> <span class="p">{</span>
<span class="c1">//一些option,提供许多hook function 定义directive的具体操作,如inserted、bind...</span>
<span class="nx">inserted</span><span class="o">:</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">el</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//指令插入元素后的操作</span>
<span class="p">}</span>
<span class="p">})</span>
</code></pre></div>
<p>另一种是局部注册,在对应组件的directives属性里注册组件名,传入指令的option对象</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">directives</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">name</span><span class="o">:</span> <span class="p">{</span> <span class="c1">//指令的名字</span>
<span class="c1">// 指令的定义</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>在定义时,Vue提供了许多hook function,例如 <code>inserted</code> 、<code>bind</code>等,<code>bind</code>是只会在绑定的对象节点被插入父节点时调用一次的函数,与<code>unbind</code>相对应,<code>unbind</code>将也只会在元素被解除绑定时调用。<br></p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">Vue</span><span class="p">.</span><span class="nx">directive</span><span class="p">(</span><span class="s1">&#39;指令的名字&#39;</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">bind</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">el</span><span class="p">,</span> <span class="nx">binding</span><span class="p">,</span> <span class="nx">vnode</span><span class="err">,</span><span class="nx">oldVnode</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//绑定指令时调用</span>
<span class="p">},</span>
<span class="nx">unbind</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">//指令解除绑定时调用</span>
<span class="p">}</span>
<span class="p">})</span>
</code></pre></div>
<p><code>bind</code>函数中的<code>binding</code>,是一个包含了众多属性的对象,关于它的所有的性质的介绍可以自行查看<a href="https://vuejs.org/v2/guide/custom-directive.html">官方文档</a> ,比较常用的一个属性<code>binding.value</code>,与其对应的是在指令中传入的字符串,Vue会自动解析这个值并执行。与此相对应的另一个属性<code>binding.expression</code>里的值则就是原始值。<br></p>
<h2 id="2-为什么要使用vuedirective-br:8fb70ceb80e0e159e41b00203ce25900">2.为什么要使用VueDirective <br></h2>
<p>有同学可能会问,我在Vue实例的方法中写DOM操作不可以吗?那为什么使用Vue Directive来封装DOM操作呢?<br>
这是因为,为了实现View和ViewModel的分离,我们必须封装DOM操作,View层负责页面上的显示,ViewModel层负责改变操作数据,由于Vue是数据驱动的,属于ViewModel层,那么其中就不应该出现View层上的DOM操作,而且,使用Vue Directive是和DOM元素的创建、销毁绑定的。Vue Directive的生命周期方法能让我们更优雅的去在合适的时机进行DOM的操作。而在ViewModel里则没有和DOM元素对应的方法。因为Vue Directive是属于View层面的,所以DOM操作应该被封装在Vue Directive里而不是出现在Vue实例中。 <br></p>
<h2 id="3-demo-自制scroll指令-br:8fb70ceb80e0e159e41b00203ce25900">3. Demo:自制scroll指令 <br></h2>
<p>接下来看一个具体使用Vue Directive封装DOM操作的scroll事件的例子,在这个例子中需求是在用户滑动到页面的底端时请求更多数据。<br></p>
<h3 id="3-1-首先将dom操作封装到指令的option中-br:8fb70ceb80e0e159e41b00203ce25900">3.1 首先将DOM操作封装到指令的option中 <br></h3>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kd">let</span> <span class="nx">scrollCallback</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">scrollHeight</span> <span class="o">&lt;</span> <span class="mi">1000</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">scrollHeight</span> <span class="o">-</span> <span class="nb">window</span><span class="p">.</span><span class="nx">scrollY</span> <span class="o">-</span> <span class="mi">100</span> <span class="o">&lt;=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">clientHeight</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">callback</span><span class="p">()</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">let</span> <span class="nx">callBackWarpped</span> <span class="c1">// 新变量 保存引用</span>
<span class="kr">export</span> <span class="k">default</span> <span class="p">{</span>
<span class="nx">bind</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">el</span><span class="p">,</span> <span class="nx">binding</span><span class="p">,</span> <span class="nx">vnode</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">callBackWarpped</span> <span class="o">=</span> <span class="nx">scrollCallback</span><span class="p">.</span><span class="nx">bind</span><span class="p">({},</span> <span class="nx">binding</span><span class="p">.</span><span class="nx">value</span><span class="p">)</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s2">&quot;scroll&quot;</span><span class="p">,</span> <span class="nx">callBackWarpped</span><span class="p">)</span>
<span class="p">},</span>
<span class="nx">unbind</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">removeEventListener</span><span class="p">(</span><span class="s2">&quot;scroll&quot;</span><span class="p">,</span> <span class="nx">callBackWarpped</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
</p>
<p>首先需要监听页面的滚动,如果触发了scroll事件那么就要执行回调函数,由于在解除绑定的时候也要将监听事件从window上移除,所以必须给回调函数取一个名字,例如本例中的<code>scrollCallback</code>,并在unbind函数中将监听移除,因此<code>scrollCallBack</code>的具体定义应在对象外执行。<br>
并且回调函数应该在页面滑动到底端时才执行,也就是说不能马上执行 <code>binding.value</code>,怎样实现这一点呢?可以将<code>bind.value</code>作为函数的参数传进<code>scrollCallback</code>,先判断,然后在满足条件时调用<code>binding.value</code> 。<br></p>
<h3 id="3-2-在组件里import一个directive-br:8fb70ceb80e0e159e41b00203ce25900">3.2 在组件里import一个directive <br></h3>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="kr">import</span> <span class="nx">scrollDirective</span> <span class="nx">from</span> <span class="s1">&#39;../../directives/scroll&#39;</span>
<span class="c1">//import 指令的option的名字 from &#39;指令option的位置&#39;</span>
</code></pre></div>
</p>
<p>使用import将directive引入组件。 <br></p>
<h3 id="3-3-在组件的directives属性中注册这个指令-值为scroll:8fb70ceb80e0e159e41b00203ce25900">3.3 在组件的directives属性中注册这个指令,值为scroll</h3>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">directives</span><span class="o">:</span> <span class="p">{</span>
<span class="nx">scroll</span><span class="o">:</span> <span class="nx">scrollDirective</span>
<span class="c1">//指令的名字:指令的option的名字</span>
<span class="p">},</span>
</code></pre></div>
</p>
<p>将引入的组件注册到scroll上。 <br></p>
<h3 id="3-4-在相应元素上加上directive指令-br:8fb70ceb80e0e159e41b00203ce25900">3.4 在相应元素上加上directive指令<br></h3>
<p><div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span></span><span class="nx">v</span><span class="o">-</span><span class="nx">scroll</span> <span class="o">=</span> <span class="s2">&quot;onScroll&quot;</span>
<span class="c1">//v-&#39;指令的名字&#39; = &quot;回调函数&quot;</span>
</code></pre></div>
</p>
<p>用注册好的名字在相对应的元素上加入指令 。<br></p>
<h3 id="3-5-编写directive指令中的函数-br:8fb70ceb80e0e159e41b00203ce25900">3.5 编写directive指令中的函数<br></h3>
<p>最后在method中编写<code>onScroll</code>函数,也就是上文中对应的<code>binding.value</code>,在这个函数中我们将会请求更多数据,而Vue就会执行相应<code>v-scroll</code>中的值。 <br><br></p>
<hr />
<p>具体的Demo请戳<a href="https://github.com/Elegenthus/scrollDemo/tree/gh-pages">这里</a></p>
</description>
</item>
<item>
<title>hackathon_Match(3)</title>
<link>https://elegenthus.github.io/post/hackathon_Match%283%29/</link>
<pubDate>Thu, 03 Nov 2016 19:54:22 +0800</pubDate>
<guid>https://elegenthus.github.io/post/hackathon_Match%283%29/</guid>
<description><p><a href="http://match.muxixyz.com">Match</a></p>
<hr />
<p>恭喜你,来到了我们的result页面,我们很快就能看到我们的match分数啦~是不是很期待?<br>
我们先来公布一份超级有爱的match结果~<br>
<img src="../../img/match3.png" alt="" />
<br>
大家可以看到我们的页面上有显示相对应应用中的共同项<br>