-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlocal-search.xml
725 lines (349 loc) · 546 KB
/
local-search.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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Interview</title>
<link href="/2024/08/31/Interview/"/>
<url>/2024/08/31/Interview/</url>
<content type="html"><![CDATA[<h1 id="面试技巧"><a href="#面试技巧" class="headerlink" title="面试技巧"></a>面试技巧</h1><h2 id="简历准备"><a href="#简历准备" class="headerlink" title="简历准备"></a>简历准备</h2><p>Boss是不能先发送简历附件的,要填写线上简历+打招呼内容。</p><h2 id="网申"><a href="#网申" class="headerlink" title="网申"></a>网申</h2><p>HR一般会在上午9点半左右以及下午两点左右打开邮箱,在上午11点、下午三点左右通知你面试;每周二、周五看邮箱的几率稍大。HR的工作顺序是:查看并筛选主动投递简历→看平台推荐人才简历→主动检索简历,打招呼后正常发简历就行。</p><blockquote><p>您好,我对贵司xx职位很感兴趣,请您看下我的简历,如果合适可以随时联系我,谢谢。</p><p>(发送简历)</p></blockquote><p>若已读未回,可能简历处于合适和不合适之间,可以做以下处理:</p><blockquote><p>HR您好,我非常看好贵司机会,此前投递简历后,发现您已读未回,可能是您没来得及处理,也可能是我的简历没有通过筛选,我想确认一下,希望能得到您的回复。谢谢!</p><p>以下是我的微信和电话,如方便,您可以直接给我电话。盼复。</p><p>(发送微信和电话)</p></blockquote><p>若还是已读不回,应该是不合适了,如果还是很想投的话可以考虑找到HR电话致电。</p><h2 id="个人介绍"><a href="#个人介绍" class="headerlink" title="个人介绍"></a>个人介绍</h2><p>面试官您好,很荣幸参加本次面试。</p><p>我叫xxx,今天来面试贵司的前端开发实习生岗位,接下来我做一个简单的自我介绍。</p><p>我是xx届的毕业生,就读xx大学的计算机与信息安全学院,在大学期间自学了Web前端及其相关技能。大一下学期的时候在xxxxx找到一份前端开发的线上实习。</p><p>在实习的时候,主要使用的技术栈和工具就是vue3+element plus,工作内容就是和其他前端一起写前端页面,我是负责写数据管理等页面或者组件,然后通过git平台上传整合,周期交任务写报告之类的,积攒了不少经验。</p><p>最近的项目是我自己写的一个TODO平台,前后端UI设计服务器部署都是我自己做的。之前有团队协作做过小程序项目,用过uniapp但最后在微信开发者平台开发的。</p><p>大学期间也还做过不少其他项目,大部分是在比赛中做的,也拿到了例如网挑国奖的成绩。在学院里担任科技协会主席,逻辑清晰,善于沟通。</p><p>以上就是我的大致情况,谢谢。</p><h1 id="Vue"><a href="#Vue" class="headerlink" title="Vue"></a>Vue</h1><h2 id="VUE3项目目录结构"><a href="#VUE3项目目录结构" class="headerlink" title="VUE3项目目录结构"></a>VUE3项目目录结构</h2><figure class="highlight brainfuck"><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><code class="hljs brainfuck"><span class="hljs-comment">| node_modules</span><span class="hljs-literal">--</span><span class="hljs-comment">项目依赖</span><br><span class="hljs-comment">| public </span><span class="hljs-literal">--</span><span class="hljs-comment">公共文件夹</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| favicon</span><span class="hljs-string">.</span><span class="hljs-comment">ico</span><span class="hljs-literal">--</span><span class="hljs-comment">网站图标</span><br><span class="hljs-comment">| src </span><span class="hljs-literal">--</span><span class="hljs-comment">源文件目录</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| assets</span> <span class="hljs-literal">--</span><span class="hljs-comment">静态文件</span><br><span class="hljs-comment"></span><span class="hljs-literal">---</span><span class="hljs-comment">| utils</span> <span class="hljs-literal">--</span><span class="hljs-comment">工具类JS</span><br><span class="hljs-comment"></span><span class="hljs-literal">---</span><span class="hljs-comment">| api</span> <span class="hljs-literal">--</span><span class="hljs-comment">接口类JS</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| components</span><span class="hljs-literal">--</span><span class="hljs-comment">组件</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| router</span><span class="hljs-literal">--</span><span class="hljs-comment">路由配置</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| store</span><span class="hljs-literal">--</span><span class="hljs-comment">状态管理器</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| views</span><span class="hljs-literal">--</span><span class="hljs-comment">视图文件,与路由结构对应</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| App</span><span class="hljs-string">.</span><span class="hljs-comment">vue</span><span class="hljs-literal">--</span><span class="hljs-comment">根组件</span><br><span class="hljs-literal">---</span><span class="hljs-comment">| main</span><span class="hljs-string">.</span><span class="hljs-comment">js </span><span class="hljs-literal">--</span><span class="hljs-comment">入口文件</span><br><span class="hljs-comment">| index</span><span class="hljs-string">.</span><span class="hljs-comment">html</span><span class="hljs-literal">--</span><span class="hljs-comment">入口html</span><br><span class="hljs-comment">| package</span><span class="hljs-string">.</span><span class="hljs-comment">json</span><span class="hljs-literal">--</span><span class="hljs-comment">命令配置及依赖管理</span><br><span class="hljs-comment">| package</span><span class="hljs-literal">-</span><span class="hljs-comment">lock</span><span class="hljs-string">.</span><span class="hljs-comment">json</span><span class="hljs-literal">--</span><span class="hljs-comment">依赖版本及更完整的依赖树</span><br><span class="hljs-comment">| README</span><span class="hljs-string">.</span><span class="hljs-comment">md</span><span class="hljs-literal">--</span><span class="hljs-comment">说明文件</span><br><span class="hljs-comment">| vue</span><span class="hljs-string">.</span><span class="hljs-comment">config</span><span class="hljs-string">.</span><span class="hljs-comment">json </span> <span class="hljs-literal">--</span><span class="hljs-comment">代理、打包等配置文件</span><br></code></pre></td></tr></table></figure><hr><blockquote><h3 id="public和assets区别:"><a href="#public和assets区别:" class="headerlink" title="public和assets区别:"></a>public和assets区别:</h3><p>同样用于存放静态文件的文件夹。由于vue-cli、vite等工具打包时,public下的文件会原封不动的添加到dist中,而assets下的文件会被合并压缩。</p><p>两者的区别是public下一般用于放有更新需求的第三方插件、图片且需要使用绝对路径来引用(否则会warning),而assets下适合用于存放项目中所必须的图标、JS文件只支持相对路径。<a href="https://vitejs.cn/vite3-cn/guide/assets.html#importing-asset-as-url">相关文档</a></p></blockquote><hr><blockquote><h3 id="有了package-json为什么还需要package-lock-json:"><a href="#有了package-json为什么还需要package-lock-json:" class="headerlink" title="有了package.json为什么还需要package-lock.json:"></a>有了package.json为什么还需要package-lock.json:</h3><p>前者声明依赖的种类而后者决定实际安装的版本,使用<code>npm install</code>时就是根据package-lock.json进行安装。</p></blockquote><h1 id="Javascript"><a href="#Javascript" class="headerlink" title="Javascript"></a>Javascript</h1><h2 id="ECMA-262标准化语言规范"><a href="#ECMA-262标准化语言规范" class="headerlink" title="ECMA-262标准化语言规范"></a>ECMA-262标准化语言规范</h2><blockquote><h3 id="ECMAScript和Javascript的区别"><a href="#ECMAScript和Javascript的区别" class="headerlink" title="ECMAScript和Javascript的区别:"></a>ECMAScript和Javascript的区别:</h3><p>ECMAScript是JavaScript的核心语言规范,而JavaScript则是基于这些规范的具体实现,包含了更多的功能和API,以便在浏览器和其他环境中运行。</p></blockquote><figure class="highlight markdown"><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></pre></td><td class="code"><pre><code class="hljs markdown">ES1(1997年)<br><span class="hljs-bullet">+</span> 基于Netscape的JavaScript 1.1。<br><br>ES2(1998年)<br><span class="hljs-bullet">+</span> 与ISO/IEC 16262标准保持一致。<br><br>ES3(1999年):<br><span class="hljs-bullet">+</span> 正则表达式:引入了正则表达式支持。<br><span class="hljs-bullet">+</span> 更好的字符串处理:增加了新的字符串方法。<br><span class="hljs-bullet">+</span> 控制语句:添加了try/catch异常处理。<br><span class="hljs-bullet">+</span> 其他改进:包括更严格的错误定义和数字格式化。<br><br>ES5(2009年):<br><span class="hljs-bullet">+</span> 严格模式:提供了更严格的错误检查。<br><span class="hljs-bullet">+</span> JSON支持:内置了对JSON的支持。<br><span class="hljs-bullet">+</span> Array方法:如forEach、map、filter等。<br><span class="hljs-bullet">+</span> Object方法:如Object.keys、Object.defineProperty等。<br><br>ES6(2015年):<br><span class="hljs-bullet">+</span> 箭头函数:简化了函数表达式。<br><span class="hljs-bullet">+</span> let和const:引入了块级作用域变量。<br><span class="hljs-bullet">+</span> 模板字符串:支持多行字符串<span class="hljs-code">` `</span> 和内嵌表达式${ }。<br><span class="hljs-bullet">+</span> 类和模块:引入了类和模块系统。<br><span class="hljs-bullet">+</span> Promise:用于处理异步操作。<br><br>ES7(2016年):数组includes方法、指数运算简化<br><span class="hljs-bullet">+</span> Array.prototype.includes():检查数组中是否包含某个元素。<br><span class="hljs-bullet">+</span> 指数运算符:简化指数运算为双星号。<br><br>ES8(2017年):简化异步、对象方法优化、字符串填充方法<br><span class="hljs-bullet">+</span> Async/Await:简化异步代码。<br><span class="hljs-bullet">+</span> Object.values() 和 Object.entries():返回对象的值和键值对数组。<br><span class="hljs-bullet">+</span> String padding:字符串填充方法。<br><br>ES9(2018年):<br><span class="hljs-bullet">+</span> 异步迭代器:支持异步数据流处理。<br><span class="hljs-bullet">+</span> Rest/Spread属性:(...)扩展对象的解构赋值和扩展运算符。<br><br>ES10(2019年)数组/对象/字符串处理方法增加<br><span class="hljs-bullet">+</span> Array.prototype.flat() 和 Array.prototype.flatMap():数组扁平化方法。<br><span class="hljs-bullet">+</span> Object.fromEntries():将键值对列表转换为对象。<br><span class="hljs-bullet">+</span> String.prototype.trimStart() 和 String.prototype.trimEnd():去除字符串开头和结尾的空白字符。<br><br>ES11(2020年):BigInt、空值合并、动态导入模块、可选链<br><span class="hljs-bullet">+</span> BigInt:支持任意精度的整数。<br><span class="hljs-bullet">+</span> 动态导入:按需加载模块。<br><span class="hljs-bullet">+</span> 空值合并运算符(??):处理null或undefined。<br><span class="hljs-bullet">+</span> 可选链运算符(?.):简化深层嵌套对象属性的访问。<br><br>ES12(2021年):逻辑赋值运算、字符串匹配方法<br><span class="hljs-bullet">+</span> 逻辑赋值运算符(&&=、||=、??=):结合逻辑运算和赋值操作。<br><span class="hljs-bullet">+</span> String.prototype.replaceAll():替换字符串中所有匹配的子串。<br><span class="hljs-bullet">+</span> Promise.any():返回第一个成功的Promise。<br><br>ES13(2022年)顶层await、类字段声明初始化<br><span class="hljs-bullet">+</span> 顶层await:在模块顶层使用await。<br><span class="hljs-bullet">+</span> 类字段声明:简化类中字段的声明和初始化。<br><br>ES14(2023年)数组方法优化<br><span class="hljs-bullet">+</span> Array.prototype.toSorted():返回排序后的数组副本。<br><span class="hljs-bullet">+</span> Array.prototype.toReversed():返回反转后的数组副本。<br><span class="hljs-bullet">+</span> Array.prototype.toSpliced():返回删除或替换元素后的数组副本。<br><br>ES15(2024年)symbol描述、匹配字符串索引<br><span class="hljs-bullet">+</span> RegExp Match Indices:提供匹配子字符串的索引。<br><span class="hljs-bullet">+</span> Symbol.prototype.description:返回Symbol的描述。<br></code></pre></td></tr></table></figure><h2 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h2><blockquote><h3 id="基本类型:"><a href="#基本类型:" class="headerlink" title="基本类型:"></a>基本类型:</h3><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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Number</span><br><span class="hljs-keyword">let</span> intNum = <span class="hljs-number">1</span>,octNum = <span class="hljs-number">001</span>,hexNum = <span class="hljs-number">0x1</span> <span class="hljs-comment">//整数,常见十进制、八进制、十六进制</span><br><span class="hljs-keyword">let</span> floatNum = <span class="hljs-number">0.1</span>,eNum = <span class="hljs-number">1.11e7</span><span class="hljs-comment">//可以表示科学计数法e后面是幂</span><br><span class="hljs-title function_">log</span>(<span class="hljs-number">0</span>/<span class="hljs-number">0</span>) <span class="hljs-comment">//返回NaN 意思是本来返回数值的操作失败</span><br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Undefined</span><br><span class="hljs-keyword">let</span> message,<span class="hljs-title function_">log</span>(message)<span class="hljs-comment">//返回undefined,变量声明过但未被初始化。</span><br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//String</span><br><span class="hljs-keyword">let</span> <span class="hljs-title class_">AStr</span> = <span class="hljs-string">"1"</span>,aStr = <span class="hljs-string">'1'</span>,someStr = <span class="hljs-string">`1`</span><span class="hljs-comment">//字符串一旦被创建,值就不可以再被改变,如果执行改变的操作,会先销毁再创建。</span><br></code></pre></td></tr></table></figure><hr><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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Null</span><br><span class="hljs-keyword">let</span> nullOne = <span class="hljs-literal">null</span>,<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> nullOne)<span class="hljs-comment">//null是一个空对象指针,输出为Object,如果变量要保存对象,但是当时又没有对象可以保存,就用null填充。</span><br><span class="hljs-title function_">log</span>(<span class="hljs-literal">null</span>==<span class="hljs-literal">undefined</span>)<span class="hljs-comment">//undefined是由null派生来的,返回为真</span><br></code></pre></td></tr></table></figure><hr><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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Boolean</span><br><span class="hljs-comment">//对于非空字符串、数值、对象、N/A 转为布尔值为true</span><br><span class="hljs-comment">//对于""、0、NaN、null、undefined 转为布尔值为false</span><br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Symbol</span><br><span class="hljs-keyword">let</span> aSymbol = <span class="hljs-title class_">Symbol</span>(<span class="hljs-string">'1'</span>),bSymbol = <span class="hljs-title class_">Symbol</span>(<span class="hljs-string">'1'</span>),<span class="hljs-title function_">log</span>(aSymbol==bSymbol)<span class="hljs-comment">//返回false,symbol是原始值,symbol实例是唯一且不可变的,symbol的作用是确保对象属性使用唯一标识符。</span><br></code></pre></td></tr></table></figure></blockquote><hr><blockquote><h3 id="引用类型:"><a href="#引用类型:" class="headerlink" title="引用类型:"></a>引用类型:</h3><p>引用类型统称为<code>object</code>,包括<code>object</code> <code>array</code> <code>function</code> <code>Date</code> <code>RegExp</code> <code>Map</code> <code>Set</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Object对象</span><br><span class="hljs-keyword">let</span> man = { <span class="hljs-comment">// 属性名可以是字符串或者数值</span><br><span class="hljs-attr">name</span>:<span class="hljs-string">"zero"</span>,<br><span class="hljs-string">"age"</span>:<span class="hljs-number">1</span>,<br><span class="hljs-number">1</span>:<span class="hljs-literal">true</span><br>}<br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Array</span><br><span class="hljs-keyword">let</span> colors = [<span class="hljs-string">"red"</span>, <span class="hljs-number">2</span>, {<span class="hljs-attr">age</span>: <span class="hljs-number">20</span> }] <span class="hljs-comment">//JS数组是动态大小的,每个槽位可以存储任意类型数据的。</span><br></code></pre></td></tr></table></figure><hr><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//Function</span><br><span class="hljs-keyword">let</span> <span class="hljs-title function_">sum</span> = (<span class="hljs-params">num1, num2</span>) => {<br> <span class="hljs-keyword">return</span> num1 + num2;<br>};<br></code></pre></td></tr></table></figure></blockquote><hr><blockquote><h3 id="区别:"><a href="#区别:" class="headerlink" title="区别:"></a>区别:</h3><p>基本数据类型和引用数据类型存储在内存中的位置不同:</p><ul><li>基本数据类型存储在栈中</li><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><code class="hljs js"><span class="hljs-keyword">let</span> a = <span class="hljs-number">10</span>;<br><span class="hljs-keyword">let</span> b = a; <span class="hljs-comment">// 赋值操作</span><br>b = <span class="hljs-number">20</span>;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a); <span class="hljs-comment">// 10值</span><br><br><span class="hljs-keyword">var</span> obj1 = {}<br><span class="hljs-keyword">var</span> obj2 = obj1;<span class="hljs-comment">//这个操作让obj1和2的引用地址相同了。</span><br>obj2.<span class="hljs-property">name</span> = <span class="hljs-string">"1"</span>;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj1.<span class="hljs-property">name</span>); <span class="hljs-comment">// 1</span><br></code></pre></td></tr></table></figure></blockquote><h2 id="Iterator相关知识"><a href="#Iterator相关知识" class="headerlink" title="Iterator相关知识"></a>Iterator相关知识</h2><blockquote><h3 id="迭代器生成方式及使用方式:"><a href="#迭代器生成方式及使用方式:" class="headerlink" title="迭代器生成方式及使用方式:"></a>迭代器生成方式及使用方式:</h3><p>某些方法会返回一个迭代器,如<code>arr.entries()</code>返回一个带有全部键值对的迭代器,使用<code>next()</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">const</span> array1 = [<span class="hljs-string">'a'</span>, <span class="hljs-string">'b'</span>, <span class="hljs-string">'c'</span>];<br><br><span class="hljs-keyword">const</span> iterator1 = array1.<span class="hljs-title function_">entries</span>();<br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(iterator1.<span class="hljs-title function_">next</span>().<span class="hljs-property">value</span>);<br><span class="hljs-comment">// Expected output: Array [0, "a"]</span><br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(iterator1.<span class="hljs-title function_">next</span>().<span class="hljs-property">value</span>);<br><span class="hljs-comment">// Expected output: Array [1, "b"]</span><br></code></pre></td></tr></table></figure></blockquote><h2 id="Array相关知识"><a href="#Array相关知识" class="headerlink" title="Array相关知识"></a>Array相关知识</h2><blockquote><h3 id="数组长度与空槽:"><a href="#数组长度与空槽:" class="headerlink" title="数组长度与空槽:"></a>数组长度与空槽:</h3><p><code>arr.length</code>可以输出数组长度,甚至可以更改<code>arr.length</code>去改变数组长度,如果用此法扩展数组长度,没有被赋值的地方会产生<code>空槽</code>,<code>空槽</code>无法输出,对于不同数组方法,<code>空槽</code>也有不同的行为。</p><p>如<code>forEach</code>等迭代方法根本不会访问空槽。而其他的拼接复制方法如<code>concat</code>则会保留空槽。一些较新的方法会视其为undefined 如<code>splice()</code>拼接数组,<code>join()</code>等。</p></blockquote><hr><blockquote><h3 id="常用的数组方法:"><a href="#常用的数组方法:" class="headerlink" title="常用的数组方法:"></a>常用的数组方法:</h3><ul><li><code>every()/some()</code>-对数组内所有元素执行括号内函数,全部通过/有一个通过返回布尔值。</li><li><code>fill(target,start,end)</code>-对数组内指定索引覆盖target值,超出范围不会扩展数组。</li><li><code>find()/findLast()</code>-返回括号内函数符合条件的第一个/最后一个值,否则返回undefined。</li><li><code>findIndex()/findLastIndex()</code>-返回括号内函数符合条件的第一个/最后一个索引,否则返回undefined。</li><li><code>indexOf()/lastIndexOf()</code>-返回括号内值符合条件的第一个值/最后一个值的索引,否则返回-1。</li><li><code>flat()</code>-扁平化数组,括号内为深度,ES10新语法</li><li><code>includes()</code>-判断数组是否包含一个值,返回布尔值,ES7新语法</li><li><code>join()</code>-将一个数组更改为其各元素以括号内字符串连接的字符串,默认使用逗号,如目标数组不是纯数组,报错。</li><li><code>pop()/push()</code>-移除/添加数组末尾一个元素并返回该值,如果push的是一个数组则会在末尾添加数组,push自身会导致循环引用。</li><li><code>shift()/unshift()</code>-移除/添加数组第一个元素并返回该值</li><li><code>reverse()/toReversed()</code>-转置原数组改变原数组/转置原数组不改变原数组,<code>toReversed()</code>ES14新语法</li><li><code>slice(start,end)</code>-浅拷贝一个由start开始end结束的数组,不改变原数组。</li><li><code>sort()/toSorted()</code>-对数组按照元素第一个字符的ascii码排序改变原数组/不改变原数组</li><li><code>splice(start,num,value...)/toSpliced()</code>-删除由start开始的num个数值,并在start索引下添加value值,改变原数组/不改变原数组。</li></ul></blockquote><hr><blockquote><h3 id="forEach、filter、map、reduce的区别"><a href="#forEach、filter、map、reduce的区别" class="headerlink" title="forEach、filter、map、reduce的区别:"></a>forEach、filter、map、reduce的区别:</h3><p>三者都是ES5的新特性,均用于数组。</p><p><code>forEach</code>遍历数组全部元素并对数组进行操作,不返回新数组,return用于跳出循环,返回undefined。</p><p><code>filter</code>遍历数组全部元素并使用判断语句返回新数组,return值为假的时候过滤。</p><p><code>map</code>遍历数组全部元素并操作数组产生新数组,不改变原数组。</p><p><code>reduce((accumulator, currentValue)=>...,initialValue)</code>-遍历数组,若initialValue设置则为初始accumulator值,若没设置则currentValue为数组第一个值,不可处理数组对象,…处不可以加大括号。</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><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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//设分别执行三种函数</span><br><span class="hljs-keyword">let</span> arr = [<br> {<span class="hljs-attr">name</span>:<span class="hljs-string">'小明'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">14</span>},<br> {<span class="hljs-attr">name</span>:<span class="hljs-string">'小华'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">11</span>},<br> {<span class="hljs-attr">name</span>:<span class="hljs-string">'小红'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">15</span>},<br> {<span class="hljs-attr">name</span>:<span class="hljs-string">'小黄'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">17</span>},<br>]<br><br><span class="hljs-keyword">let</span> forEachBack = arr.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> item.<span class="hljs-property">name</span> = <span class="hljs-string">"学生"</span>+item.<span class="hljs-property">name</span><br>})<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(forEachBack)<span class="hljs-comment">//undefined</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr)<span class="hljs-comment">//name前都加上学生</span><br><br><span class="hljs-keyword">let</span> filterBack = arr.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> <span class="hljs-keyword">return</span> item.<span class="hljs-property">age</span>><span class="hljs-number">10</span><br>})<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(filterBack)<span class="hljs-comment">//包含有name属性的,每一项age大于10的新数组</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr)<span class="hljs-comment">//arr不变</span><br><br><span class="hljs-keyword">let</span> filterBack = arr.<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> <span class="hljs-keyword">return</span> item.<span class="hljs-property">age</span>><span class="hljs-number">10</span><br>})<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(filterBack)<span class="hljs-comment">//包含有name属性的,每一项age大于10的新数组</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr)<span class="hljs-comment">//arr不变</span><br><br><span class="hljs-keyword">let</span> mapBack = arr.<span class="hljs-title function_">map</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> <span class="hljs-keyword">return</span> item.<span class="hljs-property">age</span> + <span class="hljs-number">1</span><br>})<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(mapBack)<span class="hljs-comment">//不包含有name属性的,每一项age加1的新一维数组:[15,12,16,18]</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr)<span class="hljs-comment">//arr不变</span><br><br><span class="hljs-keyword">let</span> initialValue = -<span class="hljs-number">1</span>;<br><span class="hljs-keyword">let</span> reduceBack = mapBack.<span class="hljs-title function_">reduce</span>(<br><span class="hljs-function">(<span class="hljs-params">accumulator, currentValue</span>) =></span> accumulator + currentValue,<br>initialValue<br>);<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(reduceBack)<span class="hljs-comment">//60 = -1 + 15 + 12 + 16 +18</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arr)<span class="hljs-comment">//arr不变</span><br></code></pre></td></tr></table></figure></blockquote><h2 id="String相关知识"><a href="#String相关知识" class="headerlink" title="String相关知识"></a>String相关知识</h2><p><code>String()</code>作为函数调用时,返回字面量原始值。<code>String()</code>作为构造函数(使用<code>new</code>)被调用时,会创建一个String对象,该对象不是原始类型。</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><code class="hljs js"><span class="hljs-keyword">const</span> a = <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(<span class="hljs-string">"Hello world"</span>); <span class="hljs-comment">// a === "Hello world" 为 false</span><br><span class="hljs-keyword">const</span> b = <span class="hljs-title class_">String</span>(<span class="hljs-string">"Hello world"</span>); <span class="hljs-comment">// b === "Hello world" 为 true</span><br>a <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">String</span>; <span class="hljs-comment">// 为 true</span><br>b <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">String</span>; <span class="hljs-comment">// 为 false</span><br><span class="hljs-keyword">typeof</span> a; <span class="hljs-comment">// "object"</span><br><span class="hljs-keyword">typeof</span> b; <span class="hljs-comment">// "string"</span><br></code></pre></td></tr></table></figure><hr><blockquote><h3 id="常用的字符串方法:"><a href="#常用的字符串方法:" class="headerlink" title="常用的字符串方法:"></a>常用的字符串方法:</h3><ul><li><code>concat(value,str)</code>-以value值拼接两个字符串。</li><li><code>endsWith(value,index)/endsWith()</code>-查找字符串是否以value结尾/开头,index为查找的末尾索引+1,返回布尔值。</li><li><code>includes(value)</code>-查找value值,返回布尔值。</li><li><code>indexOf(searchString, position)/lastIndexOf()</code>-查找第一次/最后一次出现searchString的索引,position为查找开始的索引,默认为0。</li><li><code>match()/search()</code>-匹配正则表达式,返回匹配的字符的数组/索引。</li><li><code>replace(value,origin)/replaceAll()</code>-匹配字符串value替换origin,返回替换后的字符串。</li><li><code>slice(start,end)</code>-提取字符串的一部分返回新字符串,不改变原字符串。</li><li><code>split(rule)</code>-按照rule模式将字符串分割成一个数组,返回该数组。</li><li><code>toLowerCase()/toUpperCase()</code>-全部换成小写/大写</li><li><code>trim()</code>-从字符串两端移除空白字符,返回新字符,不修改原来的字符。</li></ul></blockquote><h2 id="Map相关知识"><a href="#Map相关知识" class="headerlink" title="Map相关知识"></a>Map相关知识</h2><p>Map对象保存键值对,并且可以记住键的原始插入顺序,任何值都可以作为键或者值。</p><blockquote><h3 id="Object和Map的区别:"><a href="#Object和Map的区别:" class="headerlink" title="Object和Map的区别:"></a>Object和Map的区别:</h3><table><thead><tr><th align="center">区别</th><th align="center">Map</th><th align="center">Object</th></tr></thead><tbody><tr><td align="center">键的类型</td><td align="center">Map的键可以是任何值</td><td align="center">Object的键必须为字符串或者Symbol</td></tr><tr><td align="center">键的顺序</td><td align="center">Map的对象按照插入的顺序迭代</td><td align="center">Object的排序就很混乱,ES6之后按照属性创建顺序迭代</td></tr><tr><td align="center">迭代</td><td align="center">可迭代对象,可以使用for of</td><td align="center">不可迭代,默认只能用for in</td></tr><tr><td align="center">性能</td><td align="center">在涉及频繁添加和删除键值对的场景中表现更好。</td><td align="center">在涉及频繁添加和删除键值对的场景中表现更好。</td></tr></tbody></table></blockquote><hr><blockquote><h3 id="常用的map方法:"><a href="#常用的map方法:" class="headerlink" title="常用的map方法:"></a>常用的map方法:</h3><ul><li><code>clear()</code>-清除所有元素</li><li><code>delete()</code>-删除指定键的值</li><li><code>forEach()</code>-对每一个键/值进行一次操作</li><li><code>get()</code>-获取指定键的值,一般并对其进行后续处理。</li><li><code>has()</code>-检查指定键是否存在,返回布尔值。</li><li><code>keys()/values()</code>-返回一个迭代器对象,该对象包含了此map中每个元素的键/值</li><li><code>set()</code>-向map中添加一个指定的键值对。</li></ul></blockquote><h2 id="x3D-x3D-和-x3D-x3D-x3D-的区别"><a href="#x3D-x3D-和-x3D-x3D-x3D-的区别" class="headerlink" title="== 和 ===的区别"></a>== 和 ===的区别</h2><p>在使用<code>==</code>时会默认使用隐式转换改变数据类型,<code>===</code>的时候不会。</p><blockquote><h3 id="特殊情况:"><a href="#特殊情况:" class="headerlink" title="特殊情况:"></a>特殊情况:</h3><p>null和undefined只能彼此相等,其他情况均不相等。</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-literal">null</span> == <span class="hljs-literal">undefined</span> <span class="hljs-comment">// true</span><br><span class="hljs-literal">null</span> == <span class="hljs-literal">false</span> <span class="hljs-comment">// false</span><br><span class="hljs-literal">undefined</span> == <span class="hljs-literal">false</span> <span class="hljs-comment">//false</span><br></code></pre></td></tr></table></figure></blockquote><h2 id="深拷贝和浅拷贝的区别"><a href="#深拷贝和浅拷贝的区别" class="headerlink" title="深拷贝和浅拷贝的区别"></a>深拷贝和浅拷贝的区别</h2><p>浅拷贝指创建新的数据,如果属性是基本类型,则为其字面量;如果属性为引用类型,拷贝的就是内存地址。即浅拷贝出来的对象还是指向同一个内存地址。</p><blockquote><p>eg.<code>slice()</code>、<code>concat()</code></p></blockquote><p>深拷贝则是开一个新的栈,基本类型的值也是拷贝字面量;但是如果是引用类型,值相同但是会有不同的内存地址。即深拷贝出来的对象不指向同一个内存地址。</p><blockquote><p>eg.<code>JSON.stringify()</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//深拷贝</span><br><span class="hljs-keyword">let</span> obj1 = {<span class="hljs-attr">name</span>: <span class="hljs-string">'A'</span>}<br><span class="hljs-keyword">const</span> obj2 = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(obj1));<br>obj1.<span class="hljs-property">name</span> = <span class="hljs-string">'B'</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj2); <span class="hljs-comment">// {name: "A"}</span><br><br><span class="hljs-comment">//浅拷贝</span><br><span class="hljs-keyword">var</span> obj1 = {}<br><span class="hljs-keyword">var</span> obj2 = obj1;<br>obj2.<span class="hljs-property">name</span> = <span class="hljs-string">'B'</span>;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj1.<span class="hljs-property">name</span>); <span class="hljs-comment">// "B"</span><br></code></pre></td></tr></table></figure></blockquote><hr><blockquote><h3 id="手写深拷贝:"><a href="#手写深拷贝:" class="headerlink" title="手写深拷贝:"></a>手写深拷贝:</h3><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><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">deepClone</span>(<span class="hljs-params">obj,hash = <span class="hljs-keyword">new</span> <span class="hljs-built_in">WeakMap</span>()</span>){<span class="hljs-comment">//用weakmap是因为垃圾回收策略,避免内存泄漏</span><br> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> obj !== <span class="hljs-string">'object'</span>||obj === <span class="hljs-literal">null</span>)<span class="hljs-keyword">return</span> obj<span class="hljs-comment">//不是对象直接返回即可,深拷贝是对于对象而言的</span><br> <span class="hljs-keyword">if</span>(obj <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Date</span>)<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(obj)<br> <span class="hljs-keyword">if</span>(obj <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">RegExp</span>)<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RegExp</span>(obj)<span class="hljs-comment">//日期、正则对象可以使用他们内置的拷贝构造函数</span><br> <br> <span class="hljs-keyword">if</span>(hash.<span class="hljs-title function_">has</span>(obj))<span class="hljs-keyword">return</span> hash.<span class="hljs-title function_">get</span>(obj)<span class="hljs-comment">//有了就返回</span><br> <span class="hljs-keyword">let</span> cloneObj = <span class="hljs-keyword">new</span> obj.<span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span>)<span class="hljs-comment">//拿某个对象的原型对象构造出来的对象</span><br> hash.<span class="hljs-title function_">set</span>(obj, cloneObj);<span class="hljs-comment">//加到hash中</span><br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> key <span class="hljs-keyword">in</span> obj) {<span class="hljs-comment">//一层一层向下找</span><br> <span class="hljs-keyword">if</span> (obj.<span class="hljs-title function_">hasOwnProperty</span>(key)) {<span class="hljs-comment">//如果不是继承的就进if</span><br> cloneObj[key] = <span class="hljs-title function_">deepClone</span>(obj[key], hash);<span class="hljs-comment">//递归拿到不是继承的属性的键</span><br> }<br> }<br> <span class="hljs-keyword">return</span> cloneObj;<br>}<br></code></pre></td></tr></table></figure></blockquote><h2 id="闭包"><a href="#闭包" class="headerlink" title="闭包"></a>闭包</h2><p>当我们创建一个函数A中再<strong>创建</strong>一个函数B的时候,B中可以使用在A初始化的数据。这就是闭包,也就是说,闭包可以让你在一个内层函数中访问到其外层函数的作用域。</p><blockquote><h3 id="闭包的使用场景:"><a href="#闭包的使用场景:" class="headerlink" title="闭包的使用场景:"></a>闭包的使用场景:</h3><ul><li><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><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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> <span class="hljs-title class_">Counter</span> = (<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">var</span> privateCounter = <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">function</span> <span class="hljs-title function_">changeBy</span>(<span class="hljs-params">val</span>) {<br> privateCounter += val;<br> }<br> <span class="hljs-keyword">return</span> {<br> <span class="hljs-attr">increment</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-title function_">changeBy</span>(<span class="hljs-number">1</span>);<br> },<br> <span class="hljs-attr">decrement</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-title function_">changeBy</span>(-<span class="hljs-number">1</span>);<br> },<br> <span class="hljs-attr">value</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">return</span> privateCounter;<br> }<br> }<br>})();<br><br><span class="hljs-keyword">var</span> <span class="hljs-title class_">Counter1</span> = <span class="hljs-title function_">makeCounter</span>();<br><span class="hljs-keyword">var</span> <span class="hljs-title class_">Counter2</span> = <span class="hljs-title function_">makeCounter</span>();<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">value</span>()); <span class="hljs-comment">/* logs 0 */</span><br><span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">increment</span>();<br><span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">increment</span>();<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">value</span>()); <span class="hljs-comment">/* logs 2 */</span><br><span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">decrement</span>();<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Counter1</span>.<span class="hljs-title function_">value</span>()); <span class="hljs-comment">/* logs 1 */</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Counter2</span>.<span class="hljs-title function_">value</span>()); <span class="hljs-comment">/* logs 0 */</span><br></code></pre></td></tr></table></figure></li><li><p>延长变量的生命周期:本例子中延长了width的生命周期</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">// 假设我们有一个求长方形面积的函数</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">getArea</span>(<span class="hljs-params">width, height</span>) {<br> <span class="hljs-keyword">return</span> width * height<br>}<br><span class="hljs-comment">// 如果我们碰到的长方形的宽老是10</span><br><span class="hljs-keyword">const</span> area1 = <span class="hljs-title function_">getArea</span>(<span class="hljs-number">10</span>, <span class="hljs-number">20</span>)<br><span class="hljs-keyword">const</span> area2 = <span class="hljs-title function_">getArea</span>(<span class="hljs-number">10</span>, <span class="hljs-number">30</span>)<br><span class="hljs-keyword">const</span> area3 = <span class="hljs-title function_">getArea</span>(<span class="hljs-number">10</span>, <span class="hljs-number">40</span>)<br> <br><span class="hljs-comment">// 我们可以使用闭包柯里化这个计算面积的函数(柯里化的意思就是允许把一次填入多参数的函数转化为多次填入参数的函数)</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">getArea</span>(<span class="hljs-params">width</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-params">height</span> =></span> {<br> <span class="hljs-keyword">return</span> width * height<br> }<br>}<br> <br><span class="hljs-keyword">const</span> getTenWidthArea = <span class="hljs-title function_">getArea</span>(<span class="hljs-number">10</span>)<br><span class="hljs-comment">// 之后碰到宽度为10的长方形就可以这样计算面积</span><br><span class="hljs-keyword">const</span> area1 = <span class="hljs-title function_">getTenWidthArea</span>(<span class="hljs-number">20</span>)<br> <br><span class="hljs-comment">// 而且如果遇到宽度偶尔变化也可以轻松复用</span><br><span class="hljs-keyword">const</span> getTwentyWidthArea = <span class="hljs-title function_">getArea</span>(<span class="hljs-number">20</span>)<br></code></pre></td></tr></table></figure></li></ul></blockquote><h2 id="作用域及作用域链"><a href="#作用域及作用域链" class="headerlink" title="作用域及作用域链"></a>作用域及作用域链</h2><p>作用域决定了代码区块中变量及其他资源的可见性,一般将作用域分为<code>全局作用域</code>、<code>函数作用域</code>、<code>块级作用域</code>,作用域在变量被创建好的时候就确定了,不会随着执行的时候改变。</p><p>作用域链是指你需要调用变量的时候,会先从局部作用域寻找,一直往上直到全局作用域。</p><blockquote><h3 id="全局作用域、函数作用域及块级作用域:"><a href="#全局作用域、函数作用域及块级作用域:" class="headerlink" title="全局作用域、函数作用域及块级作用域:"></a>全局作用域、函数作用域及块级作用域:</h3><p>全局作用域:不在任何函数或者大括号中声明的变量,可以在程序的任何位置访问。</p><p>函数作用域:也叫局部作用域,是在函数内部声明的,不能在函数之外访问(除了闭包)</p><p>块级作用域:ES6中引入了<code>let</code>&<code>const</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> globalValue = <span class="hljs-string">"1"</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">test</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">var</span> functionValue = <span class="hljs-string">"2"</span><br>}<br><span class="hljs-title function_">test</span>(<span class="hljs-params"></span>)<br>{<br> <span class="hljs-keyword">let</span> blockValue = <span class="hljs-string">"3"</span><br> <span class="hljs-title function_">log</span>(blockValue)<span class="hljs-comment">//"3"</span><br>}<br><br><span class="hljs-title function_">log</span>(globalValue)<span class="hljs-comment">//"1"</span><br><span class="hljs-title function_">log</span>(functionValue)<span class="hljs-comment">// 报错</span><br><span class="hljs-title function_">log</span>(blockValue)<span class="hljs-comment">//报错</span><br></code></pre></td></tr></table></figure></blockquote><h2 id="原型及原型链"><a href="#原型及原型链" class="headerlink" title="原型及原型链"></a>原型及原型链</h2><p>JS中 每一个对象都有一个原型对象,当访问一个对象的属性的时候,JS不仅会在对象上寻找,还会搜索该对象的原型,以及该对象原型的原型(这叫做原型链)直到匹配或者到达原型链的末尾。</p><blockquote><h3 id="什么是对象的属性:"><a href="#什么是对象的属性:" class="headerlink" title="什么是对象的属性:"></a>什么是对象的属性:</h3><p>对象的属性是用来描述对象状态或者特征的,属性可以包含各种各样的数据,可以是基本数据也可以是函数、对象等,每个属性都有一个键值对。</p></blockquote><p>也就是说,这些属性和方法是定义在object的构造函数的<code>prototype</code>而非实例本身。</p><p>实例通过<code>_proto_</code>属性上溯原型链,每个原型都有<code>prototype</code>,而<code>prototype</code>又有<code>constructor</code>属性来指向该原型(<code>constructor</code>主要就是用于指向确认该原型)</p><p><img src="https://static.vue-js.com/60825aa0-725e-11eb-85f6-6fac77c0c9b3.png" alt="60825aa0-725e-11eb-85f6-6fac77c0c9b3.png (721×762) "></p><h2 id="继承"><a href="#继承" class="headerlink" title="继承"></a>继承</h2><p>继承是面向对象中的一个概念,继承可以让子类具有父类的各种属性和方法,不需要再编写相同的代码,并且在子类别继承父类别的同时,可以重新定义某些属性、方法,获得不同的功能。</p><blockquote><h3 id="JS常见的继承方式:"><a href="#JS常见的继承方式:" class="headerlink" title="JS常见的继承方式:"></a>JS常见的继承方式:</h3><ul><li><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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//写法一 每一个new Child,创建出来的每一个实例改变父类属性时都会影响到父类。</span><br><span class="hljs-title class_">Child</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Parent</span>();<br><span class="hljs-comment">//写法二 创建原型链继承的现代方法</span><br><span class="hljs-title class_">Child</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span> = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">create</span>(<span class="hljs-title class_">Parent</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>)<br><span class="hljs-title class_">Child</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">constructor</span> = <span class="hljs-title class_">Child</span><br></code></pre></td></tr></table></figure></li><li><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><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs JS"><span class="hljs-keyword">function</span> <span class="hljs-title function_">Parent</span>(<span class="hljs-params">name</span>) { <br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span> = name; <span class="hljs-comment">// 设置name属性 </span><br>} <br> <br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Child</span>(<span class="hljs-params">name, age</span>) { <br> <span class="hljs-comment">// 调用父类构造函数,初始化name属性 </span><br> <span class="hljs-title class_">Parent</span>.<span class="hljs-title function_">call</span>(<span class="hljs-variable language_">this</span>, name); <br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">age</span> = age; <span class="hljs-comment">// 设置子类特有的age属性 </span><br>} <br></code></pre></td></tr></table></figure></li></ul></blockquote><h2 id="this"><a href="#this" class="headerlink" title="this"></a>this</h2><p><code>this</code>是函数的一个运行时自动生成的内部对象,只能在函数内使用,指向最后调用它的对象。</p><blockquote><h3 id="绑定规则:"><a href="#绑定规则:" class="headerlink" title="绑定规则:"></a>绑定规则:</h3><p>优先级:new绑定优先级 > 显示绑定优先级 > 隐式绑定优先级 > 默认绑定优先级</p><ul><li><p>默认绑定:全局对象会默认绑定,如果严格模式下,<code>this</code>会绑定到undefined。</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><code class="hljs js"><span class="hljs-variable language_">window</span>.<span class="hljs-property">name</span> = <span class="hljs-string">'Jenny'</span>;<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">person</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span>;<br>}<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title function_">person</span>()); <span class="hljs-comment">//Jenny,调用函数的对象</span><br></code></pre></td></tr></table></figure></li><li><p>隐式绑定:函数作为对象的某个方法调用,<code>this</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> o = {<br> <span class="hljs-attr">a</span>:<span class="hljs-number">10</span>,<br> <span class="hljs-attr">b</span>:{<br> <span class="hljs-attr">a</span>:<span class="hljs-number">7</span>,<br> <span class="hljs-attr">fn</span>:<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">a</span>); <span class="hljs-comment">//undefined</span><br> }<br> }<br>}<br>o.<span class="hljs-property">b</span>.<span class="hljs-title function_">fn</span>();<span class="hljs-comment">//7</span><br><span class="hljs-keyword">var</span> j = o.<span class="hljs-property">b</span>.<span class="hljs-property">fn</span>;<br><span class="hljs-title function_">j</span>();<span class="hljs-comment">//this指向window</span><br></code></pre></td></tr></table></figure></li><li><p>new绑定:如果用<code>new</code>构造函数生成一个实例对象,<code>this</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><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><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">test</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">x</span> = <span class="hljs-number">1</span>;<br>}<br><br><span class="hljs-keyword">var</span> obj = <span class="hljs-keyword">new</span> <span class="hljs-title function_">test</span>();<br>obj.<span class="hljs-property">x</span> <span class="hljs-comment">// 1</span><br><span class="hljs-comment">//new过程遇到return一个对象,此时this指向为返回的对象</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params"></span>) <br>{ <br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">user</span> = <span class="hljs-string">'xxx'</span>; <br> <span class="hljs-keyword">return</span> {}; <br>}<br><span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> <span class="hljs-title function_">fn</span>(); <br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a.<span class="hljs-property">user</span>); <span class="hljs-comment">//undefined</span><br><span class="hljs-comment">//如果返回一个简单类型的时候,则this指向实例对象</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params"></span>) <br>{ <br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">user</span> = <span class="hljs-string">'xxx'</span>; <br> <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;<br>}<br><span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> fn; <br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a.<span class="hljs-property">user</span>); <span class="hljs-comment">//xxx</span><br><span class="hljs-comment">//注意的是null虽然也是对象,但是此时new仍然指向实例对象</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params"></span>) <br>{ <br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">user</span> = <span class="hljs-string">'xxx'</span>; <br> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>}<br><span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> fn; <br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a.<span class="hljs-property">user</span>); <span class="hljs-comment">//xxx</span><br></code></pre></td></tr></table></figure></li><li><p>显示修改:<code>apply</code> <code>call</code> <code>bind</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> x = <span class="hljs-number">0</span>;<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">test</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">x</span>);<br>}<br> <br><span class="hljs-keyword">var</span> obj = {};<br>obj.<span class="hljs-property">x</span> = <span class="hljs-number">1</span>;<br>obj.<span class="hljs-property">m</span> = test;<br>obj.<span class="hljs-property">m</span>.<span class="hljs-title function_">apply</span>(obj) <span class="hljs-comment">// 1</span><br></code></pre></td></tr></table></figure></li></ul></blockquote><p>箭头函数的<code>this</code>在代码书写编译时就已经绑定,会捕获其定义时的词法作用域中的 <code>this</code></p><h2 id="事件与事件模型"><a href="#事件与事件模型" class="headerlink" title="事件与事件模型"></a>事件与事件模型</h2><p>JS中的事件,其实就是浏览器中发生的一种交互操作。</p><p>事件流经历三个阶段:事件捕获阶段(capture phase)、处于目标阶段(target phase)、事件冒泡阶段(bubbling phase)</p><p>事件冒泡是一种从下往上的传播方式,由处于目标阶段的触发节点逐渐向上传播到最上的节点也就是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><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><code class="hljs js"><span class="hljs-keyword">var</span> button = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">'clickMe'</span>);<br><br>button.<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'1.Button'</span>);<br>};<br><span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'2.body'</span>);<br>};<br><span class="hljs-variable language_">document</span>.<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'3.document'</span>);<br>};<br><span class="hljs-variable language_">window</span>.<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'4.window'</span>);<br>};<br><br><span class="hljs-comment">//1.button</span><br><span class="hljs-comment">//2.body</span><br><span class="hljs-comment">//3.document</span><br><span class="hljs-comment">//4.window</span><br></code></pre></td></tr></table></figure><p>事件模型可以分为三种:原始事件模型(DOM 0级)、标准事件模型(DOM 2级)、IE事件模型。</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></pre></td><td class="code"><pre><code class="hljs html">//原始事件模型<br><span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"handleClick()"</span>></span>Click me<span class="hljs-tag"></<span class="hljs-name">button</span>></span><br></code></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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//标准事件模型</span><br>element.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">'click'</span>, handleClick, useCapture);<br></code></pre></td></tr></table></figure><p>区别是原始事件模型简单,但有局限,不支持事件捕获和多个事件处理器;标准事件模型提供更多灵活性和控制。</p><h2 id="typeof与instanceof"><a href="#typeof与instanceof" class="headerlink" title="typeof与instanceof"></a>typeof与instanceof</h2><p><code>typeof</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">typeof</span> <span class="hljs-number">1</span> <span class="hljs-comment">// 'number'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-string">'1'</span> <span class="hljs-comment">// 'string'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-literal">undefined</span> <span class="hljs-comment">// 'undefined'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-literal">true</span> <span class="hljs-comment">// 'boolean'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-title class_">Symbol</span>() <span class="hljs-comment">// 'symbol'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-literal">null</span> <span class="hljs-comment">// 'object'</span><br><span class="hljs-keyword">typeof</span> [] <span class="hljs-comment">// 'object'</span><br><span class="hljs-keyword">typeof</span> {} <span class="hljs-comment">// 'object'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-variable language_">console</span> <span class="hljs-comment">// 'object'</span><br><span class="hljs-keyword">typeof</span> <span class="hljs-variable language_">console</span>.<span class="hljs-property">log</span> <span class="hljs-comment">// 'function'</span><br></code></pre></td></tr></table></figure><p><code>instanceof</code> 运算符用于检测构造函数的 <code>prototype</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">// 定义构建函数</span><br><span class="hljs-keyword">let</span> <span class="hljs-title class_">Car</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {}<br><span class="hljs-keyword">let</span> benz = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Car</span>()<br>benz <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Car</span> <span class="hljs-comment">// true</span><br><span class="hljs-keyword">let</span> car = <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(<span class="hljs-string">'xxx'</span>)<br>car <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">String</span> <span class="hljs-comment">// true</span><br><span class="hljs-keyword">let</span> str = <span class="hljs-string">'xxx'</span><br>str <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">String</span> <span class="hljs-comment">// false</span><br></code></pre></td></tr></table></figure><blockquote><h3 id="手写instanceof:"><a href="#手写instanceof:" class="headerlink" title="手写instanceof:"></a>手写instanceof:</h3><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><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">myInstanceOf</span>(<span class="hljs-params">left,right</span>){<br> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> left !== <span class="hljs-string">'object'</span>||<span class="hljs-keyword">typeof</span> left === <span class="hljs-literal">null</span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span><br> <span class="hljs-keyword">let</span> proto = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">getPrototypeOf</span>(left)<br> <span class="hljs-keyword">while</span>(<span class="hljs-literal">true</span>){<br> <span class="hljs-keyword">if</span>(proto === <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<span class="hljs-comment">//防止不是使用构造函数创建的实例</span><br> <span class="hljs-keyword">if</span>(proto === right.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>)<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span><br> proto = <span class="hljs-title class_">Object</span>.<span class="hljs-title function_">getPrototypeOf</span>(proto)<br>}<br>}<br></code></pre></td></tr></table></figure></blockquote><h2 id="事件代理"><a href="#事件代理" class="headerlink" title="事件代理"></a>事件代理</h2><p>事件委托,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,而不是目标元素。</p><p>如果我们有一个列表,列表之中有大量的列表项,我们需要在点击列表项的时候响应一个事件,如果给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的,这时候就可以事件委托,把点击事件绑定在父级元素<code>ul</code>上面,然后执行事件的时候再去匹配目标元素。</p><h2 id="New"><a href="#New" class="headerlink" title="New"></a>New</h2><p>我们使用new将一个给定的构造函数创建一个实例对象。new做了如下事情:</p><ul><li>创建一个新的对象</li><li>将对象与构造函数用原型链连起来</li><li>将构造函数的this指向对象(改变this指向的方法之一)</li></ul><blockquote><h3 id="手写new:"><a href="#手写new:" class="headerlink" title="手写new:"></a>手写new:</h3><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><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">mynew</span>(<span class="hljs-params">Fun,...args</span>){<br><span class="hljs-keyword">const</span> obj = {}<br> obj.<span class="hljs-property">_proto_</span> = <span class="hljs-title class_">Fun</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span><br> <span class="hljs-keyword">let</span> result = <span class="hljs-title class_">Fun</span>.<span class="hljs-title function_">apply</span>(obj,args)<br> <span class="hljs-keyword">return</span> result <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Object</span>?<span class="hljs-attr">result</span>:obj;<br>}<br></code></pre></td></tr></table></figure></blockquote><h2 id="事件循环"><a href="#事件循环" class="headerlink" title="事件循环"></a>事件循环</h2><p>JS中所有任务都可以分为同步任务和异步任务。其中异步任务还可以分为微任务和宏任务。</p><blockquote><h3 id="微任务和宏任务:"><a href="#微任务和宏任务:" class="headerlink" title="微任务和宏任务:"></a>微任务和宏任务:</h3><ul><li>微任务:一个需要异步执行的函数,执行时机是在当前主函数执行结束后,宏任务结束之前。例如:Promise.then、Process.nextTick</li><li>宏任务:常见的宏任务有:setTimeout/setInterval、I/O</li></ul></blockquote><hr><blockquote><h3 id="async和await:"><a href="#async和await:" class="headerlink" title="async和await:"></a>async和await:</h3><p>async函数会返回一个promise对象,await会将其后的代码化为微任务。</p></blockquote><h2 id="防抖和节流"><a href="#防抖和节流" class="headerlink" title="防抖和节流"></a>防抖和节流</h2><h1 id="杂项"><a href="#杂项" class="headerlink" title="杂项"></a>杂项</h1><h2 id="Hash算法"><a href="#Hash算法" class="headerlink" title="Hash算法"></a>Hash算法</h2><p>hash(哈希)算法是把任意长度的输入,通过算法变换成固定长度的输出。</p><blockquote><p> eg.<a href="https://leetcode.cn/problems/two-sum/description/?envType=study-plan-v2&envId=top-100-liked">两数之和</a></p></blockquote><h1 id="实际面试环节"><a href="#实际面试环节" class="headerlink" title="实际面试环节"></a>实际面试环节</h1><h2 id="10-15海康威视"><a href="#10-15海康威视" class="headerlink" title="10.15海康威视"></a>10.15海康威视</h2><ul><li><p>你的上一段实习有什么亮点/难点?</p><figure class="highlight markdown"><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><code class="hljs markdown">原答:需要对给过来的一些数据进行处理。<br><br>修正:当时作为初学者接到的任务都不是很难,主要遇到的困难有使用Element Plus样式穿刺、组件间传值这些问题。<br></code></pre></td></tr></table></figure></li><li><p>JS中常用的数据结构类型有哪些?</p><figure class="highlight markdown"><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><code class="hljs markdown">原答:7种,number,undefined,string,null,boolean,symbol,其他的类型统称object,object可能包含对象、数组、函数之类的。<br><br>修正:JS中有六种基本的数据类型,分别是number、string、boolean还有undefined、null和symbol。除此之外还有一个复杂数据类型object,它包含了对象、数组和函数等,这些对象可以用来构建更复杂的数据结构,例如链表、树等。<br></code></pre></td></tr></table></figure></li><li><p>JS怎么处理大整形类型?</p><figure class="highlight markdown"><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><code class="hljs markdown">原答:一般是用bigint,对数据转化成大整形类型之后如果需要加加减减的话就要加n,比如加一就是加一n<br><br>修正:在JS中处理大整数,可以使用BigInt类型,它允许你安全地表示和操作超出Number类型安全范围的大整数。使用BigInt时,只需要在数值后面加上n或者用BigInt()函数来创建。进行算数运算时,必须所有操作数都是BigInt类型,BigInt与Number不兼容。<br></code></pre></td></tr></table></figure></li><li><p>JS的Map和对象有什么区别?</p><figure class="highlight markdown"><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><code class="hljs markdown">原答:Map和对象的一些方法属性可能不同,比如has、get之类的。<br><br>修正:首先Map的键可以是任意类型的,对象的键在访问的时候总是被当作字符串处理。迭代顺序不同,对象是按照属性创建时间迭代,Map是按照添加到map的顺序迭代。对象没有内置方法取得键值,Map有keys,values之类的。数据规模小时使用对象,数据规模大时使用map,因为map是为了快速查找而优化的。对象有原型链,Map没有原型链。<br></code></pre></td></tr></table></figure></li><li><p>怎么获取对象的属性值?返回一个数组,数组是对象的所有值怎么写?</p><figure class="highlight pgsql"><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><code class="hljs pgsql">原答:直接用键获取就可以了,用<span class="hljs-keyword">Object</span>.<span class="hljs-keyword">values</span>()即可返回数组。<br><br>修正:可以使用<span class="hljs-keyword">Object</span>的静态方法<span class="hljs-keyword">values</span>,也可以使用forin循环中间包一个obj.hasOwnProperty(key)用于确保该键是此对象的,而不是继承下来的。<br></code></pre></td></tr></table></figure></li><li><p>对象可以直接用for of循环拿这些值吗?</p><figure class="highlight rust"><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><code class="hljs rust">原答:可以,直接用<span class="hljs-keyword">for</span> <span class="hljs-title class_">of</span>应该就可以拿到。<span class="hljs-comment">//你知道什么是可迭代对象吗?对象还可以用for of拿这些值吗?</span><br><br>修正:不可以,<span class="hljs-keyword">for</span> <span class="hljs-title class_">of</span>是用于遍历可迭代对象的每个元素,例如数组 字符串 Map Set。<span class="hljs-keyword">for</span> <span class="hljs-title class_">in</span>用于遍历一个对象的所有可枚举的属性,包括其原型链上继承的。<br></code></pre></td></tr></table></figure></li><li><p>讲一下原型链吧</p><figure class="highlight markdown"><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><code class="hljs markdown">原答:意思是说每一个对象,每一个对象构建的时候需要用构造函数去构造原型。每一个对象都有一个prototype指向它的属性,里面还有一个constructor指向他自己,如果我需要用一个构造函数去构造一个新的对象的话,新的对象也会有一个<span class="hljs-emphasis">_proto_</span>指向原来的构造函数,如果想要获取一开始的构造函数的话,可以用原型链溯源往上找。<br><br>修正:原型链是一个用于实现继承的机制,每个对象都有一个内部属性,叫做prototype,这个内部属性引用了另一个对象,称为该对象的原型,代码中一般用getPrototypeOf去获取。这个对象的原型又有一个原型,这样一直往上就是原型链。如果想要访问一个对象的属性时,该对象本身没有这个属性,JS会沿着原型链网上找直到找到或者达到末端。<br></code></pre></td></tr></table></figure></li><li><p>你有一个实例,怎么通过这个实例拿到他的构造函数?</p><figure class="highlight awk"><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><code class="hljs awk">原答:可以通过循环访问_proto_去找他的原型,如果寻找到的原型的prototype和实例的相同,那就说明这是他的构造函数。<span class="hljs-regexp">//</span>不对,八股文背得太浅了,没有理解本质<br><br>修正:可以使用对象.constructor获取其构造函数,但是这个值其实可以被覆盖的。如果需要更稳健的方法,那可能得创建实例的时候就保存这个引用关系。<br></code></pre></td></tr></table></figure></li><li><p>什么是构造函数,什么是原型对象?</p><figure class="highlight haxe"><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><code class="hljs haxe">原答:构造函数就是用于构造对象的函数,原型对象就是你要创建一个实例的一个对象,比如我<span class="hljs-keyword">new</span> <span class="hljs-type">Person</span>(),Person就是他的原型对象。<br><br>修正:构造函数是用于创建函数的函数,当用<span class="hljs-keyword">new</span><span class="hljs-type"></span>关键字调用了一个函数时,这个函数就成为了一个构造函数。构造函数会创建一个新的对象,这个对象会继承构造函数prototype的属性和方法。原型对象是指某个对象中prototype所指向的对象,每个对象都有一个对象原型,该对象从其对象原型中继承相关的属性和方法。<br></code></pre></td></tr></table></figure></li><li><p>在Vue场景下,让你封装一个Vue组件,组件实现一个登录表单界面,一个name一个password,要求创建一个子组件给别人用,别人通过v-model传进来,你的表单里也是有一个name和password,如果后续你的表单扩了,后续别人也是通过v-model传,你的这个自定义组件的v-model怎么实现?</p><figure class="highlight awk"><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><code class="hljs awk">原答:不太理解 <br><span class="hljs-regexp">//</span>那你v-model怎么用的? <br>原答:绑定我所需要的一些input之类的 <br><span class="hljs-regexp">//</span>那自己写的组件不可以用v-model吗? <br>原答:直接赋值不就行了吗?<br><span class="hljs-regexp">//</span>什么是v-model<br>原答:是用vue的时候写在盒子里的用于双向绑定的。<br><span class="hljs-regexp">//</span>那如果我绑定在你自定义的属性上面呢?v-model是为了解决什么问题?<br>原答:是为了解决视图到模型的问题吧<br><br>修正:可以使用一个对象来作为v-model的值,并且为每一个属性创建一个input事件,这样在调用这个组件的时候外面只管传一个对象即可。<br><br>修正:v-model是用于表单输入和应用状态之间创建数据双向绑定,对于自定义组件,可以使用defineModel来简化v-model,接收传入的值和及时返回改变的值。<br></code></pre></td></tr></table></figure></li></ul><h2 id="10-16云合智网"><a href="#10-16云合智网" class="headerlink" title="10.16云合智网"></a>10.16云合智网</h2><ul><li><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><code class="hljs javascript">原答:用过<span class="hljs-title class_">Map</span>之类的,和箭头函数。<br><br>修正:使用过箭头函数、模板字符串、解构赋值、<span class="hljs-title class_">Promise</span>异步、<span class="hljs-keyword">let</span>和<span class="hljs-keyword">const</span>、<span class="hljs-title class_">Map</span>等。<br></code></pre></td></tr></table></figure></li><li><p>能说一下箭头函数有哪些优势吗?</p><figure class="highlight kotlin"><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><code class="hljs kotlin">原答:箭头函数和普通函数的区别是写法不同,箭头函数的<span class="hljs-keyword">this</span>指向它本身,普通函数的<span class="hljs-keyword">this</span>按照JS规定指向,普通函数可以用new去构造,箭头函数不可以。<br><br>修正:箭头函数的出现让函数的书写变得很简洁,除此之外还解决了<span class="hljs-keyword">this</span>执行环境所造成的一些问题,比如匿名函数和setTimeout的<span class="hljs-keyword">this</span>指向问题。<br></code></pre></td></tr></table></figure></li><li><p>Map的键可以有哪些类型?</p><figure class="highlight arcade"><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><code class="hljs arcade">原答:<span class="hljs-built_in">Map</span>的键可以是任何类型,如果是对象就不可以,对象的键只能被读为字符串。<br><br>(无修正,答得挺好的,下次加油)<br></code></pre></td></tr></table></figure></li><li><p>call、apply和bind的区别?</p><figure class="highlight gradle"><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><code class="hljs gradle">原答:这三者都是用于改变<span class="hljs-keyword">this</span>的指向,<span class="hljs-keyword">call</span>传入两个值,第一个值是指向的对象,第二个值传入一个参数。apply第二个值是传入的数组,然后bind就是直接返回指向的对象。<br><br>修正:这三个函数都用于改变<span class="hljs-keyword">this</span>指向,他们三个都是函数对象的静态方法,当一个函数调用<span class="hljs-keyword">call</span>的时候,会把函数中的<span class="hljs-keyword">this</span>指向改为传入的第一个对象值,还能接受一系列参数,这些参数会传递给函数。apply的用法和<span class="hljs-keyword">call</span>差不多,但是他不再接受一系列参数而是一个数组。bind和<span class="hljs-keyword">call</span>用法一样,但是返回一个新函数可以稍后调用。<br></code></pre></td></tr></table></figure></li><li><p>有没有了解过let、const和var有什么区别?</p><figure class="highlight csharp"><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><code class="hljs csharp">原答:<span class="hljs-keyword">let</span>和<span class="hljs-keyword">const</span>是ES6新增的特性,是块级元素;<span class="hljs-keyword">var</span>一般作用域全局变量。<span class="hljs-keyword">let</span>的值是可变的,<span class="hljs-keyword">const</span>的值是不可变的,如果你想要试图改变它的话会报错。<span class="hljs-comment">//那如果const定义一个对象,那么我们可以改变这个对象里属性的值吗?</span><br>原答:可以的<br><br>修正:<span class="hljs-keyword">var</span>变量具有函数作用域,但是<span class="hljs-keyword">let</span>和<span class="hljs-keyword">const</span>是块级作用域;<span class="hljs-keyword">let</span>和<span class="hljs-keyword">var</span>可以被重新赋值,<span class="hljs-keyword">const</span>不能被重新赋值,但这不代表它指向的引用类型比如对象或数组内容不能改变。当<span class="hljs-keyword">var</span>在全局作用域下声明变量的时候,这个变量会变成全局对象的属性,<span class="hljs-keyword">let</span>和<span class="hljs-keyword">const</span>就不会。<br></code></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></pre></td><td class="code"><pre><code class="hljs javascript">原答:getPrototypeOf,通过获取某个对象的原型的属性和方法来进行深拷贝。<span class="hljs-comment">//还有别的吗</span><br><br>修正:<span class="hljs-title class_">JSON</span>.<span class="hljs-property">stringify</span>+<span class="hljs-title class_">JSON</span>.<span class="hljs-property">parse</span>序列化加反序列化可以深拷贝,但是这种方法不可以复制函数、<span class="hljs-literal">undefined</span>和循环引用。有些对象比如日期对象 正则对象可以使用他们的拷贝构造函数来进行深拷贝。还有一种方法就是手写递归拷贝。(一定要会手写)<br></code></pre></td></tr></table></figure></li><li><p>有没有了解过闭包?</p><figure class="highlight less"><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><code class="hljs less">原答:假如在函数<span class="hljs-selector-tag">a</span>中定义了一个函数<span class="hljs-selector-tag">b</span>,<span class="hljs-selector-tag">b</span>中可以用到<span class="hljs-selector-tag">a</span>定义的量。<span class="hljs-comment">//什么时候使用闭包?</span><br>原答:用于构建私有变量,用于...说不出,可以举个例子。...(但是举错了,把延长变量存在时间的例子举成了构建私有变量的了。)<br><br>修正:(答得挺好的,把例子举完整即可)<br></code></pre></td></tr></table></figure></li><li><p>有没有用过splice这个函数?</p><figure class="highlight arcade"><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><code class="hljs arcade">原答:用过,<span class="hljs-built_in">splice</span>对数组进行操作,第一个值是指要操作的索引,第二个值是要删除元素的数量,<span class="hljs-built_in">splice</span>会从该索引后删除指定数量的元素,第三个值是值删除后在这个位置添加的数组。<br><br>(无修正,答得挺好的,下次加油)<br></code></pre></td></tr></table></figure></li><li><p>有没有了解过事件冒泡?</p><figure class="highlight arduino"><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><code class="hljs arduino">原答:在DOM中有三个阶段,第一个是啥来着,会去找那个事件,从最高的window往下找,一直找到那个事件,然后进入处于目标状态,比如click获得这个事件的状态,然后再往上冒泡,再从最小的盒子再冒泡到全局变量。<br><br>修正:当在DOM树中触发了一个事件,比如点击或键盘输入,这个事件会经历三个阶段:分别是事件捕获、目标阶段、事件冒泡。事件捕获会从文档的根节点开始一直传播到目标元素本身。然后就到了目标阶段,这里就是事件实际发生的地方。然后就从目标元素开始向上冒泡,一直冒泡到根元素,我们可以在目标元素以上的祖先元素设置事件监听器来响应事件。<br></code></pre></td></tr></table></figure></li><li><p>你用过HTML5吗,用过里面什么东西?</p><figure class="highlight typescript"><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><code class="hljs typescript">原答:...(不确定是不是<span class="hljs-title class_">HTML5</span>的)<br><br>修正:用过header、footer等语义元素,有助于搜索引擎优化。用过<span class="hljs-variable constant_">H5</span>的一些新表单类型,比如<span class="hljs-keyword">type</span>=email、url、<span class="hljs-built_in">number</span>。用过video元素嵌入视频。用过canvas绘制图形。用过<span class="hljs-variable language_">localStorage</span>和<span class="hljs-variable language_">sessionStorage</span>存储数据。<br></code></pre></td></tr></table></figure></li><li><p>有接触过HTML5的websocket吗?</p><figure class="highlight livecodeserver"><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><code class="hljs livecodeserver">原答:我拿它和平时我们用的一些协议来对比吧,比如我们平时用的是Http、Https,然后用<span class="hljs-built_in">get</span>、<span class="hljs-built_in">post</span>传请求,这种只能是一次过一次回这样之类的,但是websocket是进行一个长线链接,比如说我要做一个聊天网站,我在这边发,另一台电脑也会马上同步信息过去,这就是平时websocket需要用到的一个场景。<br><br>修正:websocket提供了一种在单个TCP连接上进行全双工通信的方法,这就意味着服务器和客户端可以同时发送和接收数据,这和传统的<span class="hljs-keyword">http</span>响应模式不同,<span class="hljs-keyword">http</span>通常只支持客户端到服务器的单向通信。<br></code></pre></td></tr></table></figure></li><li><p>你对Http协议了解得多吗?</p><figure class="highlight livecodeserver"><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><code class="hljs livecodeserver">原答:只了解一点<span class="hljs-comment">点//现在最新的版本是多少?</span><br>原答:http2吧好像到<span class="hljs-number">3</span>了。<br><br>修正:<span class="hljs-keyword">http</span>叫做超文本传输协议,是实现网络通信的一种规范,是万维网的数据通信的基础。最新的版本是<span class="hljs-number">2022</span>年刚更新的http3,添加的一些特性包括改用基于UDP的QUIC协议作为传输层协议,取代了传统的TCP协议。quick UDP <span class="hljs-keyword">internet</span> connections整合了TCP的可靠性和UDP的低延迟性,同时还提供TLS加密。QUIC还允许IP地址变化的情况下保持连接状态,提供了更高效的重传机制,能够更快地检测和回复丢包。<br></code></pre></td></tr></table></figure></li><li><p>有了解过https和http的区别吗?</p><figure class="highlight livecodeserver"><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><code class="hljs livecodeserver">原答:<span class="hljs-keyword">https</span>简单来说就是<span class="hljs-keyword">http</span>+TLS/SSL 因为<span class="hljs-keyword">http</span>本身是不安全的,<span class="hljs-keyword">https</span>相当于在<span class="hljs-keyword">http</span>上进行了一个加密,需要在网站上获取证书啊,去进行一个传来的密文的解密。<br><br>修正:<span class="hljs-keyword">http</span>的信息传输是明文进行的,没有进行加密处理。<span class="hljs-keyword">https</span>在<span class="hljs-keyword">http</span>的基础上加入了SSL/TLS协议,连接的时候需要进行额外的握手过程,保证一定安全但也会消耗一些性能。<span class="hljs-keyword">http</span>的端口默认使用<span class="hljs-number">80</span>,<span class="hljs-keyword">https</span>的端口默认使用<span class="hljs-number">443</span>。<span class="hljs-keyword">http</span>不需要申请证书,<span class="hljs-keyword">https</span>需要。搜索引擎策略会给<span class="hljs-keyword">https</span>的网站更高的曝光度。<br></code></pre></td></tr></table></figure></li><li><p>有没有了解过https加密用的是什么算法呢?</p><figure class="highlight arcade"><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><code class="hljs arcade">原答:没有<br><br>修正:主要用非对称加密算法例如公钥私钥、对称加密算法例如三重数据加密算法、<span class="hljs-built_in">hash</span>算法去加密。<br></code></pre></td></tr></table></figure></li><li><p>有了解过http请求方法有哪些吗?</p><figure class="highlight pgsql"><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><code class="hljs pgsql">原答:常用的<span class="hljs-keyword">get</span> post,不常用的push <span class="hljs-keyword">delete</span>之类的<br><br>修正:<span class="hljs-keyword">GET</span>方法用于从服务器获取数据,POST方法用于向服务器发送数据,PUT用于向服务器发送数据用以替换内容,<span class="hljs-keyword">DELETE</span>用于请求服务器删除资源,<span class="hljs-keyword">OPTIONS</span>用于返回服务器支持的HTTP方法及查看服务器性能,TRACE方法用于回显服务器收到的请求,用于调试。<br></code></pre></td></tr></table></figure></li><li><p>有了解过get post有什么区别吗?</p><figure class="highlight stata"><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><code class="hljs stata">原答:getpost平时我们用的时候都是要有请求头的,然后<span class="hljs-keyword">post</span>是可以传一个请求内容的。<br><br>修正:GET主要是向服务器获取数据,在url明文传递内容,不安全,且只能传输ASCII字符。<span class="hljs-keyword">POST</span>主要是向服务器提交数据,在请求体中传递内容,可以传输多种数据类型,比如文本,二进制文件。<br></code></pre></td></tr></table></figure></li><li><p>有了解过常见的http响应码有哪些吗?</p><figure class="highlight pgsql"><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><code class="hljs pgsql">原答:<span class="hljs-number">200</span>开头的就是服务正常,<span class="hljs-number">300</span>开头没怎么见过,<span class="hljs-number">400</span>开头比如<span class="hljs-number">404</span> <span class="hljs-number">405</span><span class="hljs-keyword">Method</span> <span class="hljs-keyword">Not</span> Allow这种一般是前端路由这边的一些问题,<span class="hljs-number">500</span>开头一般是服务器那边的问题。<br><br>修正:<span class="hljs-number">100</span>是服务器已经接收到请求的一部分;<span class="hljs-number">2</span>xx是成功响应码,例如<span class="hljs-number">200</span>是成功;<span class="hljs-number">3</span>xx是重定向响应码,例如<span class="hljs-number">301</span>表示请求的资源已经被移动到新的url,会返回新的url;<span class="hljs-number">4</span>xx是客户端错误,例如<span class="hljs-number">400</span>bad request错误的参数或地址,服务器理解不了,<span class="hljs-number">403</span>forbidden服务器拒绝请求,<span class="hljs-number">404</span><span class="hljs-keyword">not</span> <span class="hljs-built_in">found</span>找不到资源,<span class="hljs-number">405</span><span class="hljs-keyword">method</span> <span class="hljs-keyword">not</span> allow请求方法服务器不允许;<span class="hljs-number">5</span>xx是服务器错误,例如<span class="hljs-number">500</span>是服务器错误,<span class="hljs-number">503</span>是服务器超载。<br></code></pre></td></tr></table></figure></li><li><p>有没有了解Vue中computed和watch有什么区别?</p><figure class="highlight angelscript"><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><code class="hljs angelscript">原答:计算属性不太了解,watch是用于监听<span class="hljs-built_in">ref</span>属性的改变,如果改变的话就会执行后续的相应函数。<br><br>修正:computed属性是基于其他其他的响应式数据动态计算并返回一个新的值,有缓存功能,只有当其依赖的数据发生变化时,才会重新计算,通常用于一个属性受到多个属性影响。watch属性是监听某个响应式属性,没有缓存功能,一旦监听的值改变就会发生回调,通常用于一个属性影响多个属性。<br></code></pre></td></tr></table></figure></li><li><p>写v-for的时候一般会加一个key,为什么?</p><figure class="highlight lsl"><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><code class="hljs lsl">原答:<span class="hljs-type">key</span>是用于和v-for一起去遍历盒子的<br><br>修正:<span class="hljs-type">key</span>作为唯一标识,可以帮助vue快速定位到需要更新的DOM元素,提高渲染效率。同时还需要选择稳定的<span class="hljs-type">key</span>去保持每个列表值与其对应的组件实例的稳定关系。<br></code></pre></td></tr></table></figure></li><li><p>如果你的vue项目中遇到兄弟组件之间的通信,你会用什么方法呢?</p><figure class="highlight lasso"><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><code class="hljs lasso">原答:用一些相关的插件比如pinia,可以让父传子props再用子传父emit<br><br>修正:使用父传子props再用子传父$emit,如果是祖先组件传给后代组件可以用<span class="hljs-keyword">provide</span>和inject,如果是那种没什么关系的组件传值的话,一般用全局总线库或者pinia。<br></code></pre></td></tr></table></figure></li><li><p>有部署过项目嘛,用什么Web容器呢?</p><figure class="highlight"><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><code class="hljs">原答:直接把文件传到服务器中,然后用nginx去部署的<br><br>修正:使用Nginx部署。(常见的还有tomcat,但是没用过就不强答了。)<br></code></pre></td></tr></table></figure></li><li><p>那你改过nginx的配置嘛?</p><figure class="highlight glsl"><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><code class="hljs glsl">原答:改过端口号和<span class="hljs-keyword">index</span>页面和<span class="hljs-keyword">location</span>指向我的文件夹。<br><br>修正:监听端口、<span class="hljs-keyword">location</span>块、SSL/TLS证书和密钥。<br></code></pre></td></tr></table></figure></li><li><p>平常有接触linux?</p><figure class="highlight"><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><code class="hljs">原答:接触得少<br><br>(没什么好说的,不是一下子能提升的)<br></code></pre></td></tr></table></figure></li><li><p>听说过docker容器嘛?</p><figure class="highlight"><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><code class="hljs">原答:听说过,相当于我这边写好了,然后用docker把我这边的环境什么的打包给别人。<br><br>修正:Docker容器中包含应用程序所需要的一切运行条件,包括代码、系统工具和库等,它可以解决同一个代码放我这里能跑放别人电脑跑不了的情况。<br></code></pre></td></tr></table></figure></li><li><p>有没有用过集成持续部署的软件,比如说Jenkins</p><figure class="highlight mipsasm"><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><code class="hljs mipsasm">原答:没有用过<br><br>修正:用过Gitlab,知道<span class="hljs-keyword">jenkins,Gitlab可以将gitlab仓库的代码持续集成和部署。 </span><br></code></pre></td></tr></table></figure></li><li><p>平常CSS写得多嘛,相对定位和绝对定位解释一下</p><figure class="highlight scss"><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><code class="hljs scss">原答:一般是给父盒子相对定位,然后想要使用绝对定位,需要给父元素设置相对定位才能使用绝对定位,绝对定位是相对于父元素的。<br><br>修正:相对定位的通过<span class="hljs-attribute">position</span> relative设置,设置之后改动偏移量盒子会偏移,但是它还是占据原来的位置。设置绝对定位是<span class="hljs-attribute">position</span> absolute,需要给他父元素设置相对定位,绝对定位就会完全脱离文档流,不再占据原来的空间。根据偏移量移动。<br></code></pre></td></tr></table></figure></li><li><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><code class="hljs css">原答:比如说常用的<span class="hljs-attribute">justify-content</span>、align-item。<span class="hljs-attribute">flex-wrap</span>可以对子元素进行换行处理。<br><br>修正:用过,比如<span class="hljs-attribute">flex-direction</span>决定主轴方向,<span class="hljs-attribute">flex-wrap</span>决定子元素是否换行,<span class="hljs-attribute">justify-content</span>决定主轴的对齐方式,<span class="hljs-attribute">align-items</span>决定和主轴交叉的那个轴的对齐方式。<br></code></pre></td></tr></table></figure></li><li><p>算法题:100~999的水仙花数</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//原答:</span><br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">100</span>; i < <span class="hljs-number">999</span>; i++){<br> <span class="hljs-keyword">let</span> sum = <span class="hljs-number">0</span><br> <span class="hljs-keyword">let</span> temp = i<br> <span class="hljs-keyword">while</span> (temp > <span class="hljs-number">0</span>) {<br> sum += (temp % <span class="hljs-number">10</span>) ** <span class="hljs-number">3</span><br> temp = <span class="hljs-built_in">parseInt</span>(temp/<span class="hljs-number">10</span>)<br> }<br> <span class="hljs-keyword">if</span>(sum === i)<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(i);<br>}<br><br><span class="hljs-comment">//(挺好的)</span><br></code></pre></td></tr></table></figure></li></ul>]]></content>
<categories>
<category>随笔</category>
</categories>
<tags>
<tag>😶🌫️</tag>
</tags>
</entry>
<entry>
<title>Eventstorm</title>
<link href="/2024/07/01/Eventstorm/"/>
<url>/2024/07/01/Eventstorm/</url>
<content type="html"><![CDATA[<h1 id="简介及概念"><a href="#简介及概念" class="headerlink" title="简介及概念"></a>简介及概念</h1><p>什么是事件风暴?</p><p>事件风暴是一场发现事件模型的头脑风暴会议,通过领域专家、产品经理和技术人员共同头碰头的群策群力,以事件模型为主要线索,发现业务系统中发生的代表重要事实的重要事件。</p><p>事件风暴是Alberto Brandolini的心血结晶,它是Gamestorming和领域驱动设计(DDD)原则的综合学习实践。</p><blockquote><p>领域驱动设计(DDD,Domain-Driven Design)是一种通过将实现连接到持续进化的模型来满足复杂需求的软件开发方法。</p><p>领域驱动设计的前提是:</p><ul><li>把项目的主要重点放在核心领域(core domain)和域逻辑。</li><li>把复杂的设计放在有界域(bounded context)的模型上。</li><li>发起一个创造性的合作之间的技术和域界专家以迭代地完善的概念模式,解决特定领域的问题。</li></ul></blockquote><p>事件风暴催化并加速小组学习,通常在几小时或几天内实现更传统的建模技术从未做过的事情。</p><p>事件风暴使用简单的便利贴来实现。</p><h1 id="特点及用处"><a href="#特点及用处" class="headerlink" title="特点及用处"></a>特点及用处</h1><h2 id="快速"><a href="#快速" class="headerlink" title="快速"></a>快速</h2><p>事件风暴能够很快的(通常只需几天或几个小时)搭建出业务流程的模型。</p><h2 id="清晰"><a href="#清晰" class="headerlink" title="清晰"></a>清晰</h2><p>通过多角色对于业务流程的完善,事件风暴使得整个模型显得尤为清晰,在我看来,他更像是把业务专注于“业务”本身。</p><p>我为什么这么说呢 -> 如果我们正常对模型进行搭建的时候,可能是靠自己(或者是某个部门)对整个业务进行模拟:我需要什么,我要做什么。虽然这是我们能够做到最好的情况了,但是因为业务不止需要一个部门去实现,这样做往往会导致我们一开始看起来很合适的的某个部分,在别的人眼里显得非常的怪异。</p><p>这就催生出了事件风暴,对于业务模型中的事件,不同的人有不同的答案。</p><h2 id="简单"><a href="#简单" class="headerlink" title="简单"></a>简单</h2><p>事件风暴具有简单的特性,对于没有编程背景的人,只需一点点的逻辑性就可以参与进来,这对于业务开发是十分高效且合理的。</p><h1 id="核心概念"><a href="#核心概念" class="headerlink" title="核心概念"></a>核心概念</h1><h2 id="领域事件-Event"><a href="#领域事件-Event" class="headerlink" title="领域事件 Event"></a>领域事件 Event</h2><ul><li>指正在探索的领域的相关事件,命名需要代表深刻的业务领域含义。</li></ul><h2 id="参与者-Actor"><a href="#参与者-Actor" class="headerlink" title="参与者 Actor"></a>参与者 Actor</h2><ul><li>指涉及领域事件的的人员,一组人、一个团队或者某个人。(也可以说是对应探索领域的用户)</li></ul><h2 id="外部系统-External-System"><a href="#外部系统-External-System" class="headerlink" title="外部系统 External System"></a>外部系统 External System</h2><ul><li>可部署的IT系统,我认为是用于补充actor,比如事件的触发可能是通过外部第三方系统产生。</li></ul><h2 id="策略-Policy"><a href="#策略-Policy" class="headerlink" title="策略 Policy"></a>策略 Policy</h2><ul><li>根据业务约束或者是规则自动或手动触发。</li></ul><h2 id="命令-Command"><a href="#命令-Command" class="headerlink" title="命令 Command"></a>命令 Command</h2><ul><li>代表行动、意图,指一个触发器。</li></ul><h2 id="读模型-Read-Model"><a href="#读模型-Read-Model" class="headerlink" title="读模型 Read Model"></a>读模型 Read Model</h2><ul><li>参与者需要某些信息做出决策,通过读模型来获取这些信息。</li></ul><h2 id="聚合-Aggregate"><a href="#聚合-Aggregate" class="headerlink" title="聚合 Aggregate"></a>聚合 Aggregate</h2><ul><li>一个对象群体、一类对象的总称。</li></ul><h1 id="流程"><a href="#流程" class="headerlink" title="流程"></a>流程</h1><h2 id="事件风暴会议开始"><a href="#事件风暴会议开始" class="headerlink" title="事件风暴会议开始"></a>事件风暴会议开始</h2><p>在主持人的指导下,与业务专家开始梳理当前的业务中有哪些领域事件。(即已经发生需要保存下来的那些事实)。</p><p>只有先找到发生的事实,将其标记为领域事件,才能发现这些事实涉及哪些对象,对象之间的结构边界才能得到划分,而划分了边界的对象才可能是DDD中的限界上下文。</p><p>针对每一个领域事件,项目组成员围绕它进行业务分析,增加各种命令与事件,进行思考与之相关的资源、外部系统与时间。</p><h2 id="按照时间线组织事件"><a href="#按照时间线组织事件" class="headerlink" title="按照时间线组织事件"></a>按照时间线组织事件</h2><p>按照用户使用业务的时间线进行事件组织,由这些事件组成合理的故事。</p><h2 id="加入界面以及命令"><a href="#加入界面以及命令" class="headerlink" title="加入界面以及命令"></a>加入界面以及命令</h2><p>事件由命令触发,来源可以是用户或者是外部系统。</p><h2 id="加入聚合关联命令和事件"><a href="#加入聚合关联命令和事件" class="headerlink" title="加入聚合关联命令和事件"></a>加入聚合关联命令和事件</h2><p>加入聚合后,可以继续完善缺失的事件。</p><h2 id="识别核心子域"><a href="#识别核心子域" class="headerlink" title="识别核心子域"></a>识别核心子域</h2><p>每一个核心子域都是一个完善的微服务,我们要做的是把这些子域分开,各子域之间不能相互依赖太多,修改时会相互牵扯。</p>]]></content>
<categories>
<category>工具使用</category>
</categories>
<tags>
<tag>工具</tag>
<tag>笔记</tag>
<tag>架构</tag>
</tags>
</entry>
<entry>
<title>React</title>
<link href="/2024/06/24/React/"/>
<url>/2024/06/24/React/</url>
<content type="html"><![CDATA[<p>本笔记是基于已有一定前端基础的情况下做的,如果看不懂建议看官方文档,还是看不懂建议上视频平台找博主视频手把手教。</p><blockquote><p>have fun😗</p></blockquote><h1 id="Next框架"><a href="#Next框架" class="headerlink" title="Next框架"></a>Next框架</h1><p>next对于react教程简单易懂,是我目前见过最友好的文档了,next补全了react的文档可以这么说。它不仅教你自己的脚手架怎么使用,还教你更新node、使用ts及tailwindcss,甚至还会让你跟着他一点点的改代码显示改出来的效果,让你答题恢复注意力,就和哄幼儿园的宝宝一样。</p><p>链接<a href="https://nextjs.org/learn/dashboard-app/getting-started">Learn Next.js: Getting Started | Next.js (nextjs.org)</a></p><blockquote><p>clsx库<a href="https://www.npmjs.com/package/clsx">clsx - npm (npmjs.com)</a> 可以结合JS/TS 条件更换样式</p></blockquote><blockquote><p>next 自带的组件库很好用嘞</p></blockquote><h2 id="页面路由"><a href="#页面路由" class="headerlink" title="页面路由"></a>页面路由</h2><p>对于<code>page.tsx</code>,它 是一个特殊的Next.js文件,用于导出 React 组件,并且需要它才能访问路由。</p><p>相当于你在app里面创建一个新的文件夹<code>new</code>下面放<code>page.tsx</code>后,访问页面路由<code>/new</code>就可以看到这个页面,他是文件夹形式的路由安排,而vite是将一份新的js文件如<code>route.js</code>写上页面的逻辑。</p><blockquote><p> next允许在不知道路由名称的时候创建路由,使用方括号<code>[]</code>设置。</p></blockquote><p>同样的对于css样式,next使用<code>layout.tsx</code>文件进行编写。这样就可以实现主页里的小页面进行更换了。</p><blockquote><p>对于/app/layout.tsx,其引用的文件是全局适用的,这被称为<code>根布局</code>。</p></blockquote><p>Link组件可以让用户在应用程序中页面链接。</p><blockquote><p>值得一提的是为了改善导航体验,Next.js 会自动按路由段对应用程序进行代码拆分。这与传统的 React SPA 不同,在传统的 React SPA 中,浏览器会在初始加载时加载所有应用程序代码。</p><p>按路由拆分代码意味着页面变得孤立。如果某个页面抛出错误,应用程序的其余部分仍将正常工作。</p></blockquote><p>在实际开发中我们经常会遇到需要用到路由name的时候,对于vue我们可以从我们写的路由js文件中找到<code>$route.path</code>等方式获取路由名称。而对于react,可以使用<code>usePathname()</code>的钩子来实现这个操作。</p><blockquote><p>添加 ‘use client’ 在文件顶部可以将此模块机器传递的依赖标记为客户端代码。 这些组件在用户设备上运行,并且可以使用浏览器API和React的状态和效果钩子,相对应的是’use server’。</p></blockquote><blockquote><p>tips:在第六章设置数据库那里,部署到vercel上会在seed组件报错,只需要删掉seed目录即可。详见<a href="https://github.com/vercel/next-learn/issues/768">Issue #768</a></p><p>同样的,当数据库配置好了之后再下下来/seed路径及其文件然后继续即可。</p></blockquote><h2 id="流媒体"><a href="#流媒体" class="headerlink" title="流媒体"></a>流媒体</h2><p>流式处理是一种数据传输技术,它允许您将路由分解为更小的“块”,并在它们准备就绪时逐步将它们从服务器流式传输到客户端。</p><blockquote><p>在next中loading.tsx是一个特殊的页面,会在对应页面加载时显示。</p></blockquote><p>React Suspense 可以更为精细的控制流媒体。</p><figure class="highlight tsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs tsx"><span class="hljs-keyword">import</span> { <span class="hljs-title class_">Suspense</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;<br></code></pre></td></tr></table></figure><p>这样做之后就可以用suspense标签包住想要精细化控制显示的路由了。</p><h2 id="部分预渲染"><a href="#部分预渲染" class="headerlink" title="部分预渲染"></a>部分预渲染</h2><p>Next.js 14 引入了部分预渲染的实验版本——一种新的渲染模型,允许在同一路线中结合静态和动态渲染的优势。</p><figure class="highlight tsx"><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><code class="hljs tsx"><span class="hljs-comment">//next.config.mjs</span><br> <br><span class="hljs-keyword">const</span> nextConfig = {<br> <span class="hljs-attr">experimental</span>: {<br> <span class="hljs-attr">ppr</span>: <span class="hljs-string">'incremental'</span>,<br> },<br>};<br> <br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> nextConfig;<br><br><span class="hljs-comment">//组件</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> experimental_ppr = <span class="hljs-literal">true</span>;<br></code></pre></td></tr></table></figure><h2 id="搜索"><a href="#搜索" class="headerlink" title="搜索"></a>搜索</h2><p>这里采用URL搜索参数,以下是好处:</p><ul><li>可添加书签和可共享的 URL:由于搜索参数位于 URL 中,因此用户可以为应用程序的当前状态添加书签,包括其搜索查询和筛选器,以供将来参考或共享。</li><li>服务器端渲染和初始加载:可以直接在服务器上使用 URL 参数来渲染初始状态,从而更轻松地处理服务器渲染。</li><li>分析和跟踪:直接在 URL 中进行搜索查询和筛选,可以更轻松地跟踪用户行为,而无需额外的客户端逻辑。</li></ul><p>接下来我们要做的就是:</p><ul><li>获取用户的输入</li><li>使用搜索参数更新URL</li><li>保持URL和输入同步</li><li>更新表</li></ul><blockquote><p><code>URLSearchParams</code> 是一个 Web API,它提供用于操作 URL 查询参数的实用工具方法。可以使用它来获取参数字符串,而不是创建复杂的字符串文本,例如 <code>?page=1&query=a</code></p></blockquote><h3 id="消抖"><a href="#消抖" class="headerlink" title="消抖"></a>消抖</h3><p>在我们一开始handleSearch中,加入<code>console.log</code>测试,但是在控制台中输入<code>你好</code>我们可以看到:</p><figure class="highlight markdown"><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><code class="hljs markdown">n<br>ni<br>ni'h<br>ni'ha<br>ni'hao<br>你好<br></code></pre></td></tr></table></figure><blockquote><p>因为每次敲击键盘的时候都会更新URL,所以每次更新都会查询数据库,这明显是不合适的。</p></blockquote><p>我们采用停止键入延迟固定时间后才运行代码的方式进行消抖。</p><h2 id="处理错误"><a href="#处理错误" class="headerlink" title="处理错误"></a>处理错误</h2><p>对于正常遇到的错误,我们需要对其进行处理。</p><blockquote><p>在next中error.tsx是一个特殊的页面,会在对应页面错误时显示。</p></blockquote><p>如果是404页面,我们也许可以进行一些特殊处理。</p><figure class="highlight tsx"><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><code class="hljs tsx"><span class="hljs-keyword">import</span> { notFound } <span class="hljs-keyword">from</span> <span class="hljs-string">'next/navigation'</span>;<br><span class="hljs-comment">//判断并调用</span><br><span class="hljs-title function_">notFound</span>();<br></code></pre></td></tr></table></figure><p>并在根目录下添加not-found.tsx,就在可以404返回状态下触发了。</p>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
</tags>
</entry>
<entry>
<title>MiniProgram</title>
<link href="/2024/04/30/MiniProgram/"/>
<url>/2024/04/30/MiniProgram/</url>
<content type="html"><![CDATA[<h1 id="踩坑的小笔记,不需要细看"><a href="#踩坑的小笔记,不需要细看" class="headerlink" title="踩坑的小笔记,不需要细看"></a>踩坑的小笔记,不需要细看</h1><p>发现运行打不开,说要配置好小程序的AppId,一个身份证号、一个手机号只能注册5个小程序。</p><blockquote><p>管理员身份验证还卡了我一下,说是要重新绑定一遍银行卡,成了。</p></blockquote><p>uniapp运行又打不开,要到微信开发者工具那里设置端口开放,全部关掉重开才行。</p><p>想用element-plus 好,他不给用;想用pinia,好,还是报错,刚刚问了一下,tailwind也是不能用的。哈哈。</p><p>去网上搜索了一下,原来uniapp本来就没什么好用的UI库,难绷。uniapp的风评更是依托。看到这我打算直接转回原生开发平台开发了。</p><p>哈哈。原本以为可以爽复制粘贴的项目,重构吧。</p><h2 id=""><a href="#" class="headerlink" title=""></a></h2><p>问题一:阿里的icon引不了,需要去icon库里下载,然后将download好的文件放入工作区,新建一个<code>iconfont.wxss</code>复制<code>iconfont.css</code>的内容。在<code>app.wxss</code>中<code>@import</code>引入<code>iconfont.wxss</code>。</p><p>还需要把最新的链接<code>@font-face</code>复制粘贴替换掉</p><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><code class="hljs html">//在wxml文件中 iconfont表示iconfont.wxss中默认引入源 icon-name表示图标类名,可以在下载的包的html中查看<br><span class="hljs-tag"><<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"iconfont icon-name"</span>></span><span class="hljs-tag"></<span class="hljs-name">i</span>></span><br></code></pre></td></tr></table></figure><p>更新的时候要把文件替换,还要把在线链接换掉iconfont.wxss的在线链接换掉。</p><h2 id="-1"><a href="#-1" class="headerlink" title=""></a></h2><p>问题二:模拟器和真机调试的显示内容不一样。</p><h2 id="页面路由"><a href="#页面路由" class="headerlink" title="页面路由"></a>页面路由</h2><p>app.json下pages配置,页面内使用navigator标签进行跳转,一个文件夹下的wxml、wxss、js直接放一起打包了。</p><h2 id="高德地图"><a href="#高德地图" class="headerlink" title="高德地图"></a>高德地图</h2><p><a href="https://lbs.amap.com/api/wx/gettingstarted">入门指南-微信小程序插件 | 高德地图API (amap.com)</a></p><p>logo隐藏找了几篇都不行,决定overflowhidden完事。</p><h2 id="-2"><a href="#-2" class="headerlink" title=""></a></h2><p>引入JS文件需要让文件名大写。</p><h2 id="高德定位app-json配置"><a href="#高德定位app-json配置" class="headerlink" title="#高德定位app.json配置"></a>#高德定位app.json配置</h2><figure class="highlight prolog"><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><code class="hljs prolog"><span class="hljs-string">"permission"</span>: {<br> <span class="hljs-string">"scope.userLocation"</span>: {<br> <span class="hljs-string">"desc"</span>: <span class="hljs-string">"你的位置信息将用于小程序位置接口的效果展示"</span><br> }<br> },<br> <span class="hljs-string">"requiredPrivateInfos"</span>: [<br> <span class="hljs-string">"chooseLocation"</span>,<br> <span class="hljs-string">"getLocation"</span><br> ]<br></code></pre></td></tr></table></figure><h2 id="-3"><a href="#-3" class="headerlink" title=""></a></h2><p>哈哈调用获得用户号码、身份证验证都需要钱。</p><h2 id="-4"><a href="#-4" class="headerlink" title=""></a></h2><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><code class="hljs JS"><span class="hljs-comment">//想要在success回调函数中改变data中的数据要</span><br><span class="hljs-attr">success</span>: <span class="hljs-function">(<span class="hljs-params">r</span>) =></span> {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setData</span>({<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-number">1</span>)<br> })<br>}<br><span class="hljs-comment">//在主函数或者某个函数中打印要</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">data</span>)<br></code></pre></td></tr></table></figure><h2 id="-5"><a href="#-5" class="headerlink" title=""></a></h2><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><code class="hljs js"><span class="hljs-comment">//使用函数初始化data里的数据</span><br><span class="hljs-attr">onLoad</span>:<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){<br><span class="hljs-title function_">init</span>()<span class="hljs-comment">//初始化你data的操作</span><br><span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setData</span>({<br> <span class="hljs-attr">dataName</span>:<span class="hljs-variable language_">this</span>.<span class="hljs-property">data</span>.<span class="hljs-property">dataName</span><br>})<br>} <br></code></pre></td></tr></table></figure><h2 id="-6"><a href="#-6" class="headerlink" title=""></a></h2><p>如果下次写还是用uni吧,不是uni烂,是小程序烂</p><h2 id="-7"><a href="#-7" class="headerlink" title=""></a></h2><p>用div不用view的话盒子撑不开,比如你已经设置了w&h,但他还是会没有大小</p><h2 id="-8"><a href="#-8" class="headerlink" title=""></a></h2><p>小程序点击不能在函数后面加括号传参,要写个<code>data-xxx</code>然后在<code>e.currentTarget.dataset.xxx</code>里获取</p>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
</tags>
</entry>
<entry>
<title>Network</title>
<link href="/2024/04/22/Network/"/>
<url>/2024/04/22/Network/</url>
<content type="html"><![CDATA[<h2 id="网络协议"><a href="#网络协议" class="headerlink" title="网络协议"></a>网络协议</h2><h3 id="HTTP"><a href="#HTTP" class="headerlink" title="HTTP"></a>HTTP</h3><p><strong>(HyperText Transfer Protocol,超文本传输协议)</strong></p><h4 id="五层模型"><a href="#五层模型" class="headerlink" title="五层模型"></a>五层模型</h4><ul><li>应用层<ul><li>为应用软件提供了很多服务,构建于协议之上。</li></ul></li><li>传输层<ul><li>数据的传输都是在这层定义的,数据过大分包分片。</li></ul></li><li>网络层<ul><li>为数据在节点之间传输创建逻辑链路</li></ul></li><li>数据链路层<ul><li>通讯实体间建立数据链路连接。</li></ul></li><li>物理层<ul><li>主要作用是定义物理设备如何传输数据(光缆、网线)</li></ul></li></ul><h4 id="发展"><a href="#发展" class="headerlink" title="发展"></a>发展</h4><ul><li><p>HTTP 0.9</p><ul><li>只有一个GET,发送完毕就关闭tcp协议。</li></ul></li><li><p>HTTP 1.0</p><ul><li>增加了GET POST HEAD</li><li>Status Code</li><li>Header</li><li>多字符集支持</li><li>权限</li><li>缓存</li><li>内容编码</li><li>多部分发送</li></ul><blockquote><p>缺点:每个TCP连接都只能发送一个请求,发送数据完毕连接就关闭。如果还要请求其他资源就必须再新建一个连接。但是TCP新建连接的成本很高,因为客户端和服务器需要三次握手,而且刚开始发送的时候效率很慢。有些浏览器为了解决这个问题使用了一个非标准的Connection字段<code>Connection:Keep-alive</code>这个字段要求服务器不要关闭TCP连接,以便其他请求复用。</p></blockquote></li><li><p>HTTP 1.1</p><ul><li>增加了OPTIONS、PUT、PATCH、DELETE、TRACE、CONNECT</li><li>持久连接</li><li>增加host</li></ul><blockquote><p>缺点:虽然1.1版本支持TCP复用,但是同一个TCP连接中,所有数据通信是按照次序进行的,服务器只有处理完一个回应才会进行下一个回应。会造成<strong>队头堵塞</strong>,这就导致一些网页优化技巧:合并脚本和样式表、图片嵌入CSS代码、域名分片等。</p></blockquote></li><li><p>HTTP 2.0</p><ul><li>二进制传输</li><li>信道复用</li><li>分帧传输</li><li>Sever Push</li></ul></li></ul><h4 id="三次握手"><a href="#三次握手" class="headerlink" title="三次握手"></a>三次握手</h4><ul><li>第一次握手: 发送SYN报文, 传达信息: “你好, 我想建立连接”</li><li>第二次握手: 回传SYN+ACK报文, 传达信息: “好的, 可以建立链接”;</li><li>第三次握手: 回传ACK报文, 传到信息: “好的, 我知道了, 那我们连接”。然后建立连接</li></ul><blockquote><p>TCP为什么要进行三次握手:因为网络传输有延迟,客户端发送请求到服务器端要求建立连接,如果服务器端直接返回的话可能会产生丢 包的情况导致客户端接收不到数据,客户端会因为超时就关闭了,可能就去发送新的请求了,然而服务端并不知道丢包导致客户端没有接收数据,服务端端口就一直开着,造成了额外的开销。所以需要三次握手确认 这个过程。</p></blockquote><h4 id="报文"><a href="#报文" class="headerlink" title="报文"></a>报文</h4><ul><li>请求报文<ul><li>请求组成:请求行,消息报头,请求正文</li></ul></li><li>响应报文<ul><li>响应组成:状态行,消息报头,响应正文</li></ul></li></ul><h4 id="状态码"><a href="#状态码" class="headerlink" title="状态码"></a>状态码</h4><ul><li>1XX:指示信息–表示请求已接收,继续处理。</li><li>2XX:成功–表示请求已被成功接受、理解、接受。</li><li>3XX:重定向–要完成请求必须进一步操作。</li><li>4XX:客户端错误–请求有语法错误或无法实现。</li><li>5XX:服务端错误–服务端未能实现合法的请求。</li></ul><h4 id="Cache-Control"><a href="#Cache-Control" class="headerlink" title="Cache-Control"></a>Cache-Control</h4><p>Cache-Control 是一个 <strong>HTTP 协议中关于缓存的响应头</strong>,它由一些能够允许你定义一个响应资源应该何时、如何被缓存以及缓存多长时间的指令组成。 当浏览器保存了资源的副本从而达到 快速访问的目的 的时候也就是 HTTP 发生了缓存。</p><ul><li>可缓存性:<ul><li>public 任何都可以</li><li>private 只有它发起浏览器可以缓存</li><li>no-cache 去服务端验证才能使用</li><li>no-store 彻底不能</li><li>no-transform 代理服务器、客户端实体不能改动返回内容</li></ul></li><li>到期时间<ul><li>max-age 最大时间</li><li>s-maxage 只有在代理服务器才会生效</li><li>max-stale 只能在发起端设置 就算max-age时间过期 max-stale时间没过期也会走缓存</li></ul></li></ul><h4 id="长连接"><a href="#长连接" class="headerlink" title="长连接"></a>长连接</h4><p>Connection:keep-alive/close 打开关闭</p><p>打开的话就是TCP连接上把HTTP请求的内容发送并接受完返回,不需要多次握手。</p><p>这里可以设置关闭时间,也有些浏览器会有TCP并发限制,比如Chrome浏览器就是6次并发请求限制。</p><h4 id="数据协商"><a href="#数据协商" class="headerlink" title="数据协商"></a>数据协商</h4><ul><li><p>请求</p><ul><li><p>Accept 什么类型</p></li><li><p>Accept-Encoding 压缩方式</p></li><li><p>Accept-Language 语言 </p></li><li><p>user-Agent 浏览器信息</p></li></ul></li><li><p>返回</p><ul><li><p>Content-type 类型</p></li><li><p>Content-Encoding 压缩类型</p></li><li><p>Content-Language 语言</p></li></ul></li></ul><h4 id="CSP-内容安全策略"><a href="#CSP-内容安全策略" class="headerlink" title="CSP 内容安全策略"></a>CSP 内容安全策略</h4><ul><li>限制方式:Content-Security-Policy:””</li></ul><p>如果没有按照限制的方式加载会发回一个错误信息</p><h3 id="HTTPS"><a href="#HTTPS" class="headerlink" title="HTTPS"></a>HTTPS</h3><p>HTTPS是通过握手进行加密,通过公钥进行加密,通过私钥进行解密。</p><ul><li>流程<ul><li>客户端请求服务器获取<code>证书公钥</code></li><li>客户端解析证书</li><li>生成随机值</li><li>用<code>公钥加密</code>随机值生成密钥</li><li>客户端将<code>秘钥</code>发送给服务器</li><li>服务器用<code>私钥</code>解密得到随机值</li><li>将信息和随机值混合在一起进行对称加密</li><li>将加密的内容发送给客户端</li><li>客户端用<code>秘钥</code>解密信息</li></ul></li></ul><h3 id="跨域"><a href="#跨域" class="headerlink" title="跨域"></a>跨域</h3><h4 id="跨域原因"><a href="#跨域原因" class="headerlink" title="跨域原因"></a>跨域原因</h4><p>浏览器的同源策略限制了跨域请求资源。</p><h4 id="JSONP跨域"><a href="#JSONP跨域" class="headerlink" title="JSONP跨域"></a>JSONP跨域</h4><p>JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。具体来说,当一个网页想要从另一个域名获取数据时,它会向那个域名发送一个请求,然后在返回的响应中插入一段script标签,这段标签的src属性就是数据所在的URL。这样,浏览器就会去执行这段script标签中的JavaScript代码,从而获取到数据。但是这种方法存在一定的安全风险,因为它绕过了浏览器的同源策略。</p><h4 id="跨域的限制"><a href="#跨域的限制" class="headerlink" title="跨域的限制"></a>跨域的限制</h4><ul><li>默认跨域允许的方法只有GET、POST、HEAD,其他的方法都不允许。</li><li>默认允许Content-type以下三个,其他的预请求验证,通过就能发送。<ul><li>text/plain</li><li>multipart/form-data</li><li>application/x-www-form-urlencoded</li></ul></li><li>请求头限制,自定义的请求头是不允许的,预请求验证才能通过。</li></ul><h2 id="Cookie-amp-Session-amp-Token-的区别"><a href="#Cookie-amp-Session-amp-Token-的区别" class="headerlink" title="Cookie & Session & Token 的区别"></a>Cookie & Session & Token 的区别</h2><h3 id="Cookies"><a href="#Cookies" class="headerlink" title="Cookies"></a>Cookies</h3><p>客户端的浏览器发出HTTP请求,服务器会进行Cookie设置,也就是set-Cookie,Cookie发送给浏览器之后,浏览器会保存起来,之后发送的每一个请求都会附上这个Cookie。</p><p>但是Cookie本身是有有被篡改风险的,同时用户可能禁用、容量限制4KB。</p><h3 id="Session"><a href="#Session" class="headerlink" title="Session"></a>Session</h3><p>相当于加密版的Cookie,首先也是浏览器发出HTTP请求,服务器这边会设置一个SessionID,并把此ID和会话结束时间一起记录到Cookie返回到客户端,然后不带有用户的密码,只带有SessionID和会话结束时间,在结束时间到的时候就删除cookie,然后由于cookie性质,每次访问都会附上cookie,所以就可以实现长时间登录了。</p><p>但是如果多很多用户,那么SessionID对于服务器将是一个巨大的负担;如果拥有多台服务器的话,那么SessionID又需要去共享给每一台服务器。太笨拙了。</p><h3 id="Token"><a href="#Token" class="headerlink" title="Token"></a>Token</h3><p>多服务器的情况下,如果想要存储SessionID的话,可以放到数据库中,但是如果数据库和后端连接的某个地方又炸了呢。种种情况下催生出了JWT(JSON Web Token)</p><p>也是像上面那样的,首先是浏览器发出HTTP请求,给到一个JSON格式的账号密码给服务端,服务端将其转化为JWT签名密文发给客户端,根据Cookie的性质,每次都会把JWT密文发回给服务端,这样就可以认证登录了。</p><blockquote><p>JWT是由三个部分构成的 <code>header</code>.<code>payload</code>.<code>signature</code></p><p><code>header</code>部分声明需要用什么算法来生成签名。<br><code>payload</code>部分是一些特殊的数据,比如有效期之类的。</p><p><code>header</code> <code>payload</code>的JSON格式Base64编码之后 服务器保存的一段密码对这俩进行算法运算,算出来的东西就是<code>signature</code></p></blockquote><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>Cookie是一个载体,Session是保存在服务器那边的下信息,Token是诞生于服务器但是保存在浏览器这边。</p><h2 id="Session-Storage-amp-Local-Storage-amp-Cookie-的区别"><a href="#Session-Storage-amp-Local-Storage-amp-Cookie-的区别" class="headerlink" title="Session Storage & Local Storage & Cookie 的区别"></a>Session Storage & Local Storage & Cookie 的区别</h2><h3 id="Session-Storage"><a href="#Session-Storage" class="headerlink" title="Session Storage"></a>Session Storage</h3><p>Session Storage 是用于本地存储一个会话中的数据,当会话结束时数据就会被销毁,也就是浏览器关闭的时候就会被销毁。<strong>Session Storage 和 Session 不是一个东西</strong> 。</p><p>是 Web Storage 用于本地存储的一个方式。</p><h3 id="Local-Storage"><a href="#Local-Storage" class="headerlink" title="Local Storage"></a>Local Storage</h3><p>Local Storage 是持久化的存储数据,不删除(通过各种方式)是不会消失的。</p><p>是 Web Storage 用于本地存储的一个方式。</p><h3 id="Cookie"><a href="#Cookie" class="headerlink" title="Cookie"></a>Cookie</h3><p>Cookie 是存储在浏览器端的一小段文本数据,每次向服务端发送请求的时候Cookie都会被发送过去。故Cookie不能作为前端的数据缓存。将token存储到cookie中一般是由后端实现。</p><p>是HTTP规范的一部分。</p>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
</tags>
</entry>
<entry>
<title>Amap</title>
<link href="/2024/04/08/Amap/"/>
<url>/2024/04/08/Amap/</url>
<content type="html"><![CDATA[<h2 id="高德地图api使用"><a href="#高德地图api使用" class="headerlink" title="高德地图api使用"></a>高德地图api使用</h2><p><a href="https://lbs.amap.com/api/javascript-api-v2/summary">概述-地图 JS API 2.0|高德地图API (amap.com)</a></p><h3 id="Vue-使用前准备"><a href="#Vue-使用前准备" class="headerlink" title="Vue 使用前准备"></a>Vue 使用前准备</h3><ul><li><p>首先登录高德,注册成为开发者,创建key,服务平台选择Web端(JS API)。</p></li><li><p>进入工作区:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell"> npm i @amap/amap-jsapi-loader --save<br></code></pre></td></tr></table></figure></li><li><p>在需要使用的组件下:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">import</span> <span class="hljs-title class_">AMapLoader</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'@amap/amap-jsapi-loader'</span>;<br></code></pre></td></tr></table></figure></li><li><p>示例代码</p><figure class="highlight plaintext"><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></pre></td><td class="code"><pre><code class="hljs vue"><script setup><br>import { onMounted, onUnmounted } from "vue";<br>import AMapLoader from "@amap/amap-jsapi-loader";<br><br>let map = null;<br><br>onMounted(() => {<br> AMapLoader.load({<br> key: "", // 申请好的Web端开发者Key,首次调用 load 时必填<br> version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15<br> plugins: ["AMap.Scale"], //需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...']<br> })<br> .then((AMap) => {<br> map = new AMap.Map("container", {<br> // 设置地图容器id<br> viewMode: "3D", // 是否为3D地图模式<br> zoom: 11, // 初始化地图级别<br> center: [116.397428, 39.90923], // 初始化地图中心点位置<br> });<br> })<br> .catch((e) => {<br> console.log(e);<br> });<br>});<br><br>onUnmounted(() => {<br> map?.destroy();<br>});<br></script><br><br><template><br> <div id="container"></div><br></template><br><br><style scoped><br>#container {<br> width: 100%;<br> height: 800px;<br>}<br></style><br></code></pre></td></tr></table></figure></li></ul><h3 id="Vue-水印去除"><a href="#Vue-水印去除" class="headerlink" title="Vue 水印去除"></a>Vue 水印去除</h3><p>在index.html中加上:</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><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><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">style</span>></span><span class="language-css"></span><br><span class="language-css"> <span class="hljs-selector-class">.amap-logo</span> {</span><br><span class="language-css"> <span class="hljs-attribute">display</span>: none;</span><br><span class="language-css"> <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span> <span class="hljs-meta">!important</span>;</span><br><span class="language-css"> }</span><br><span class="language-css"> </span><br><span class="language-css"> <span class="hljs-selector-class">.amap-copyright</span> {</span><br><span class="language-css"> <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>;</span><br><span class="language-css"> }</span><br><span class="language-css"> </span><span class="hljs-tag"></<span class="hljs-name">style</span>></span><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>工具使用</category>
</categories>
<tags>
<tag>工具</tag>
<tag>前端</tag>
</tags>
</entry>
<entry>
<title>Pinia</title>
<link href="/2024/03/25/Pinia/"/>
<url>/2024/03/25/Pinia/</url>
<content type="html"><![CDATA[<h1 id="Pinia简介"><a href="#Pinia简介" class="headerlink" title="Pinia简介"></a>Pinia简介</h1><p>Pinia 是 Vue 的专属状态管理库,可以同时支持vue2和vue3,它允许你跨组件或页面共享状态。如果你熟悉组合式 API 的话,你可能会认为可以通过一行简单的 <code>export const state = reactive({})</code> 来共享一个全局状态。对于单页应用来说确实可以,但如果应用在服务器端渲染,这可能会使你的应用暴露出一些<a href="https://cn.vuejs.org/guide/scaling-up/ssr#cross-request-state-pollution">安全漏洞</a>。 而如果使用 Pinia,即使在小型单页应用中,你也可以获得如下功能:</p><ul><li>Devtools 支持<ul><li>追踪 actions、mutations 的时间线</li><li>在组件中展示它们所用到的 Store</li><li>让调试更容易的 Time travel</li></ul></li><li>热更新<ul><li>不必重载页面即可修改 Store</li><li>开发时可保持当前的 State</li></ul></li><li>插件:可通过插件扩展 Pinia 功能</li><li>为 JS 开发者提供适当的 TypeScript 支持以及<strong>自动补全</strong>功能。</li><li>支持服务端渲染</li></ul><p>Pinia其实就是Vuex5,所以他们是一样的东西。</p><p>它拥有比MITT更多的功能。而且也没有遇到兄弟组件传值出现的问题。好用。</p><h1 id="Pinia安装"><a href="#Pinia安装" class="headerlink" title="Pinia安装"></a>Pinia安装</h1><p><a href="https://pinia.vuejs.org/zh/getting-started.html">Pinia官网</a></p><p>Nodejs包管理器下载:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm install pinia<br></code></pre></td></tr></table></figure><p>vite配置</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><code class="hljs js"><span class="hljs-comment">//main.js</span><br><span class="hljs-keyword">import</span> { createApp } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span><br><span class="hljs-keyword">import</span> { createPinia } <span class="hljs-keyword">from</span> <span class="hljs-string">'pinia'</span><br><span class="hljs-keyword">const</span> pinia = <span class="hljs-title function_">createPinia</span>()<br><span class="hljs-title function_">createApp</span>(<span class="hljs-title class_">App</span>).<span class="hljs-title function_">use</span>(pinia).<span class="hljs-title function_">mount</span>(<span class="hljs-string">'#app'</span>)<br></code></pre></td></tr></table></figure><h1 id="Store"><a href="#Store" class="headerlink" title="Store"></a>Store</h1><h3 id="Store简介"><a href="#Store简介" class="headerlink" title="Store简介"></a>Store简介</h3><p>Store (如 Pinia) 是一个保存状态和业务逻辑的实体,它并不与你的组件树绑定。换句话说,<strong>它承载着全局状态</strong>。它有点像一个永远存在的组件,每个组件都可以读取和写入它。它有<strong>三个概念</strong>,<a href="https://pinia.vuejs.org/zh/core-concepts/state.html">state</a>、<a href="https://pinia.vuejs.org/zh/core-concepts/getters.html">getter</a> 和 <a href="https://pinia.vuejs.org/zh/core-concepts/actions.html">action</a>,我们可以假设这些概念相当于组件中的 <code>data</code>、 <code>computed</code> 和 <code>methods</code>。</p><h3 id="Store使用"><a href="#Store使用" class="headerlink" title="Store使用"></a>Store使用</h3><p>先创建一个js/ts文件。</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//我是直接创到了public目录下 /public/store/user.js</span><br><span class="hljs-keyword">import</span> { defineStore } <span class="hljs-keyword">from</span> <span class="hljs-string">'pinia'</span><br><span class="hljs-keyword">import</span> { ref,computed } <span class="hljs-keyword">from</span> <span class="hljs-string">"vue"</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useCounterStore = <span class="hljs-title function_">defineStore</span>(<span class="hljs-string">'counter'</span>, <span class="hljs-function">() =></span> {<br> <span class="hljs-keyword">const</span> count = <span class="hljs-title function_">ref</span>(<span class="hljs-number">0</span>)<br> <span class="hljs-keyword">const</span> doubleCount = <span class="hljs-title function_">computed</span>(<span class="hljs-function">() =></span> count.<span class="hljs-property">value</span> * <span class="hljs-number">2</span>)<br> <span class="hljs-keyword">function</span> <span class="hljs-title function_">increment</span>(<span class="hljs-params"></span>) {<br> count.<span class="hljs-property">value</span>++<br> }<br><br> <span class="hljs-keyword">return</span> { count, doubleCount, increment }<br>})<br></code></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">import</span> { useCounterStore } <span class="hljs-keyword">from</span> <span class="hljs-string">'/public/stores/user.js'</span><br><span class="hljs-keyword">const</span> store = <span class="hljs-title function_">useCounterStore</span>()<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(store.<span class="hljs-property">count</span>)<br></code></pre></td></tr></table></figure><p>就行了,感觉比MITT方便不少,store似乎就是一个reactive对象。可以解构。</p>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
</tags>
</entry>
<entry>
<title>AutoHotKey</title>
<link href="/2024/03/01/AutoHotKey/"/>
<url>/2024/03/01/AutoHotKey/</url>
<content type="html"><![CDATA[<p>工作的时候手碰着键盘就不想去动鼠标了,但是有一些常用的文件夹或者软件需要点点点点开,就算把他放在桌面或者开始界面都还是需要点点点,那么对于我们这种快捷键爱好者应该怎么设置一个全局快捷键呢。</p><p>本来呢这篇文章是关于 文件夹/软件全局快捷键设置的 但是我使用的方法吧他时灵时不灵</p><blockquote><p>就是创快捷方式点属性改快捷键</p></blockquote><p>虽然偶尔能打开,但是更多的是按完快捷键卡顿很久才打开或者干脆开不开了,很蠢。</p><p>干脆去找桌面脚本语言了。</p><h1 id="AutoHotKey"><a href="#AutoHotKey" class="headerlink" title="AutoHotKey"></a>AutoHotKey</h1><p>找到了这个,这玩意好用啊,无论是文件还是网站都可以快速打开,真的很爽。</p><p>现在只是探索了一个简单的使用方法,还有很多可以尝试来着。</p><p><a href="https://www.autohotkey.com/">AutoHotkey</a> </p><h3 id="基本使用"><a href="#基本使用" class="headerlink" title="基本使用"></a>基本使用</h3><ul><li><p>首先就是进行一个2.0版本的下载。</p></li><li><p>下载完成之后是一个autohotkey dash,新建一个empty文件,直接用右键啥方式打开都行(我是vscode),进去编写。</p></li><li><p>编写好了右键使用其他方式打开,找到autohotkey目录下的<code>AutoHotkeyU64.exe</code>打开 一路确定</p></li><li><p>然后双击你写的脚本文件,就开始运行了。</p></li></ul><h3 id="基础语法"><a href="#基础语法" class="headerlink" title="基础语法"></a>基础语法</h3><ul><li><p><code>;</code>是注释</p></li><li><p>热键:</p><ul><li><code>#</code>:win键</li><li><code>!</code>:alt键</li><li><code>^</code>:ctrl键</li><li><code>+</code>:shift键</li></ul></li><li><p>连接符是<code>::</code> 用于连接热键和运行</p></li><li><p>运行是 <code>Run</code> 运行后面跟文件路径、网址、程序</p></li><li><p>示例:</p><figure class="highlight ahk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs ahk"><span class="hljs-comment">;ctrl+shift+z 打开c盘</span><br><span class="hljs-title">^+z::</span>Run C:\<br></code></pre></td></tr></table></figure></li></ul><h3 id="开机自启动"><a href="#开机自启动" class="headerlink" title="开机自启动"></a>开机自启动</h3><p>如果需要不双击运行而是一开机就运行,那么执行以下操作</p><figure class="highlight bash"><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><code class="hljs bash">把写好的脚本放到<br>{C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup}<br>或者也可能是<br>{C:\用户\用户名\AppData\Roaming\Microsoft\Windows\开始菜单\程序\启动}<br></code></pre></td></tr></table></figure><p>这样之后每次开电脑就会打开,虽然不是马上开,等个几秒就可以了</p>]]></content>
<categories>
<category>工具使用</category>
</categories>
<tags>
<tag>工具</tag>
<tag>快捷使用</tag>
</tags>
</entry>
<entry>
<title>Nginx</title>
<link href="/2024/01/30/Nginx/"/>
<url>/2024/01/30/Nginx/</url>
<content type="html"><![CDATA[<p>下载路径:<a href="https://nginx.org/en/download.html">nginx下载</a></p><p>Nginx是目前最流行的web服务器,同类型的还有Apache、Cloudflare、OpenResty。最开始是由⼀个叫做igor的俄罗斯的程序员开发的,2019年3⽉11⽇被美国的F5公司以6.7亿美元的价格收购,现在Nginx是F5公司旗下的⼀款产品了。</p><h1 id="Nginx进程模型"><a href="#Nginx进程模型" class="headerlink" title="Nginx进程模型"></a>Nginx进程模型</h1><ul><li>Master进程是Nginx的主进程,负责读取和验证配置文件。</li><li>worker进程就是nginx的工作进程,负责处理实际的请求。</li><li>master进程只可以有一个,但是worker进程可以有很多个。</li></ul><h1 id="Nginx部署静态资源"><a href="#Nginx部署静态资源" class="headerlink" title="Nginx部署静态资源"></a>Nginx部署静态资源</h1><p>nginx静态资源部署运行时需要开任务管理器检查是否存在。</p><p>子文件夹:</p><ul><li>html:用于放你需要部署的、打包好的静态资源。tips:直接放有html的那一堆不要再多包一个文件夹了。</li><li>logs:用于放每次运行的情况。</li><li>conf:是配置,可以在nginx.conf中修改端口号,默认80,如果占用就会报错,可修改。<ul><li>端口号:需要修改时打开nginx.conf文件,找到server->listen 修改后面端口号即可</li></ul></li></ul><h1 id="Nginx配置文件"><a href="#Nginx配置文件" class="headerlink" title="Nginx配置文件"></a>Nginx配置文件</h1><h3 id="配置文件的结构"><a href="#配置文件的结构" class="headerlink" title="配置文件的结构"></a>配置文件的结构</h3><p>Nginx的配置⽂件是由⼀系列的指令组成的,每个指令都是由⼀个指令名和⼀个或者多个参数组成的。</p><p>指令和参数之间使⽤空格来分隔,指令以分号 ; 结尾,参数可以使⽤单引号或者双引号来包裹。</p><p>配置⽂件分为以下⼏个部分:</p><figure class="highlight nginx"><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><code class="hljs nginx"><span class="hljs-comment"># 全局块</span><br><br><span class="hljs-attribute">worker_processes</span> <span class="hljs-number">1</span>;<br><br><span class="hljs-section">events</span> {<br><span class="hljs-comment"># events块</span><br>}<br><span class="hljs-section">http</span> {<br> <span class="hljs-comment"># http块</span><br> <span class="hljs-section">server</span> {<br><span class="hljs-comment"># server块</span><br> <span class="hljs-section">location</span> / {<br> <span class="hljs-comment"># location块</span><br> }<br> }<br>}<br></code></pre></td></tr></table></figure><h5 id="全局块"><a href="#全局块" class="headerlink" title="全局块"></a>全局块</h5><ul><li>worker_processes是用于控制worker进程数量的,也可以设置auto,worker进程数量保持同服务器CPU内核数量相同比较合适</li><li>其他一些能配置的东西包括运行Nginx服务器的用户组、进程PID存放路径、日志存放路径和类型以及配置文件引入等。</li></ul><h5 id="events块"><a href="#events块" class="headerlink" title="events块"></a>events块</h5><blockquote><p>用于配置客户端和服务器网络连接的一些配置。比如指定每个worker进程可以接收多少个网络连接、网络IO模型等。</p></blockquote><ul><li>use:指定使用哪种网络IO模型,只能在events块中进行配置。</li><li>worker_connections:每个worker process允许链接的最大连接数。</li></ul><h5 id="http块"><a href="#http块" class="headerlink" title="http块"></a>http块</h5><blockquote><p>虚拟主机、反向代理、负载均衡等都在这里配置,http块可以包含很多server块又叫虚拟主机。</p></blockquote><ul><li>include:nginx可以使用include指令引入其他配置文件。</li><li>default_type:默认类型,如果请求的URL没有包含文件类型,会使用默认类型。</li><li>sendflie:开启高效文件传输模式。</li><li>keepalive_timeout:连接超时时间。</li><li>access_log:日志的存放路径和类型。</li><li>log_format:自定义日志格式。</li><li>sendfile_max_chunk:设置sendfile最⼤传输⽚段⼤⼩,默认为0,表示不限制。</li><li>keepalive_requests:每个连接的请求次数。</li><li>keepalive_timeout: keepalive超时时间。</li><li>gzip:开启gzip压缩。</li><li>gzip_min_length: 开启gzip压缩的最⼩⽂件⼤⼩。</li><li>gzip_comp_level:gzip压缩级别,1-9,级别越⾼压缩率越⾼,但是消耗CPU资源也越多。</li><li>gzip_types:gzip压缩⽂件类型。</li><li>upstream: upstream指令⽤于定义⼀组服务器,⼀般⽤来配置反向代理和负载均衡。</li><li>ip_hash指令⽤于设置负载均衡的⽅式,ip_hash表示使⽤客户端的IP进⾏hash,这样可以保证同⼀个客户端的请求每次都会分配到同⼀个服务器,解决了session共享的问题。</li><li>weight ⽤于设置权重,权重越⾼被分配到的⼏率越⼤</li></ul><h5 id="server块"><a href="#server块" class="headerlink" title="server块"></a>server块</h5><ul><li><p>listen:监听IP和端⼝。</p><ul><li>listen指令⾮常灵活,可以指定多个IP和端⼝,也可以使⽤通配符</li></ul> <figure class="highlight clean"><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><code class="hljs clean">下⾯是⼏个实际的例⼦:<br># listen <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>:<span class="hljs-number">80</span>; # 监听来⾃<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>的<span class="hljs-number">80</span>端⼝的请求<br># listen <span class="hljs-number">80</span>; # 监听来⾃所有IP的<span class="hljs-number">80</span>端⼝的请求<br># listen *:<span class="hljs-number">80</span>; # 监听来⾃所有IP的<span class="hljs-number">80</span>端⼝的请求,同上<br># listen <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>; # 监听来⾃来⾃<span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span>的<span class="hljs-number">80</span>端⼝,默认端⼝为<span class="hljs-number">80</span><br></code></pre></td></tr></table></figure></li><li><p>server_name:⽤来指定虚拟主机的域名,可以使⽤精确匹配、通配符匹配和正则匹配等⽅式</p></li><li><p>location:location块⽤来配置请求的路由,⼀个server块可以包含多个location块,每个location块就是⼀个请求路由。</p><ul><li>root:root指令⽤于指定请求的根⽬录,可以是绝对路径,也可以是相对路径</li><li>index:index指令⽤于指定默认⽂件,如果请求的是⽬录,则会在⽬录下查找默认⽂件</li></ul></li><li><p>error_page:⽤于指定错误⻚⾯,可以指定多个,按照优先级从⾼到低依次查找</p></li></ul><h1 id="Nginx的常用模块"><a href="#Nginx的常用模块" class="headerlink" title="Nginx的常用模块"></a>Nginx的常用模块</h1><ul><li><p>http_access_module :接受或者拒绝特定的客户端请求</p></li><li><p>http_auth_basic_module :HTTP基本认证,使用用户名和密码来限制对资源的访问</p></li><li><p>http_autoindex_module :⾃动索引,⽤于显示⽬录列表</p></li><li><p>http_browser_module :从 User-Agent 请求头中获取和识别客户端浏览器</p></li><li><p>http_charset_module :添加特定的字符集到 Content-Type 响应头中</p></li><li><p>http_empty_gif_module :返回⼀个1像素的透明GIF图⽚</p></li><li><p>http_fastcgi_module :FastCGI⽀持</p></li><li><p>http_geo_module :从IP地址中获取地理位置信息</p></li><li><p>http_gzip_module :Gzip压缩⽀持</p></li><li><p>http_limit_conn_module :限制并发连接数</p></li><li><p>http_limit_req_module :限制请求速率</p></li><li><p>http_map_module :从变量中获取值</p></li><li><p>http_memcached_module :Memcached⽀持</p></li><li><p>http_proxy_module :反向代理⽀持</p></li><li><p>http_referer_module :防盗链</p></li><li><p>http_rewrite_module :URL重写</p></li><li><p>http_scgi_module :转发请求到SCGI服务器</p></li><li><p>http_ssi_module :处理和⽀持SSI(Server Side Includes)</p></li><li><p>http_split_clients_module :根据客户端IP地址或者其他变量将客户端分配到组中,⼀般⽤于A/B测试</p></li><li><p>http_upstream_hash_module :启⽤⼀致性哈希负载均衡</p></li><li><p>http_upstream_ip_hash_module :启⽤IP哈希负载均衡</p></li><li><p>http_upstream_keepalive_module :启⽤⻓连接负载均衡</p></li><li><p>http_upstream_least_conn_module :启⽤最少连接负载均衡</p></li><li><p>http_upstream_zone_module :启⽤共享内存负载均衡</p></li><li><p>http_userid_module :为客户端设置⼀个唯⼀的ID(UID、cookie)</p></li><li><p>http_uwsgi_module :转发请求到uWSGI服务器,⼀般⽤于Python应⽤</p></li></ul><h1 id="Nginx反向代理"><a href="#Nginx反向代理" class="headerlink" title="Nginx反向代理"></a>Nginx反向代理</h1><blockquote><p>正向代理:正向代理就是代理客户端,比如想访问某些国外网站的时候访问不了,这个时候就需要VPN代理服务器进行正向代理,帮你代理客户端</p></blockquote><blockquote><p>反向代理:反向代理就是代理服务端,比如访问一个网站的时候,比如访问咕噜咕噜(Google),他有很多很多服务器,但是对外暴露的只有一个域名,那我们访问的请求会被转发到后面的服务器上,真实的端口IP服务器信息被隐藏。</p></blockquote><h3 id="第一步:在upstream里面放服务器配置:"><a href="#第一步:在upstream里面放服务器配置:" class="headerlink" title="第一步:在upstream里面放服务器配置:"></a>第一步:在upstream里面放服务器配置:</h3><p>在upstream后面是一个名字类似Vue路由配置中的name,可以随便取。</p><figure class="highlight nginx"><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><code class="hljs nginx"><span class="hljs-section">upstream</span> name {<br><span class="hljs-attribute">server</span> <span class="hljs-number">127.0.0.1:8000</span>;<br> <span class="hljs-attribute">server</span> <span class="hljs-number">127.0.0.1:8001</span>;<br> <span class="hljs-attribute">server</span> <span class="hljs-number">127.0.0.1:8002</span>;<br> ...(启动的服务)<br>}<br></code></pre></td></tr></table></figure><p>有时候后台服务器的性能可能不同,以下为两种策略:</p><ul><li>ip_hash指令⽤于设置负载均衡的⽅式,ip_hash表示使⽤客户端的IP进⾏hash,这样可以保证同⼀个客户端的请求每次都会分配到同⼀个服务器,解决了session共享的问题。</li><li>weight:⽤于设置权重,权重越⾼被分配到的⼏率越⼤,用于分流。</li></ul><h3 id="第二步:在localtion中配置:"><a href="#第二步:在localtion中配置:" class="headerlink" title="第二步:在localtion中配置:"></a>第二步:在localtion中配置:</h3><p>localtion后面的/…是自己取的名字,意思是将所有访问<a href="http://app的请求发送到前面取的name里,/">http://app的请求发送到前面取的name里,</a></p><figure class="highlight nginx"><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><code class="hljs nginx"><span class="hljs-attribute">localtion</span> /route {<br> <span class="hljs-attribute">proxy_pass</span> http://name;<br>}<br></code></pre></td></tr></table></figure><p>这样请求都被代理到我们所有服务器中,默认是以轮询的方式来代理。</p><h1 id="HTTPS配置"><a href="#HTTPS配置" class="headerlink" title="HTTPS配置"></a>HTTPS配置</h1><h3 id="证书"><a href="#证书" class="headerlink" title="证书"></a>证书</h3><p>HTTP默认端口是80,HTTPS默认端口是443。</p><p>HTTPS协议需要使用到SSL证书,主流云平台上都可以申请到SSL证书,也可以通过openssl生成一个自签名的证书。</p><figure class="highlight vbnet"><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><code class="hljs vbnet">生成私钥文件:<br>openssl genrsa -out <span class="hljs-keyword">private</span>.<span class="hljs-keyword">key</span> <span class="hljs-number">2048</span><br>根据私钥生成证书签名请求文件:<br>openssl req -<span class="hljs-built_in">new</span> -<span class="hljs-keyword">key</span> <span class="hljs-keyword">private</span>.<span class="hljs-keyword">key</span> -out cert.csr<br>使用私钥对证书申请进行签名从而生成证书文件:<br>openssl x509 -req -<span class="hljs-keyword">in</span> cert.csr -out cacert.pem -signkey <span class="hljs-keyword">private</span>.<span class="hljs-keyword">key</span><br></code></pre></td></tr></table></figure><h3 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h3><p>在server中修改listen监听端口,改为 <code>443 ssl</code></p><ul><li>ssl_certificate:用于放证书文件路径(填入完整证书链可以不报红)</li><li>ssl_certificate_key:用于放证书私钥文件路径(填入完整证书链可以不报红)</li><li>ssl_session_timeout:缓存有效期</li><li>ssl_protocols:安全链接可选的加密协议</li><li>ssl_ciphers:配置加密套件/加密算法</li><li>ssl_prefer_server_ciphers:使用服务器端的首选算法</li></ul><h3 id="重定向"><a href="#重定向" class="headerlink" title="重定向"></a>重定向</h3><p>在http的server上加如下代码:</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">return <span class="hljs-number">301</span> https:<span class="hljs-regexp">//</span><span class="hljs-variable">$server_name</span><span class="hljs-variable">$request_url</span><br></code></pre></td></tr></table></figure><h1 id="虚拟主机"><a href="#虚拟主机" class="headerlink" title="虚拟主机"></a>虚拟主机</h1><p>虚拟主机可以在一台服务器上部署多个站点,nginx的虚拟主机是通过server块来实现的,每个server块就是一个虚拟主机,通过server_name来指定这个虚拟主机的域名。</p>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
<tag>服务器</tag>
</tags>
</entry>
<entry>
<title>Problem</title>
<link href="/2024/01/30/Problem/"/>
<url>/2024/01/30/Problem/</url>
<content type="html"><![CDATA[<h1 id="Git-gt-Time-out"><a href="#Git-gt-Time-out" class="headerlink" title="Git -> Time out"></a>Git -> Time out</h1><ul><li><p>背景:</p><p>用于解决git上传Time out的情况。<br>无论是用git的push还是hexo的deploy,经常会出现Time out的情况。</p></li><li><p>解决方法一:</p><p>重启+开开关关梯子+更换网络</p><blockquote><p>这个的话完全看玄学,我之前经常开开关关梯子+换网就解决了,很抽象。</p></blockquote></li><li><p>解决方法二:</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs stylus">git config <span class="hljs-attr">--global</span> https<span class="hljs-selector-class">.proxy</span> <span class="hljs-comment">//使用代理</span><br>git config <span class="hljs-attr">--global</span> <span class="hljs-attr">--unset</span> https<span class="hljs-selector-class">.proxy</span> <span class="hljs-comment">//取消代理</span><br></code></pre></td></tr></table></figure><blockquote><p>这个我用过很多很多很多很多次,都把他背下来了,有时候确实有用</p></blockquote></li><li><p>解决方法三:</p><p>在传TS笔记的时候家里的网死活传不上去,尝试过网上所有的方法了整了一下午,很抽象的是可以去外网。</p><p>那不妨直接用git自己内置的update flies,即拖动上传。</p></li></ul><h1 id="TypeScript-gt-“Could-not-find-a-declaration-file-for-module-‘xxx-js’-‘xxx-js’-implicitly-has-an-‘any’-type"><a href="#TypeScript-gt-“Could-not-find-a-declaration-file-for-module-‘xxx-js’-‘xxx-js’-implicitly-has-an-‘any’-type" class="headerlink" title="TypeScript -> “Could not find a declaration file for module ‘xxx.js’. ‘xxx.js’ implicitly has an ‘any’ type."></a>TypeScript -> “Could not find a declaration file for module ‘xxx.js’. ‘xxx.js’ implicitly has an ‘any’ type.</h1><ul><li><p>背景:</p><p>尝试使用TS的时候呢,遇到了一些问题,在main.ts中引用已经写好的js文件时(旧版本已经写好的配置文件,详见blog中的vue.config)发生报错,错误代码为ts(7016),一眼ts和原生起冲突了。</p></li><li><p>解决方法一:</p><p>我没试过这个方法,但是Vue2的可以试试(也许)。</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-comment">//将import引入改为require引入</span><br><span class="hljs-keyword">import</span> <span class="hljs-variable language_">module</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"module.js"</span><br><span class="hljs-comment">//改为=></span><br><span class="hljs-keyword">const</span> <span class="hljs-variable language_">module</span> = <span class="hljs-built_in">require</span>(<span class="hljs-string">'module.js'</span>)<br></code></pre></td></tr></table></figure><p>为啥我没试过呢,因为在Vue3中,require语法已经不能使用了,在Vue3版本中,直接使用上述的require语法会导致报错,提示require不是一个函数。这是因为Vue3及以上版本使用了ES Module语法,不再支持使用CommonJS语法来引入模块。</p><blockquote><p>小知识:require和import的性能比较</p><p><code>require</code> 的性能相对于 <code>import</code> 稍低。</p><p>因为 <code>require</code> 是在运行时才引入模块并且还赋值给某个变量,而 <code>import</code> 只需要依据 <code>import</code> 中的接口在编译时引入指定模块所以性能稍高</p></blockquote></li><li><p>解决方法二:</p><p>也是我自己琢磨出来的方法,适用性比较低吧可能。</p><p>问题既然出在 TS 和 JS 对接上,那我向上兼容,把 JS 文件更新成 TS 的不就完事了,在修改引用的文件后缀和文件内容后果然还是不报错了。</p></li><li><p>解决方法三:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-comment">//先在项目目录(也就是和众多config同目录)下创建一个modules.d.ts</span><br><span class="hljs-comment">//modules.d.ts (modules可以自己取名字)</span><br><span class="hljs-keyword">declare</span> <span class="hljs-variable language_">module</span> <span class="hljs-string">'*.js'</span>;<br><br><span class="hljs-comment">//然后在 tsconfig.json 中的 "include" 配置下添加一个 "modules.d.ts"</span><br><span class="hljs-comment">// tsconfig.json</span><br><span class="hljs-string">"include"</span>: [<span class="hljs-string">"src/**/*.ts"</span>, <span class="hljs-string">"src/**/*.tsx"</span>, <span class="hljs-string">"src/**/*.vue"</span>, <span class="hljs-string">"module.d.ts"</span>]<br><br><span class="hljs-comment">//然后在你的main.ts中用正常的import xx from 'xx.js' 即可</span><br><span class="hljs-comment">//main.ts</span><br><span class="hljs-keyword">import</span> xxx <span class="hljs-keyword">from</span> <span class="hljs-string">'xx.js'</span><br></code></pre></td></tr></table></figure><p>推荐使用的方法,无论是你自己的Js文件还是引的依赖包都可以从这里引入到main.ts中,如果引依赖。</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-comment">//modules.d.ts</span><br><span class="hljs-keyword">declare</span> <span class="hljs-variable language_">module</span> <span class="hljs-string">'依赖名'</span>;<br><br><span class="hljs-comment">//main.ts</span><br><span class="hljs-keyword">import</span> xxx <span class="hljs-keyword">from</span> <span class="hljs-string">'依赖名'</span><br></code></pre></td></tr></table></figure></li></ul><h1 id="TypeScript-gt-代码未错误但出现错误提醒(编辑器为vscode)"><a href="#TypeScript-gt-代码未错误但出现错误提醒(编辑器为vscode)" class="headerlink" title="TypeScript -> 代码未错误但出现错误提醒(编辑器为vscode)"></a>TypeScript -> 代码未错误但出现错误提醒(编辑器为vscode)</h1><ul><li><p>背景:</p><p>在写TS项目的时候发现出了报错提示,但是我是直接粘的element-plus的代码,报的错也很奇怪,网上搜也解决不彻底,最抽象的是项目能跑。</p></li></ul><blockquote><p> 后面才知道是因为eslint(vscode扩展-用于检查js书写错误)</p></blockquote><p>遂去找ts检查扩展,发现根本找不到。</p><blockquote><p>好像目前就没有好用的ts语法检查扩展</p></blockquote><ul><li><p>解决方法一:</p><p>首先这个方法我是行不通的,但是我觉得可能是我某个扩展的问题。</p><p>打开设置 -> 搜索validate ->下面找到并设置禁止typescript验证 -> 重新启动编辑器。</p></li><li><p>解决方法二:</p><p>直接让他不检查语法错误。</p><figure class="highlight typescript"><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><code class="hljs typescript">在script标签下加上这行注释。注意,是注释!!<br><br><span class="hljs-comment">// @ts-nocheck</span><br></code></pre></td></tr></table></figure><p>这样ts代码就不会报错了,但也检查不出来问题了,至少不难受了看着。</p></li><li><p>解决方法三:</p><p>没有三了,按道理来说网上是有某种关于eslint配置可行的,但是我配了两个都不行。我以后找到了再来更新吧🤕</p></li></ul><h1 id="IPv4-amp-IPv6-gt-“http-proxy-error”"><a href="#IPv4-amp-IPv6-gt-“http-proxy-error”" class="headerlink" title="IPv4&IPv6 -> “http proxy error”"></a>IPv4&IPv6 -> “http proxy error”</h1><p>之前在打ICT的时候就遇到过类似的问题,当时以为是es6的fetch哪里没配置好,后面换成axios就可以了,但实际不是这样。今天在打服创的时候又遇到这玩意了。</p><ul><li><p>背景</p><p>跨域,localhost但是不同端口跨域。</p><p>我前端config文件明明配置得好好的,但是f12永远报我接的是前端跑着的端口,代码编辑器上更是出一个http proxy error,我就对着一直改啊改啊,发现一直还是这个报错,后面找到是后端的问题。</p></li><li><p>解决方法:</p><p>我遇到的问题实际上是后端允许的网络协议和前端发出来的网络协议不同,用的python后端,那边是给的一个IPv4接口,前端用的是IPv6,结果接不上,解决方法就是更改后端接口使用的网络协议。</p><figure class="highlight python"><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><code class="hljs python"><span class="hljs-comment">#此处就放后端部分代码了,语言是python</span><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:<br> app.run(host = <span class="hljs-string">'0.0.0.0'</span>,port = <span class="hljs-number">5000</span>)<br> <span class="hljs-comment">#在本地的端口5000运行,配置IPv4 IPv6都可以使用,不然前端报错http proxy error</span><br></code></pre></td></tr></table></figure></li></ul><h1 id="Headers-gt-400-Bad-REQUEST-文件上传"><a href="#Headers-gt-400-Bad-REQUEST-文件上传" class="headerlink" title="Headers -> 400(Bad REQUEST)文件上传"></a>Headers -> 400(Bad REQUEST)<code>文件上传</code></h1><ul><li><p>背景:</p><p>是需要上传一个文件,又是经典的Postman可以前端不行。</p></li><li><p>解决方法:</p><p>最后发现是Headers的问题,大家都说:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-attr">headers</span>: {<br> <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'multipart/form-data'</span><br> }<br></code></pre></td></tr></table></figure><p>上传文件要这样子配置,但是实际上我把它整个headers删了反而成功了,原因是什么呢?</p><blockquote><p>发现去掉 Content-Type 的请求头部多了一个 boundary ,查查。</p><p><strong>Boundary 是一种用于分隔多个实体(如文件、表单字段等)的标识符</strong>。 它通常用于 multipart/form-data 类型的请求中,用于将多个部分组合在一起,并指示它们的边界。</p></blockquote><p>原来<code>POST</code>请求上传文件的时候是不需要自己设置 Content-Type,会自动给你添加一个 boundary ,用来分割消息主体中的每个字段,如果这个时候自己设置了 Content-Type, 服务器反而不知道怎么分割各个字段。</p></li></ul><h1 id="Javascript-amp-CSS-gt-label点击事件阻止"><a href="#Javascript-amp-CSS-gt-label点击事件阻止" class="headerlink" title="Javascript&CSS -> label点击事件阻止"></a>Javascript&CSS -> label点击事件阻止</h1><ul><li><p>背景:</p><p>以下HTML:</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><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">label</span>></span><br><span class="hljs-tag"><<span class="hljs-name">div</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"console.log(1)"</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">label</span>></span><br></code></pre></td></tr></table></figure><p>怎么才能实现点击div但是不触发label的点击事件呢?我找了很多方法CSS的还有JS的都不太行,CSS的话是想hover到div上时label的点击事件取消,但是又会连带到div里,用div包label和div加absolute又很麻烦因为还有别的需求。JS是想使用stopPropagation阻止冒泡,但是label的点击事件不受影响。</p></li><li><p>解决方法:</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></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">div</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"inputFocus"</span>></span><br><span class="hljs-tag"><<span class="hljs-name">div</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"stopFocus()"</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"></<span class="hljs-name">div</span>></span><br><span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"inputRef"</span>></span><br></code></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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">const</span> <span class="hljs-title function_">inputFocus</span> = (<span class="hljs-params"></span>) => {<br> inputRef.<span class="hljs-property">value</span>.<span class="hljs-title function_">click</span>();<br>}<br><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">stopFocus</span> = (<span class="hljs-params">event</span>) => {<br> <span class="hljs-comment">//业务函数</span><br> ...<br> <span class="hljs-comment">//阻止冒泡</span><br> <span class="hljs-variable language_">window</span>.<span class="hljs-property">event</span>.<span class="hljs-title function_">stopPropagation</span>();<br>}<br></code></pre></td></tr></table></figure><p>这样就行了div是可以使用stopPropagation函数的。</p><blockquote><p>但是为什么label不行呢,全网查找了一下没找到。</p><p>去MDN看了一下对于这个标签的描述:</p><p>不要在 <code>label</code> 元素内部放置可交互的元素,这样做会让用户更难激活/触发与 <code>label</code> 相关联的表单输入元素。</p></blockquote></li></ul><h1 id="HTML-amp-Javascript-gt-“input标签使用”"><a href="#HTML-amp-Javascript-gt-“input标签使用”" class="headerlink" title="HTML&Javascript -> “input标签使用”"></a>HTML&Javascript -> “input标签使用”</h1><ul><li><p>背景:</p><p>需求是上传图片、显示、点icon删除、点icon预览。</p><p>但是卡在删除上面了,有一个小bug——每次点击icon删除后就会没办法上传之前上传的那一张图片。</p></li><li><p>解决方法:</p><p>其实很简单只不过说我把input标签隐藏起来了,每次删除都是把显示的图片删掉,原本传到input里图片的没删掉。</p><p>但为什么还要写到Problem中呢?</p><p>因为我发现input里图片删除也很有意思:</p><figure class="highlight plaintext"><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><code class="hljs vue"><template><br><input ref="inputRef"><br></template><br><script><br> const inputRef = ref('')<br> //inputRef.value 对应的是他的页面标签<br> //inputRef.value.value 对应的是他的图片(路径)<br></script><br></code></pre></td></tr></table></figure></li></ul><h1 id="Vue-gt-“addEventListener-is-not-a-function”"><a href="#Vue-gt-“addEventListener-is-not-a-function”" class="headerlink" title="Vue -> “addEventListener is not a function”"></a>Vue -> “addEventListener is not a function”</h1><ul><li><p>背景:</p><p>在引一个3d canvas库,但是一直报这个错误,后面找到是vue的ref问题,其实报这个错误是因为一直都获取不到标签。</p></li><li><p>解决方法:</p><p>添加onMounted函数,是这样的:</p><ul><li>Vue 会首先解析和执行组件中的 <code><script></code> 部分,这包括响应式数据、计算属性、监听器、方法等的定义。</li><li>接着会编译模板,将数据绑定到视图中,渲染生成的 HTML。这一步通常是在<code>beforeCreate</code> 和 <code>created</code> 阶段中完成,因为 Vue 需要在渲染之前准备好数据、计算属性等。</li><li><code>onMounted</code> 生命周期钩子函数是在 Vue 3 中的 Composition API 中使用的,它在组件挂载到 DOM 后执行。在 Vue 3 的生命周期中,类似于 <code>onMounted</code> 的生命周期钩子函数会在合适的时机被调用。这意味着它在组件渲染后执行。</li></ul><p>因为定义的ref在script中还未访问到DOM元素,就自然还为空,为空的话后续函数就没办法执行咯。</p></li></ul><h1 id="MITT-gt-onAPI使用问题"><a href="#MITT-gt-onAPI使用问题" class="headerlink" title="MITT -> onAPI使用问题"></a>MITT -> onAPI使用问题</h1><ul><li><p>背景:</p><p>在兄弟组件中调用全局事件总线MITT的时候,emit和on都是可以使用的,但是:</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><code class="hljs js"><span class="hljs-keyword">const</span> test = <span class="hljs-title function_">ref</span>()<br>event.<span class="hljs-title function_">on</span>(<span class="hljs-string">'name'</span>,<span class="hljs-function">(<span class="hljs-params">val</span>)=></span>{<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(val);<span class="hljs-comment">//可以得到值</span><br> test.<span class="hljs-property">value</span> = val;<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(test.<span class="hljs-property">value</span>);<span class="hljs-comment">//可以得到值</span><br>})<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(test.<span class="hljs-property">value</span>);<span class="hljs-comment">//不可以得到值</span><br></code></pre></td></tr></table></figure><p>这就很抽象了,那我调用on的意义不久完全失去了嘛。</p><p>经过尝试ref -> reactive、生命周期等等都没用。</p><p>讨论了一下能看出是渲染顺序问题或者深拷贝问题,但是就是不知道怎么解决。</p></li><li><p>解决方法一:</p><p>最原始的方法就是存到localstorage里面🤣。</p></li><li><p>解决方法二:</p><p>换用pinia Vue状态管理库。</p></li><li><p>解决方法三:</p><p>先用emit传到父组件中,然后再用defineprops传到目的组件中。</p></li></ul><h1 id="HTML-amp-CSS-gt-fixed状态盒子消失"><a href="#HTML-amp-CSS-gt-fixed状态盒子消失" class="headerlink" title="HTML&CSS -> fixed状态盒子消失"></a>HTML&CSS -> fixed状态盒子消失</h1><ul><li><p>背景:</p><p>Header盒子加了一个fixed样式,但是不见了。</p></li><li><p>解决方法:</p><p>加一下z-index。</p></li></ul><h1 id="Pack-gt-打包的时候index-html无法打开"><a href="#Pack-gt-打包的时候index-html无法打开" class="headerlink" title="Pack -> 打包的时候index.html无法打开"></a>Pack -> 打包的时候index.html无法打开</h1><ul><li><p>背景:</p><p>需要把写好的文件给队友调试,但是发现index.html无法打开。</p></li><li><p>解决方法:</p><p>在vite.config.js下:</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><code class="hljs js"><span class="hljs-comment">//添加如下代码</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title function_">defineConfig</span>({<br> <span class="hljs-attr">plugins</span>: [<span class="hljs-title function_">vue</span>()],<br> <span class="hljs-attr">base</span>:<span class="hljs-string">'./'</span><br>})<br></code></pre></td></tr></table></figure><p>然后index.html不要直接打开,会有跨域问题,使用vscode 的<code>Live Server</code>插件打开。</p></li></ul><h1 id="CSS-gt-高度非固定造成的样式错误"><a href="#CSS-gt-高度非固定造成的样式错误" class="headerlink" title="CSS -> 高度非固定造成的样式错误"></a>CSS -> 高度非固定造成的样式错误</h1><ul><li><p>背景:</p><p>比如一个for循环渲染div,然后造成的高度比预设值多,那就会多出来一些白色的。</p></li><li><p>解决方法:</p><p>可以包两层div,外层heightauto,内层height100vh,然后在写。</p></li></ul><h1 id="文件传输-gt-发送文件服务器报500"><a href="#文件传输-gt-发送文件服务器报500" class="headerlink" title="文件传输 -> 发送文件服务器报500"></a>文件传输 -> 发送文件服务器报500</h1><ul><li><p>背景:</p><p>在打比赛的时候发送为JSON格式的文件不行,服务器报500,Postman也不行</p></li><li><p>解决方法:</p><p>JSON的key设置为files。</p></li></ul><h1 id="服务器搭建-gt-如何快速开始搭建一个服务器"><a href="#服务器搭建-gt-如何快速开始搭建一个服务器" class="headerlink" title="服务器搭建 -> 如何快速开始搭建一个服务器"></a>服务器搭建 -> 如何快速开始搭建一个服务器</h1><p>还不是很熟悉服务器相关的操作,所以写一下拿到一个新的服务器相关的操作。</p><p>先进root,拿到最高权限。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">sudo passwd root<br></code></pre></td></tr></table></figure><p>输入两次密码(密码是看不到的,但是其实已经输入了)</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">su<br></code></pre></td></tr></table></figure><p>再输入两次密码。</p><p>下载apt-get:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">sudo apt-get install ssh<br></code></pre></td></tr></table></figure><p>下载nginx,同时检查nginx版本以及启动一下nginx:</p><figure class="highlight shell"><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><code class="hljs shell">apt-get install nginx<br>nginx -v<br>service nginx start<br></code></pre></td></tr></table></figure><p>之后进入浏览器,在Ubuntu系统中输入<code>127.0.0.1</code>,在其他电脑中输入<code>该服务器的ip地址</code>即可访问。</p><p>在<code>/var/www/html</code>目录下:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">sudo git clone <repoName><br></code></pre></td></tr></table></figure><p>然后调整配置:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">sudo nano /etc/nginx/sites-enabled/default<br></code></pre></td></tr></table></figure><p>把<code>server->root</code>重写为新clone的目录下。</p><p>重新启动nginx:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs shell">sudo nginx -t<br>sudo systemctl restart nginx<br></code></pre></td></tr></table></figure><h1 id="服务器搭建-gt-如何部署SSL证书"><a href="#服务器搭建-gt-如何部署SSL证书" class="headerlink" title="服务器搭建 -> 如何部署SSL证书"></a>服务器搭建 -> 如何部署SSL证书</h1><p>经过备案,获取到SSL证书之后,下载到本地。</p><p>先通过ssh传文件到服务器:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">ssh root@<ip><br></code></pre></td></tr></table></figure><p>然后传文件,将证书文件传到nginx安装目录下(默认/etc/nginx):</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">scp -r <上传文件目录地址> root@<ip>:<服务器安放地址><br></code></pre></td></tr></table></figure><p>然后配置nginx:</p><figure class="highlight shell"><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><code class="hljs shell"><span class="hljs-meta prompt_">#</span><span class="language-bash">将端口设置为443</span><br>sudo nano /etc/nginx/sites-enabled/default<br><span class="hljs-meta prompt_"></span><br><span class="hljs-meta prompt_">#</span><span class="language-bash">修改配置</span><br>sudo nano /etc/nginx/nginx.conf<br><span class="hljs-meta prompt_"></span><br><span class="hljs-meta prompt_">#</span><span class="language-bash">在http间添加</span><br>server {<br> #SSL 默认访问端口号为 443<br> listen 443 ssl default; <br> #请填写绑定证书的域名<br> server_name <>; <br> #请填写证书文件的相对路径或绝对路径<br> ssl_certificate xxx.crt; <br> #请填写私钥文件的相对路径或绝对路径<br> ssl_certificate_key xxx.key; <br> ssl_session_timeout 5m;<br> #请按照以下协议配置<br> ssl_protocols TLSv1.2 TLSv1.3; <br> #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。<br> ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; <br> ssl_prefer_server_ciphers on;<br> location / {<br> #网站主页路径。此路径仅供参考,具体请您按照实际目录操作。<br> #例如,您的网站主页在 Nginx 服务器的 /etc/www 目录下,则请修改 root 后面的 html 为 /etc/www。<br> root html; <br> index index.html index.htm;<br> }<br> }<br></code></pre></td></tr></table></figure><p>再运行一次</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs shell">nginx -t<br>nginx -s reload<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>随笔</category>
</categories>
<tags>
<tag>😶🌫️</tag>
</tags>
</entry>
<entry>
<title>TypeScript</title>
<link href="/2024/01/30/TypeScript/"/>
<url>/2024/01/30/TypeScript/</url>
<content type="html"><![CDATA[<h1 id="TypeScript"><a href="#TypeScript" class="headerlink" title="TypeScript"></a>TypeScript</h1><p>前言:很久之前就想着学Typescript了,但是一直在嘴上说没有时间学,说是没有但实际上学习这个也不会花费太久时间,只要肯挤时间并强制去完成就肯定可以完成。</p><p><a href="https://typescript.bootcss.com/">TypeScript 中文手册 </a></p><p>TS其实就是JS Plus,笔记中只写我觉得和JS不一样的很多的地方详细需要自己参考文档。</p><h1 id="TypeScript相比JS的优势"><a href="#TypeScript相比JS的优势" class="headerlink" title="TypeScript相比JS的优势"></a>TypeScript相比JS的优势</h1><ul><li>更早(写代码的同时)发现错误,减少找Bug、改Bug时间,提升开发效率。</li><li>程序中任何位置的代码都有代码提示,随时随地的安全感,增强了开发体验。</li><li>强大的类型系统提升了代码的可维护性,使得重构代码更加容易。</li><li>支持最新的ECMAScript语法,优先体验最新的语法,让你走在前端技术的最前沿。</li><li>TS类型推断机制,不需要在代码中的每个地方都显示标注类型,让你在享受优势的同时,尽量降低了成本。除此之外,Vue 3源码使用TS重写、Angular默认支持TS、React与TS完美配合,TypeScript已成为大中型前端项目的首先编程语言。</li></ul><h1 id="安装TypeScript"><a href="#安装TypeScript" class="headerlink" title="安装TypeScript"></a>安装TypeScript</h1><p>有两种主要的方式来获取TypeScript工具:</p><ul><li>通过npm(Node.js包管理器)</li><li>安装Visual Studio的TypeScript插件</li></ul><p>Visual Studio 2017和Visual Studio 2015 Update 3默认包含了TypeScript。 如果你的Visual Studio还没有安装TypeScript,你可以<a href="https://typescript.bootcss.com/index.html#download-links">下载</a>它。</p><p>针对使用npm的用户:</p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmake">npm <span class="hljs-keyword">install</span> -g typescript<br></code></pre></td></tr></table></figure><h1 id="TS中的高级功能"><a href="#TS中的高级功能" class="headerlink" title="TS中的高级功能"></a>TS中的高级功能</h1><h2 id="类型注解"><a href="#类型注解" class="headerlink" title="类型注解"></a>类型注解</h2><p>TypeScript里的类型注解是一种轻量级的为函数或变量添加约束的方式。 在这个例子里,我们希望<code>greeter</code>函数接收一个字符串参数。 然后尝试把<code>greeter</code>的调用改成传入一个数组:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">greeter</span>(<span class="hljs-params">person: <span class="hljs-built_in">string</span></span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello, "</span> + person;<br>}<br><br><span class="hljs-keyword">let</span> user = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>]; <br><br><span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-property">innerHTML</span> = <span class="hljs-title function_">greeter</span>(user);<br></code></pre></td></tr></table></figure><p>重新编译,你会看到产生了一个错误。</p><figure class="highlight subunit"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs subunit"><span class="hljs-keyword">error </span>TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.<br></code></pre></td></tr></table></figure><p>类似地,尝试删除<code>greeter</code>调用的所有参数。 TypeScript会告诉你使用了非期望个数的参数调用了这个函数。 在这两种情况中,TypeScript提供了静态的代码分析,它可以分析代码结构和提供的类型注解。</p><p><strong>要注意的是尽管有错误,<code>greeter.js</code>文件还是被创建了。 就算你的代码里有错误,你仍然可以使用TypeScript。但在这种情况下,TypeScript会警告你代码可能不会按预期执行。</strong></p><h2 id="接口"><a href="#接口" class="headerlink" title="接口"></a>接口</h2><p>让我们开发这个示例应用。这里我们使用接口来描述一个拥有<code>firstName</code>和<code>lastName</code>字段的对象。 在TypeScript里,只在两个类型内部的结构兼容那么这两个类型就是兼容的。 这就允许我们在实现接口时候只要保证包含了接口要求的结构就可以,而不必明确地使用<code>implements</code>语句。</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> {<br> <span class="hljs-attr">firstName</span>: <span class="hljs-built_in">string</span>;<br> <span class="hljs-attr">lastName</span>: <span class="hljs-built_in">string</span>;<br>}<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">greeter</span>(<span class="hljs-params">person: Person</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello, "</span> + person.<span class="hljs-property">firstName</span> + <span class="hljs-string">" "</span> + person.<span class="hljs-property">lastName</span>;<br>}<br><br><span class="hljs-keyword">let</span> user = { <span class="hljs-attr">firstName</span>: <span class="hljs-string">"Jane"</span>, <span class="hljs-attr">lastName</span>: <span class="hljs-string">"User"</span> };<br><br><span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-property">innerHTML</span> = <span class="hljs-title function_">greeter</span>(user);<br></code></pre></td></tr></table></figure><p>因为我对type对象不是很了解(看完这些文章之后感觉到tasklist有些语句需要规范化了orz),这里也补充一下type&interface的知识:</p><p>类型别名 type 和 接口 interface 区别与联系</p><ul><li><p>不同点:</p><ul><li><p>类型别名type用来给一个类型起个新名字,接口interface是命名数据结构(例如对象)的另一种方式</p></li><li><p>type可以用来表示基本类型、对象类型、联合类型、元组和交集;interface仅限于描述对象类型</p></li><li><p>interface 定义重名了会合并属性,type 会报错</p></li><li><p>interface 可以 extends, type 是不允许 extends ,但是 type 缺可以通过交叉类型 实现 interface 的 extend 行为,并且两者并不是相互独立的,也就是说 interface 可以 extends type, type 也可以 与 interface 类型 交叉</p></li></ul></li><li><p>相同点:</p><ul><li><p>都可以描述 Object和Function</p></li><li><p>interface 和 type 都可以继承。</p></li></ul></li></ul><h2 id="类"><a href="#类" class="headerlink" title="类"></a>类</h2><p>最后,让我们使用类来改写这个例子。 TypeScript支持JavaScript的新特性,比如支持基于类的面向对象编程。</p><p>让我们创建一个<code>Student</code>类,它带有一个构造函数和一些公共字段。 注意类和接口可以一起共作,程序员可以自行决定抽象的级别。</p><p>还要注意的是,在构造函数的参数上使用<code>public</code>等同于创建了同名的成员变量。</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Student</span> {<br> <span class="hljs-attr">fullName</span>: <span class="hljs-built_in">string</span>;<br> <span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">public</span> firstName: <span class="hljs-built_in">string</span>, <span class="hljs-keyword">public</span> middleInitial: <span class="hljs-built_in">string</span>, <span class="hljs-keyword">public</span> lastName: <span class="hljs-built_in">string</span></span>) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">fullName</span> = firstName + <span class="hljs-string">" "</span> + middleInitial + <span class="hljs-string">" "</span> + lastName;<br> }<br>}<br><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Person</span> {<br> <span class="hljs-attr">firstName</span>: <span class="hljs-built_in">string</span>;<br> <span class="hljs-attr">lastName</span>: <span class="hljs-built_in">string</span>;<br>}<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">greeter</span>(<span class="hljs-params">person : Person</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello, "</span> + person.<span class="hljs-property">firstName</span> + <span class="hljs-string">" "</span> + person.<span class="hljs-property">lastName</span>;<br>}<br><br><span class="hljs-keyword">let</span> user = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>(<span class="hljs-string">"Jane"</span>, <span class="hljs-string">"M."</span>, <span class="hljs-string">"User"</span>);<br><br><span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-property">innerHTML</span> = <span class="hljs-title function_">greeter</span>(user);<br></code></pre></td></tr></table></figure><h1 id="基础类型"><a href="#基础类型" class="headerlink" title="基础类型"></a>基础类型</h1><h2 id="枚举"><a href="#枚举" class="headerlink" title="枚举"></a>枚举</h2><p><code>enum</code>类型是对JavaScript标准数据类型的一个补充。 像C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Color</span> {<span class="hljs-title class_">Red</span>, <span class="hljs-title class_">Green</span>, <span class="hljs-title class_">Blue</span>}<br><span class="hljs-keyword">let</span> <span class="hljs-attr">c</span>: <span class="hljs-title class_">Color</span> = <span class="hljs-title class_">Color</span>.<span class="hljs-property">Green</span>;<br></code></pre></td></tr></table></figure><p>默认情况下,从<code>0</code>开始为元素编号。 你也可以手动的指定成员的数值。 例如,我们将上面的例子改成从<code>1</code>开始编号:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Color</span> {<span class="hljs-title class_">Red</span> = <span class="hljs-number">1</span>, <span class="hljs-title class_">Green</span>, <span class="hljs-title class_">Blue</span>}<br><span class="hljs-keyword">let</span> <span class="hljs-attr">c</span>: <span class="hljs-title class_">Color</span> = <span class="hljs-title class_">Color</span>.<span class="hljs-property">Green</span>;<br></code></pre></td></tr></table></figure><p>或者,全部都采用手动赋值:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Color</span> {<span class="hljs-title class_">Red</span> = <span class="hljs-number">1</span>, <span class="hljs-title class_">Green</span> = <span class="hljs-number">2</span>, <span class="hljs-title class_">Blue</span> = <span class="hljs-number">4</span>}<br><span class="hljs-keyword">let</span> <span class="hljs-attr">c</span>: <span class="hljs-title class_">Color</span> = <span class="hljs-title class_">Color</span>.<span class="hljs-property">Green</span>;<br></code></pre></td></tr></table></figure><p>枚举类型提供的一个便利是你可以由枚举的值得到它的名字。 例如,我们知道数值为2,但是不确定它映射到Color里的哪个名字,我们可以查找相应的名字:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">Color</span> {<span class="hljs-title class_">Red</span> = <span class="hljs-number">1</span>, <span class="hljs-title class_">Green</span>, <span class="hljs-title class_">Blue</span>}<br><span class="hljs-keyword">let</span> <span class="hljs-attr">colorName</span>: <span class="hljs-built_in">string</span> = <span class="hljs-title class_">Color</span>[<span class="hljs-number">2</span>];<br><br><span class="hljs-title function_">alert</span>(colorName); <span class="hljs-comment">// 显示'Green'因为上面代码里它的值是2</span><br></code></pre></td></tr></table></figure><h2 id="任意值"><a href="#任意值" class="headerlink" title="任意值"></a>任意值</h2><p>有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用<code>any</code>类型来标记这些变量</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> <span class="hljs-attr">list</span>: <span class="hljs-built_in">any</span>[] = [<span class="hljs-number">1</span>, <span class="hljs-literal">true</span>, <span class="hljs-string">"free"</span>];<br></code></pre></td></tr></table></figure><h2 id="Never"><a href="#Never" class="headerlink" title="Never"></a>Never</h2><p><code>never</code>类型表示的是那些永不存在的值的类型。 例如,<code>never</code>类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是<code>never</code>类型,当它们被永不为真的类型保护所约束时。</p><p><code>never</code>类型是任何类型的子类型,也可以赋值给任何类型;然而,<em>没有</em>类型是<code>never</code>的子类型或可以赋值给<code>never</code>类型(除了<code>never</code>本身之外)。 即使<code>any</code>也不可以赋值给<code>never</code>。</p><p>下面是一些返回<code>never</code>类型的函数:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-comment">// 返回never的函数必须存在无法达到的终点</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">error</span>(<span class="hljs-params">message: <span class="hljs-built_in">string</span></span>): <span class="hljs-built_in">never</span> {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(message);<br>}<br><br><span class="hljs-comment">// 推断的返回值类型为never</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fail</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-title function_">error</span>(<span class="hljs-string">"Something failed"</span>);<br>}<br><br><span class="hljs-comment">// 返回never的函数必须存在无法达到的终点</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">infiniteLoop</span>(<span class="hljs-params"></span>): <span class="hljs-built_in">never</span> {<br> <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {<br> }<br>}<br></code></pre></td></tr></table></figure><h2 id="类型断言"><a href="#类型断言" class="headerlink" title="类型断言"></a>类型断言</h2><p>有时候你会遇到这样的情况,你会比TypeScript更了解某个值的详细信息。 通常这会发生在你清楚地知道一个实体具有比它现有类型更确切的类型。</p><p>通过<em>类型断言</em>这种方式可以告诉编译器,“相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。 TypeScript会假设你,程序员,已经进行了必须的检查。</p><p>类型断言有两种形式。 其一是“尖括号”语法:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">let</span> <span class="hljs-attr">someValue</span>: <span class="hljs-built_in">any</span> = <span class="hljs-string">"this is a string"</span>;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">strLength</span>: <span class="hljs-built_in">number</span> = (<<span class="hljs-built_in">string</span>>someValue).<span class="hljs-property">length</span>;<br></code></pre></td></tr></table></figure><p>另一个为<code>as</code>语法:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">let</span> <span class="hljs-attr">someValue</span>: <span class="hljs-built_in">any</span> = <span class="hljs-string">"this is a string"</span>;<br><br><span class="hljs-keyword">let</span> <span class="hljs-attr">strLength</span>: <span class="hljs-built_in">number</span> = (someValue <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>).<span class="hljs-property">length</span>;<br></code></pre></td></tr></table></figure><p>两种形式是等价的。 至于使用哪个大多数情况下是凭个人喜好;然而,当你在TypeScript里使用JSX时,只有<code>as</code>语法断言是被允许的。</p><h1 id="变量声明"><a href="#变量声明" class="headerlink" title="变量声明"></a>变量声明</h1><p><code>let</code>和<code>const</code>是JavaScript里相对较新的变量声明方式。 像我们之前提到过的,<code>let</code>在很多方面与<code>var</code>是相似的,但是可以帮助大家避免在JavaScript里常见一些问题。 <code>const</code>是对<code>let</code>的一个增强,它能阻止对一个变量再次赋值。</p><p>因为TypeScript是JavaScript的超集,所以它本身就支持<code>let</code>和<code>const</code>。 下面我们会详细说明这些新的声明方式以及为什么推荐使用它们来代替<code>var</code>。</p><h2 id="作用域规则"><a href="#作用域规则" class="headerlink" title="作用域规则"></a>作用域规则</h2><p>对于熟悉其它语言的人来说,<code>var</code>声明有些奇怪的作用域规则。 看下面的例子:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">shouldInitialize: <span class="hljs-built_in">boolean</span></span>) {<br> <span class="hljs-keyword">if</span> (shouldInitialize) {<br> <span class="hljs-keyword">var</span> x = <span class="hljs-number">10</span>;<br> }<br><br> <span class="hljs-keyword">return</span> x;<br>}<br><br><span class="hljs-title function_">f</span>(<span class="hljs-literal">true</span>); <span class="hljs-comment">// returns '10'</span><br><span class="hljs-title function_">f</span>(<span class="hljs-literal">false</span>); <span class="hljs-comment">// returns 'undefined'</span><br></code></pre></td></tr></table></figure><p>有些读者可能要多看几遍这个例子。 变量<code>x</code>是定义在*<code>if</code>语句里面<em>,但是我们却可以在语句的外面访问它。 这是因为<code>var</code>声明可以在包含它的函数,模块,命名空间或全局作用域内部任何位置被访问(我们后面会详细介绍),包含它的代码块对此没有什么影响。 有些人称此为</em><code>var</code>作用域<em>或</em>函数作用域*。 函数参数也使用函数作用域。</p><h2 id="变量获取怪异之处"><a href="#变量获取怪异之处" class="headerlink" title="变量获取怪异之处"></a>变量获取怪异之处</h2><p>快速的猜一下下面的代码会返回什么:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">10</span>; i++) {<br> <span class="hljs-built_in">setTimeout</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(i); }, <span class="hljs-number">100</span> * i);<br>}<br></code></pre></td></tr></table></figure><p>介绍一下,<code>setTimeout</code>会在若干毫秒的延时后执行一个函数(等待其它代码执行完毕)。</p><p>好吧,看一下结果:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br><span class="hljs-number">10</span><br></code></pre></td></tr></table></figure><p>很多JavaScript程序员对这种行为已经很熟悉了,但如果你很不解,你并不是一个人。 大多数人期望输出结果是这样:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-number">0</span><br><span class="hljs-number">1</span><br><span class="hljs-number">2</span><br><span class="hljs-number">3</span><br><span class="hljs-number">4</span><br><span class="hljs-number">5</span><br><span class="hljs-number">6</span><br><span class="hljs-number">7</span><br><span class="hljs-number">8</span><br><span class="hljs-number">9</span><br></code></pre></td></tr></table></figure><p>还记得我们上面讲的变量获取吗?</p><blockquote><p>每当<code>g</code>被调用时,它都可以访问到<code>f</code>里的<code>a</code>变量。</p></blockquote><p>让我们花点时间考虑在这个上下文里的情况。 <code>setTimeout</code>在若干毫秒后执行一个函数,并且是在<code>for</code>循环结束后。 <code>for</code>循环结束后,<code>i</code>的值为<code>10</code>。 所以当函数被调用的时候,它会打印出<code>10</code>!</p><p>一个通常的解决方法是使用立即执行的函数表达式(IIFE)来捕获每次迭代时<code>i</code>的值:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">10</span>; i++) {<br> <span class="hljs-comment">// capture the current state of 'i'</span><br> <span class="hljs-comment">// by invoking a function with its current value</span><br> (<span class="hljs-keyword">function</span>(<span class="hljs-params">i</span>) {<br> <span class="hljs-built_in">setTimeout</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(i); }, <span class="hljs-number">100</span> * i);<br> })(i);<br>}<br></code></pre></td></tr></table></figure><p>这种奇怪的形式我们已经司空见惯了。 参数<code>i</code>会覆盖<code>for</code>循环里的<code>i</code>,但是因为我们起了同样的名字,所以我们不用怎么改<code>for</code>循环体里的代码。</p><h2 id="let声明"><a href="#let声明" class="headerlink" title="let声明"></a>let声明</h2><h3 id="块作用域"><a href="#块作用域" class="headerlink" title="块作用域"></a>块作用域</h3><p>当用<code>let</code>声明一个变量,它使用的是<em>词法作用域</em>或<em>块作用域</em>。 不同于使用<code>var</code>声明的变量那样可以在包含它们的函数外访问,块作用域变量在包含它们的块或<code>for</code>循环之外是不能访问的。</p><h3 id="重定义及屏蔽"><a href="#重定义及屏蔽" class="headerlink" title="重定义及屏蔽"></a>重定义及屏蔽</h3><p>我们提过使用<code>var</code>声明时,它不在乎你声明多少次;你只会得到1个。</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">x</span>) {<br> <span class="hljs-keyword">var</span> x;<br> <span class="hljs-keyword">var</span> x;<br><br> <span class="hljs-keyword">if</span> (<span class="hljs-literal">true</span>) {<br> <span class="hljs-keyword">var</span> x;<br> }<br>}<br></code></pre></td></tr></table></figure><p>在上面的例子里,所有<code>x</code>的声明实际上都引用一个<em>相同</em>的<code>x</code>,并且这是完全有效的代码。 这经常会成为bug的来源。 好的是,<code>let</code>声明就不会这么宽松了。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> x = <span class="hljs-number">10</span>;<br><span class="hljs-keyword">let</span> x = <span class="hljs-number">20</span>; <span class="hljs-comment">// 错误,不能在1个作用域里多次声明`x`</span><br></code></pre></td></tr></table></figure><p>并不是要求两个均是块级作用域的声明TypeScript才会给出一个错误的警告。</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">x</span>) {<br> <span class="hljs-keyword">let</span> x = <span class="hljs-number">100</span>; <span class="hljs-comment">// error: interferes with parameter declaration</span><br>}<br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">g</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">let</span> x = <span class="hljs-number">100</span>;<br> <span class="hljs-keyword">var</span> x = <span class="hljs-number">100</span>; <span class="hljs-comment">// error: can't have both declarations of 'x'</span><br>}<br></code></pre></td></tr></table></figure><p>并不是说块级作用域变量不能用函数作用域变量来声明。 而是块级作用域变量需要在明显不同的块里声明。</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">condition, x</span>) {<br> <span class="hljs-keyword">if</span> (condition) {<br> <span class="hljs-keyword">let</span> x = <span class="hljs-number">100</span>;<br> <span class="hljs-keyword">return</span> x;<br> }<br><br> <span class="hljs-keyword">return</span> x;<br>}<br><br><span class="hljs-title function_">f</span>(<span class="hljs-literal">false</span>, <span class="hljs-number">0</span>); <span class="hljs-comment">// returns 0</span><br><span class="hljs-title function_">f</span>(<span class="hljs-literal">true</span>, <span class="hljs-number">0</span>); <span class="hljs-comment">// returns 100</span><br></code></pre></td></tr></table></figure><p>在一个嵌套作用域里引入一个新名字的行为称做<em>屏蔽</em>。 它是一把双刃剑,它可能会不小心地引入新问题,同时也可能会解决一些错误。 例如,假设我们现在用<code>let</code>重写之前的<code>sumMatrix</code>函数。</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">sumMatrix</span>(<span class="hljs-params">matrix: <span class="hljs-built_in">number</span>[][]</span>) {<br> <span class="hljs-keyword">let</span> sum = <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < matrix.<span class="hljs-property">length</span>; i++) {<br> <span class="hljs-keyword">var</span> currentRow = matrix[i];<br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < currentRow.<span class="hljs-property">length</span>; i++) {<br> sum += currentRow[i];<br> }<br> }<br><br> <span class="hljs-keyword">return</span> sum;<br>}<br></code></pre></td></tr></table></figure><p>这个版本的循环能得到正确的结果,因为内层循环的<code>i</code>可以屏蔽掉外层循环的<code>i</code>。</p><p><em>通常</em>来讲应该避免使用屏蔽,因为我们需要写出清晰的代码。 同时也有些场景适合利用它,你需要好好打算一下。</p><h2 id="let和const用哪个"><a href="#let和const用哪个" class="headerlink" title="let和const用哪个"></a><code>let</code>和<code>const</code>用哪个</h2><p>现在我们有两种作用域相似的声明方式,我们自然会问到底应该使用哪个。 与大多数泛泛的问题一样,答案是:依情况而定。</p><p>使用<a href="https://en.wikipedia.org/wiki/Principle_of_least_privilege">最小特权原则</a>,所有变量除了你计划去修改的都应该使用<code>const</code>。 基本原则就是如果一个变量不需要对它写入,那么其它使用这些代码的人也不能够写入它们,并且要思考为什么会需要对这些变量重新赋值。 使用<code>const</code>也可以让我们更容易的推测数据的流动。</p><p>另一方面,用户很喜欢<code>let</code>的简洁性。 这个手册大部分地方都使用了<code>let</code>。</p><h2 id="解构数组"><a href="#解构数组" class="headerlink" title="解构数组"></a>解构数组</h2><p>最简单的解构莫过于数组的解构赋值了:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">let</span> input = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>];<br><span class="hljs-keyword">let</span> [first, second] = input;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(first); <span class="hljs-comment">// outputs 1</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(second); <span class="hljs-comment">// outputs 2</span><br></code></pre></td></tr></table></figure><p>这创建了2个命名变量 <code>first</code> 和 <code>second</code>。 相当于使用了索引,但更为方便:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript">first = input[<span class="hljs-number">0</span>];<br>second = input[<span class="hljs-number">1</span>];<br></code></pre></td></tr></table></figure><p>解构作用于已声明的变量会更好:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-comment">// swap variables</span><br>[first, second] = [second, first];<br></code></pre></td></tr></table></figure><p>作用于函数参数:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">[first, second]: [<span class="hljs-built_in">number</span>, <span class="hljs-built_in">number</span>]</span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(first);<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(second);<br>}<br><span class="hljs-title function_">f</span>(input);<br></code></pre></td></tr></table></figure><p>你可以在数组里使用<code>...</code>语法创建剩余变量:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">let</span> [first, ...rest] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>];<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(first); <span class="hljs-comment">// outputs 1</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(rest); <span class="hljs-comment">// outputs [ 2, 3, 4 ]</span><br></code></pre></td></tr></table></figure><p>当然,由于是JavaScript, 你可以忽略你不关心的尾随元素:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> [first] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>];<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(first); <span class="hljs-comment">// outputs 1</span><br></code></pre></td></tr></table></figure><p>或其它元素:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> [, second, , fourth] = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>];<br></code></pre></td></tr></table></figure><h2 id="对象解构"><a href="#对象解构" class="headerlink" title="对象解构"></a>对象解构</h2><p>你也可以解构对象:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">let</span> o = {<br> <span class="hljs-attr">a</span>: <span class="hljs-string">"foo"</span>,<br> <span class="hljs-attr">b</span>: <span class="hljs-number">12</span>,<br> <span class="hljs-attr">c</span>: <span class="hljs-string">"bar"</span><br>};<br><span class="hljs-keyword">let</span> { a, b } = o;<br></code></pre></td></tr></table></figure><p>这通过 <code>o.a</code> and <code>o.b</code> 创建了 <code>a</code> 和 <code>b</code> 。 注意,如果你不需要 <code>c</code> 你可以忽略它。</p><p>就像数组解构,你可以用没有声明的赋值:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript">({ a, b } = { <span class="hljs-attr">a</span>: <span class="hljs-string">"baz"</span>, <span class="hljs-attr">b</span>: <span class="hljs-number">101</span> });<br></code></pre></td></tr></table></figure><p>注意,我们需要用括号将它括起来,因为Javascript通常会将以 <code>{</code> 起始的语句解析为一个块。</p><p>你可以在对象里使用<code>...</code>语法创建剩余变量:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> { a, ...passthrough } = o;<br><span class="hljs-keyword">let</span> total = passthrough.<span class="hljs-property">b</span> + passthrough.<span class="hljs-property">c</span>.<span class="hljs-property">length</span>;<br></code></pre></td></tr></table></figure><h2 id="属性重命名"><a href="#属性重命名" class="headerlink" title="属性重命名"></a>属性重命名</h2><p>你也可以给属性以不同的名字:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> { <span class="hljs-attr">a</span>: newName1, <span class="hljs-attr">b</span>: newName2 } = o;<br></code></pre></td></tr></table></figure><p>这里的语法开始变得混乱。 你可以将 <code>a: newName1</code> 读做 “<code>a</code> 作为 <code>newName1</code>“。 方向是从左到右,好像你写成了以下样子:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> newName1 = o.<span class="hljs-property">a</span>;<br><span class="hljs-keyword">let</span> newName2 = o.<span class="hljs-property">b</span>;<br></code></pre></td></tr></table></figure><p>令人困惑的是,这里的冒号<em>不是</em>指示类型的。 如果你想指定它的类型, 仍然需要在其后写上完整的模式。</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> {a, b}: {<span class="hljs-attr">a</span>: <span class="hljs-built_in">string</span>, <span class="hljs-attr">b</span>: <span class="hljs-built_in">number</span>} = o;<br></code></pre></td></tr></table></figure><h2 id="默认值"><a href="#默认值" class="headerlink" title="默认值"></a>默认值</h2><p>默认值可以让你在属性为 undefined 时使用缺省值:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">keepWholeObject</span>(<span class="hljs-params">wholeObject: { a: <span class="hljs-built_in">string</span>, b?: <span class="hljs-built_in">number</span> }</span>) {<br> <span class="hljs-keyword">let</span> { a, b = <span class="hljs-number">1001</span> } = wholeObject;<br>}<br></code></pre></td></tr></table></figure><p>现在,即使 <code>b</code> 为 undefined , <code>keepWholeObject</code> 函数的变量 <code>wholeObject</code> 的属性 <code>a</code> 和 <code>b</code> 都会有值。</p><h2 id="函数声明"><a href="#函数声明" class="headerlink" title="函数声明"></a>函数声明</h2><p>解构也能用于函数声明。 看以下简单的情况:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">type</span> C = { <span class="hljs-attr">a</span>: <span class="hljs-built_in">string</span>, b?: <span class="hljs-built_in">number</span> }<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">{ a, b }: C</span>): <span class="hljs-built_in">void</span> {<br> <span class="hljs-comment">// ...</span><br>}<br></code></pre></td></tr></table></figure><p>但是,通常情况下更多的是指定默认值,解构默认值有些棘手。 首先,你需要在默认值之前设置其格式。</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">{ a, b } = { a: <span class="hljs-string">""</span>, b: <span class="hljs-number">0</span> }</span>): <span class="hljs-built_in">void</span> {<br> <span class="hljs-comment">// ...</span><br>}<br><span class="hljs-title function_">f</span>(); <span class="hljs-comment">// ok, default to { a: "", b: 0 }</span><br></code></pre></td></tr></table></figure><p>其次,你需要知道在解构属性上给予一个默认或可选的属性用来替换主初始化列表。 要知道 <code>C</code> 的定义有一个 <code>b</code> 可选属性:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">f</span>(<span class="hljs-params">{ a, b = <span class="hljs-number">0</span> } = { a: <span class="hljs-string">""</span> }</span>): <span class="hljs-built_in">void</span> {<br> <span class="hljs-comment">// ...</span><br>}<br><span class="hljs-title function_">f</span>({ <span class="hljs-attr">a</span>: <span class="hljs-string">"yes"</span> }); <span class="hljs-comment">// ok, default b = 0</span><br><span class="hljs-title function_">f</span>(); <span class="hljs-comment">// ok, default to {a: ""}, which then defaults b = 0</span><br><span class="hljs-title function_">f</span>({}); <span class="hljs-comment">// error, 'a' is required if you supply an argument</span><br></code></pre></td></tr></table></figure><p><strong>要小心使用解构。 从前面的例子可以看出,就算是最简单的解构表达式也是难以理解的。 尤其当存在深层嵌套解构的时候,就算这时没有堆叠在一起的重命名,默认值和类型注解,也是令人难以理解的。 解构表达式要尽量保持小而简单。 你自己也可以直接使用解构将会生成的赋值表达式。</strong></p><h2 id="展开"><a href="#展开" class="headerlink" title="展开"></a>展开</h2><p>展开操作符正与解构相反。 它允许你将一个数组展开为另一个数组,或将一个对象展开为另一个对象。 例如:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">let</span> first = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>];<br><span class="hljs-keyword">let</span> second = [<span class="hljs-number">3</span>, <span class="hljs-number">4</span>];<br><span class="hljs-keyword">let</span> bothPlus = [<span class="hljs-number">0</span>, ...first, ...second, <span class="hljs-number">5</span>];<br></code></pre></td></tr></table></figure><p>这会令<code>bothPlus</code>的值为<code>[0, 1, 2, 3, 4, 5]</code>。 展开操作创建了<code>first</code>和<code>second</code>的一份浅拷贝。 它们不会被展开操作所改变。</p><p>你还可以展开对象:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> defaults = { <span class="hljs-attr">food</span>: <span class="hljs-string">"spicy"</span>, <span class="hljs-attr">price</span>: <span class="hljs-string">"$$"</span>, <span class="hljs-attr">ambiance</span>: <span class="hljs-string">"noisy"</span> };<br><span class="hljs-keyword">let</span> search = { ...defaults, <span class="hljs-attr">food</span>: <span class="hljs-string">"rich"</span> };<br></code></pre></td></tr></table></figure><p><code>search</code>的值为<code>{ food: "rich", price: "$$", ambiance: "noisy" }</code>。 对象的展开比数组的展开要复杂的多。 像数组展开一样,它是从左至右进行处理,但结果仍为对象。 这就意味着出现在展开对象后面的属性会覆盖前面的属性。 因此,如果我们修改上面的例子,在结尾处进行展开的话:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">let</span> defaults = { <span class="hljs-attr">food</span>: <span class="hljs-string">"spicy"</span>, <span class="hljs-attr">price</span>: <span class="hljs-string">"$$"</span>, <span class="hljs-attr">ambiance</span>: <span class="hljs-string">"noisy"</span> };<br><span class="hljs-keyword">let</span> search = { <span class="hljs-attr">food</span>: <span class="hljs-string">"rich"</span>, ...defaults };<br></code></pre></td></tr></table></figure><p>那么,<code>defaults</code>里的<code>food</code>属性会重写<code>food: "rich"</code>,在这里这并不是我们想要的结果。</p><p>对象展开还有其它一些意想不到的限制。 首先,它仅包含对象 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties">自身的可枚举属性</a>。 大体上是说当你展开一个对象实例时,你会丢失其方法:</p><figure class="highlight typescript"><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><code class="hljs typescript"><span class="hljs-keyword">class</span> <span class="hljs-title class_">C</span> {<br> p = <span class="hljs-number">12</span>;<br> <span class="hljs-title function_">m</span>(<span class="hljs-params"></span>) {<br> }<br>}<br><span class="hljs-keyword">let</span> c = <span class="hljs-keyword">new</span> <span class="hljs-title function_">C</span>();<br><span class="hljs-keyword">let</span> clone = { ...c };<br>clone.<span class="hljs-property">p</span>; <span class="hljs-comment">// ok</span><br>clone.<span class="hljs-title function_">m</span>(); <span class="hljs-comment">// error!</span><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
</tags>
</entry>
<entry>
<title>Interview&Knowledge about Web-Front</title>
<link href="/2023/12/06/Interview-Knowledge-about-Web-Front/"/>
<url>/2023/12/06/Interview-Knowledge-about-Web-Front/</url>
<content type="html"><![CDATA[<h3 id="前端未来的展望✨"><a href="#前端未来的展望✨" class="headerlink" title="前端未来的展望✨"></a>前端未来的展望✨</h3><p>当前PC和Mobile端前端都开发得差不多了,渐渐趋于一个稳态的状态,我们不妨展望一下未来:</p><ul><li>ChatGPT在短期内很快就兴起了,最为容易看到的就是我去年这个时间节点还在自己手搓代码,但是这一届的学弟学妹已经开始使用GPT进行查找代码错误和提供代码思路了🤕。所以GPTwith前端、也可以推广到AIwith前端是一个大方向,但是前端这个东西似乎不是很适合机器学习,目前能做的好像我知道的就是用于代码优化(指机器学习作用于前端)。</li><li>脑机接口近年来也开始兴起,前端作为人机交互工程师,未来脑机接口热潮的时候一定是一个风口浪尖。</li><li>语音转文字前端也是一个点。</li></ul><h3 id="前端人应该拥有的素养❤️"><a href="#前端人应该拥有的素养❤️" class="headerlink" title="前端人应该拥有的素养❤️"></a>前端人应该拥有的素养❤️</h3><ul><li>Blog要经常记录,我打算寒假就让学弟学妹们去制作一个自己的blog,可以使用vercel、4everland自己部署,也可以hexo+github部署……自己决定。Blog内容还是尽量自己手敲(这点我自己也没有做到,自己手敲上去的东西更加属于自己,虽然复制粘贴文档的显得工作量更多🥺)</li><li>积极思考,常常思考自己的代码有没有改进的地方,这个是从韦华贤学长那里学到的,事件点是在我的tasklist有一个函数一眼就需要封装一下,自己很蠢的没看出来,和他沟通之后他说是一个习惯问题,我仔细思考过后觉得这个也是一个前端人应该拥有的素养😈</li><li>拥有好奇心和自趣力——前端-WEB-或者说整个计算机行业都是快速迭代的,需要你跳出工作&其他需求式编程去自己学习自己钻研,这个过程是相当有趣的。</li><li>责任心这个东西就算跳开前端工程师这个tag也是很重要的东西,它是可以伴随你一生的良好品质,不管是平日的生活遇到的东西还是以后自己项目中会遇到的一些事情,你都需要一个很重的责任心去维护一些东西。</li><li>增加学习深度,扩宽学习广度:这个是一个很有意思的问题,在我多方向调研和请教很多人过后,我得到一个结论:在国内大环境,广度重要性远大于深度重要性(至少对于前端且考虑范围取最大)。这过程中我请教了厚华学长、阿韦学长、环节、工具箱学长,各有说辞:<ul><li>厚华学长在准备实习,有很多自己整理出来的面经,他得到的结论是,我需要去弄懂很多之前已经学过会用的,但是基层逻辑不懂的东西,确实是这样,他share过来的很多面试题目我基本看了只能答出表层的东西,再问深一点就没办法说出它的底层逻辑了,但是我认为这个是一个很基本的深度(本来就需要去掌握的东西)以至于他不能算是深度。</li><li>第二个就是阿韦,在深度广度这一块的话给的建议是先学透一个,这样基本原理弄清楚之后其他也会好搞很多。</li><li>工具箱学长也是说建议有自己能拿出手的东西,深度。</li><li>但是面向实际开发中,不管是大厂小厂,都需要你有一个很广的技术栈,会了web需要app,甚至后端、操作系统、ui都需要。</li></ul></li></ul><h3 id="漫谈🎇"><a href="#漫谈🎇" class="headerlink" title="漫谈🎇"></a>漫谈🎇</h3><ul><li>面试相关问题:<ul><li>对于前端工程师面试中更加需要注意的是编程范式的问题,作为一个刚刚毕业或者还没有毕业的小东西,当你没有一个非常专业or深度的知识的话,面试官更加有可能考你的是很基础的编程——数据结构等。</li><li>对于后端工程师,需要通透的是数据库有关知识,这里我不是很了解,不多胡诌了。</li><li>如果拥有自己的项目的话,面试官会问项目相关架构。</li><li>更加重要的是,你需要面试的时候自己编写代码,这就需要你拥有相关的能力。</li></ul></li><li>面试八股文这一块,我有一个观点,我觉得这个属于一个戏称,其实面试中提到的问题我个人认为还是很有用的,通透原理才能使用。所以我觉得多收集多解决这些问题还是很有趣的,有时候还能遇到一些自己不会的问题。</li><li>当你通过面试进入公司之后技术就不会是最难的东西了,更加难的是团队的协作等。这是一个很有趣的我从一些前端大牛身上拿到的观点。</li><li>多投简历、脸皮要厚,什么想投的都去尝试,过后成或不成都可以促进你的学习——在面试中没有解决的问题可以自己花时间去解决。</li><li>多参与开源项目,可能一开始在开源项目中能做的很少,但是这是一个渐进的过程,后面就可以做的多起来了。</li></ul>]]></content>
<categories>
<category>随笔</category>
</categories>
<tags>
<tag>😶🌫️</tag>
</tags>
</entry>
<entry>
<title>MITT</title>
<link href="/2023/11/13/MITT/"/>
<url>/2023/11/13/MITT/</url>
<content type="html"><![CDATA[<p>在Vue3中为了优化代码会使用全局事件总线bus去在不同组件之间传值。</p><p>首先先安装一下mitt</p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmake">npm <span class="hljs-keyword">install</span> mitt<br></code></pre></td></tr></table></figure><p>添加一个bus.js的文件里面放这些</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><code class="hljs javascript"><span class="hljs-keyword">import</span> mitt <span class="hljs-keyword">from</span> <span class="hljs-string">'mitt'</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> events = <span class="hljs-title function_">mitt</span>()<br></code></pre></td></tr></table></figure><p>在需要使用bus的组件里引入依赖</p><figure class="highlight clean"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs clean"><span class="hljs-keyword">import</span> { events } <span class="hljs-keyword">from</span> <span class="hljs-string">'.../.../bus.js'</span><br></code></pre></td></tr></table></figure><p>使用方法主要是三种:</p><ul><li><p>emit:想要传出值或函数</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><code class="hljs javascript">events.<span class="hljs-title function_">emit</span>(<span class="hljs-string">'functionName'</span>, postValue)<br><span class="hljs-comment">//其中functionName是你绑定的一个函数名,相当于一个标识,可以在不同组件中靠这个来判定来源和目的地,postValue是你要传的值。</span><br></code></pre></td></tr></table></figure></li><li><p>on:想要接受传入值</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><code class="hljs javascript">events.<span class="hljs-title function_">on</span>(<span class="hljs-string">'functionName'</span>, <span class="hljs-function">(<span class="hljs-params">val</span>) =></span> { ... })<br><span class="hljs-comment">//其中functionName是你绑定的一个函数名,相当于一个标识,可以在不同组件中靠这个来判定来源和目的地,val是你上面传出来的postValue,要干什么自己写在...里。</span><br></code></pre></td></tr></table></figure><p>兄弟组件之间使用on会有一个小问题,详见<a href="https://taskmanagerol.github.io/2024/01/30/Problem/">Problem</a> </p></li><li><p>off:想要解绑事件</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><code class="hljs javascript"><span class="hljs-comment">//某些情况可能要解绑</span><br>events.<span class="hljs-title function_">off</span>(<span class="hljs-string">"functionName"</span>)<br></code></pre></td></tr></table></figure></li></ul>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
</tags>
</entry>
<entry>
<title>Vue.Config</title>
<link href="/2023/11/13/Vue.Config/"/>
<url>/2023/11/13/Vue.Config/</url>
<content type="html"><![CDATA[<h2 id="Vite框架项目创建"><a href="#Vite框架项目创建" class="headerlink" title="Vite框架项目创建"></a>Vite框架项目创建</h2><figure class="highlight bash"><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><code class="hljs bash">npm create vite@latest<br>npm install<br>npm run dev<br>//(别忘记在package.json中<span class="hljs-string">"scripts"</span>对象中<span class="hljs-string">"dev"</span>后面把<span class="hljs-string">"vite"</span>改成<span class="hljs-string">"vite --open"</span>)<br></code></pre></td></tr></table></figure><h2 id="Vue-Router路由安装"><a href="#Vue-Router路由安装" class="headerlink" title="Vue Router路由安装"></a>Vue Router路由安装</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm install vue-router@4<br>//安装后别忘记在src下新建一个router子文件夹和index.js、routes.js子文件<br></code></pre></td></tr></table></figure><h3 id="index-js(直接复制粘贴即可)"><a href="#index-js(直接复制粘贴即可)" class="headerlink" title="index.js(直接复制粘贴即可)"></a>index.js(直接复制粘贴即可)</h3><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><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><code class="hljs js"><span class="hljs-comment">// 导入router所需的方法</span><br><span class="hljs-keyword">import</span> { createRouter, createWebHashHistory } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue-router'</span><br><br><span class="hljs-comment">// 导入路由页面的配置</span><br><span class="hljs-keyword">import</span> routes <span class="hljs-keyword">from</span> <span class="hljs-string">'./routes.js'</span><br><br><span class="hljs-comment">// 路由参数配置</span><br><span class="hljs-keyword">const</span> router = <span class="hljs-title function_">createRouter</span>({<br> <span class="hljs-comment">// 使用hash(createWebHashHistory)模式,(createWebHistory是HTML5历史模式,支持SEO)</span><br> <span class="hljs-attr">history</span>: <span class="hljs-title function_">createWebHashHistory</span>(),<br> <span class="hljs-attr">routes</span>: routes,<br>})<br><br><span class="hljs-comment">// 全局前置守卫,这里可以加入用户登录判断</span><br>router.<span class="hljs-title function_">beforeEach</span>(<span class="hljs-function">(<span class="hljs-params">to, <span class="hljs-keyword">from</span>, next</span>) =></span> {<br> <span class="hljs-comment">// 继续前进 next()</span><br> <span class="hljs-comment">// 返回 false 以取消导航</span><br> <span class="hljs-title function_">next</span>()<br>})<br><br><span class="hljs-comment">// 全局后置钩子,这里可以加入改变页面标题等操作</span><br>router.<span class="hljs-title function_">afterEach</span>(<span class="hljs-function">(<span class="hljs-params">to, <span class="hljs-keyword">from</span></span>) =></span> {<br> <span class="hljs-comment">// const _title = to.meta.title</span><br> <span class="hljs-comment">// if (_title) {</span><br> <span class="hljs-comment">// window.document.title = _title</span><br> <span class="hljs-comment">// }</span><br>})<br><br><span class="hljs-comment">// 导出默认值</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> router<br></code></pre></td></tr></table></figure><h3 id="routes-js(直接复制粘贴即可)"><a href="#routes-js(直接复制粘贴即可)" class="headerlink" title="routes.js(直接复制粘贴即可)"></a>routes.js(直接复制粘贴即可)</h3><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><code class="hljs js"><span class="hljs-keyword">const</span> routes = [<br> {<br> <span class="hljs-attr">path</span>: <span class="hljs-string">'/'</span>,<br> <span class="hljs-attr">name</span>: <span class="hljs-string">'HOME'</span>,<br> <span class="hljs-attr">component</span>: <span class="hljs-function">() =></span> <span class="hljs-keyword">import</span>(<span class="hljs-string">''</span>)<br> }<br>]<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> routes<br></code></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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//最后就是别忘记在main.js里添加引入依赖</span><br><span class="hljs-keyword">import</span> router <span class="hljs-keyword">from</span> <span class="hljs-string">'./router/index.js'</span><br><span class="hljs-title function_">createApp</span>(<span class="hljs-title class_">App</span>).<span class="hljs-title function_">use</span>(router).<span class="hljs-title function_">mount</span>(<span class="hljs-string">'#app'</span>)<span class="hljs-comment">//.use(router)</span><br></code></pre></td></tr></table></figure><h2 id="APP-vue初始化"><a href="#APP-vue初始化" class="headerlink" title="APP.vue初始化"></a>APP.vue初始化</h2><figure class="highlight plaintext"><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><code class="hljs vue"><script setup></script><br><br><template><br> <router-view></router-view><br></template><br><br><style scoped></style><br></code></pre></td></tr></table></figure><h2 id="style-css初始化"><a href="#style-css初始化" class="headerlink" title="style.css初始化"></a>style.css初始化</h2><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></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-comment">/* 部分标签修改 */</span><br><span class="hljs-selector-tag">body</span> {<br> <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;<br> <span class="hljs-attribute">display</span>: flex;<br> place-items: center;<br>}<br><br><span class="hljs-selector-id">#app</span> {<br> <span class="hljs-attribute">max-width</span>: <span class="hljs-number">1280px</span>;<br> <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;<br> <span class="hljs-attribute">text-align</span>: center;<br>}<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>😶🌫️</tag>
</tags>
</entry>
<entry>
<title>Canvas</title>
<link href="/2023/07/21/Canvas/"/>
<url>/2023/07/21/Canvas/</url>
<content type="html"><![CDATA[<h1 id="canvas画布使用——CSS进阶"><a href="#canvas画布使用——CSS进阶" class="headerlink" title="canvas画布使用——CSS进阶"></a>canvas画布使用——CSS进阶</h1><p>在大一的时候学的一些高数、线性代数都可以用于canvas画布,所以还是很重要的,能好好学就好好学。</p><p>文章参考:<a href="https://www.jianshu.com/p/e3ebe08dddad">在canvas上绘制3d图形 - 简书 (jianshu.com)</a>(写得真的很好,少见的好文章)</p><h3 id="简单绘制三维图形"><a href="#简单绘制三维图形" class="headerlink" title="简单绘制三维图形"></a>简单绘制三维图形</h3><p>因为canvas是一个二维的东西,所以我们想要画出三维的图形就要考虑把这个三维图形给投影到二维上,进而给造成一种三维的错觉。所以首先需要学习的是如何表示三维坐标轴上的任意一个点。通过文章中的推导我们可以看到:</p><p>从空间内的任意点A(xA,yA,zA)观察空间内的任一点G(xG,yG,zG),它在xy平面内的投影H的坐标为:</p><p> $x = ((xG-xA)*zA)/(zA-zG) ; y = ((yG-yA)*zA)/(zA-zG)$</p><h3 id="三维图形-的旋转"><a href="#三维图形-的旋转" class="headerlink" title="三维图形 的旋转"></a>三维图形 的旋转</h3><p>对于一个图形,如果要对其进行y轴的旋转(从观察点更为明显且符合逻辑),则从y轴向下俯视xz平面可以使用一个极坐标的逻辑从而确定我们变换之后的坐标点。<br>主要就是确定每个点(控制旋转的是角度)</p><p><img src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8xMDk2NTEyMi1kMmM1NWUzNTFhMmQ0Zjc1LnBuZz9pbWFnZU1vZ3IyL2F1dG8tb3JpZW50L3N0cmlwfGltYWdlVmlldzIvMi93LzMxMS9mb3JtYXQvd2VicA?x-oss-process=image/format,png" alt="img"></p><p>这个时候假定D点与x轴的夹角是α,圆的半径为R,将D点绕着y轴旋转β旋转至D’点,这个时候D’与x轴夹角为α+β,此时D’的x坐标为cos(α+β)*R,D’的z坐标为sin(α+β)*R</p><p>D’的x坐标:</p><p>$cos(α+β)<em>R=R</em>cosα<em>cosβ-R</em>sinα*sinβ$</p><p>D’的z坐标sin(α+β)<em>R=R</em>sinα<em>cosβ+R</em>cosα<em>sinβ<br>而R</em>sinα就是旋转之前D点的z坐标,R<em>cosα就是旋转之前D点的x坐标,<br>D’的x坐标为x</em>cosβ-z<em>sinβ<br>D’的z坐标为z</em>cosβ+x<em>sinβ<br>将结论代入到我们的立方体的8个顶点ABCDEFGH中<br>对于任一点D(xD,yD,zD),其绕y轴旋转β角的时候,它的三维坐标变为(xD</em>cosβ-zD<em>sinβ,yD,zD</em>cosβ+xD*sinβ)</p><h3 id="正弦曲线阵(含代码)"><a href="#正弦曲线阵(含代码)" class="headerlink" title="正弦曲线阵(含代码)"></a>正弦曲线阵(含代码)</h3><p>博客中写的是vue2的,我自己用的是vue3,所以以下是我已经写好的正弦曲线阵代码。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">canvas</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"wave"</span> <span class="hljs-attr">:width</span>=<span class="hljs-string">"canvasWidth"</span> <span class="hljs-attr">:height</span>=<span class="hljs-string">"canvasHeight"</span>></span><span class="hljs-tag"></<span class="hljs-name">canvas</span>></span><br></code></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><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><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//绘制正弦波浪canvas</span><br><span class="hljs-keyword">import</span> { ref, watch } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>; <br><span class="hljs-keyword">const</span> wave = <span class="hljs-title function_">ref</span>(<span class="hljs-string">''</span>)<br><span class="hljs-keyword">const</span> canvasWidth = <span class="hljs-title function_">ref</span>(<span class="hljs-number">1920</span>)<br><span class="hljs-keyword">const</span> canvasHeight = <span class="hljs-title function_">ref</span>(<span class="hljs-number">800</span>)<br><span class="hljs-comment">//构建一个结构体 方便后期绘制多条正弦曲线</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Line</span> {<br> <span class="hljs-title function_">constructor</span> (a, b, c, d, z, start, end, gap) {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">a</span> = a<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">b</span> = b<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">c</span> = c<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">d</span> = d <span class="hljs-comment">//以上四个控制正弦函数振幅周期之类的</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">z</span> = z <span class="hljs-comment">//三维坐标</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">start</span> = start <span class="hljs-comment">//绘画开始点</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">end</span> = end <span class="hljs-comment">//绘画结束点</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">gap</span> = gap <span class="hljs-comment">//间距</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">pointList</span> = []<br> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">computePointList</span>()<br> }<br> computePointList () {<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">pointList</span> = []<br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-variable language_">this</span>.<span class="hljs-property">start</span>; i <= <span class="hljs-variable language_">this</span>.<span class="hljs-property">end</span>; i = i + <span class="hljs-variable language_">this</span>.<span class="hljs-property">gap</span>) {<br> <span class="hljs-keyword">let</span> x = i<br> <span class="hljs-keyword">let</span> y = <span class="hljs-variable language_">this</span>.<span class="hljs-property">a</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">sin</span>((<span class="hljs-variable language_">this</span>.<span class="hljs-property">b</span> * x + <span class="hljs-variable language_">this</span>.<span class="hljs-property">c</span>) / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) + <span class="hljs-variable language_">this</span>.<span class="hljs-property">d</span> <span class="hljs-comment">// 即y = A sin(ωx + φ) + B</span><br> <span class="hljs-keyword">let</span> offset = i <span class="hljs-comment">//偏移量用来让他运动</span><br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">pointList</span>.<span class="hljs-title function_">push</span>({<br> x,<br> y,<br> <span class="hljs-attr">z</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">z</span>,<br> <span class="hljs-attr">originX</span>: x,<br> offset<br> })<br> }<br> }<br>}<br><span class="hljs-keyword">const</span> lineList = [<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">390</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">360</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">330</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">300</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">270</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">240</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">210</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">180</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">150</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">120</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">90</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">60</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">30</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">30</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">60</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">90</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">120</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">150</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">180</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">210</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">240</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">270</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Line</span>(<span class="hljs-number">20</span>, <span class="hljs-number">2</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">300</span>, -<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">10</span>),<br> <br>]<span class="hljs-comment">//整个类的列表出来</span><br><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">draw</span> = (<span class="hljs-params">visual</span>) => { <span class="hljs-comment">//这是个绘制正弦点的函数</span><br> <span class="hljs-keyword">const</span> context = wave.<span class="hljs-property">value</span>.<span class="hljs-title function_">getContext</span>(<span class="hljs-string">"2d"</span>);<br> context.<span class="hljs-title function_">clearRect</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, canvasWidth.<span class="hljs-property">value</span>, canvasHeight.<span class="hljs-property">value</span>) <span class="hljs-comment">//清空像素</span><br> lineList.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">line</span> =></span> {<br> line.<span class="hljs-property">pointList</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> <span class="hljs-keyword">const</span> pointSize = <span class="hljs-number">1.5</span> * visual.<span class="hljs-property">z</span> / (visual.<span class="hljs-property">z</span> - item.<span class="hljs-property">z</span>) <span class="hljs-comment">//整个近大远小</span><br> context.<span class="hljs-title function_">beginPath</span>()<br> context.<span class="hljs-title function_">arc</span>(item.<span class="hljs-property">canvasX</span> + canvasWidth.<span class="hljs-property">value</span> / <span class="hljs-number">2</span>, item.<span class="hljs-property">canvasY</span> + canvasHeight.<span class="hljs-property">value</span> / <span class="hljs-number">2</span>, pointSize, <span class="hljs-number">0</span>, <span class="hljs-number">2</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) <span class="hljs-comment">//arc(x, y, radius, startAngle, endAngle, counterclockwise);</span><br> context.<span class="hljs-title function_">closePath</span>()<br> context.<span class="hljs-title function_">fill</span>()<br> })<br> })<br>}<br><span class="hljs-keyword">const</span> <span class="hljs-title function_">updatePointList</span> = (<span class="hljs-params">rotationAngleSpeed, visual</span>) => { <span class="hljs-comment">//这是个更新点的位置而使正弦函数移动的函数</span><br> lineList.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">line</span> =></span> {<br> line.<span class="hljs-property">pointList</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> <span class="hljs-keyword">let</span> x = item.<span class="hljs-property">x</span><br> <span class="hljs-keyword">let</span> z = item.<span class="hljs-property">z</span><br> item.<span class="hljs-property">x</span> = x * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">cos</span>(rotationAngleSpeed / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) - z * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">sin</span>(rotationAngleSpeed / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) <br> item.<span class="hljs-property">z</span> = z * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">cos</span>(rotationAngleSpeed / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) + x * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">sin</span>(rotationAngleSpeed / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) <br> item.<span class="hljs-property">y</span> = line.<span class="hljs-property">a</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">sin</span>((line.<span class="hljs-property">b</span> * item.<span class="hljs-property">originX</span> + line.<span class="hljs-property">c</span> + item.<span class="hljs-property">offset</span>) / <span class="hljs-number">180</span> * <span class="hljs-title class_">Math</span>.<span class="hljs-property">PI</span>) + line.<span class="hljs-property">d</span> <span class="hljs-comment">//绕y轴旋转所以y比较特别</span><br> item.<span class="hljs-property">canvasX</span> = (item.<span class="hljs-property">x</span> - visual.<span class="hljs-property">x</span>) * visual.<span class="hljs-property">z</span> / (visual.<span class="hljs-property">z</span> - z)<br> item.<span class="hljs-property">canvasY</span> = (item.<span class="hljs-property">y</span> - visual.<span class="hljs-property">y</span>) * visual.<span class="hljs-property">z</span> / (visual.<span class="hljs-property">z</span> - z)<br> })<br> })<br>}<br><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">animationFrame</span> = (<span class="hljs-params">visual</span>) => { <span class="hljs-comment">//正弦函数动画</span><br> <span class="hljs-variable language_">window</span>.<span class="hljs-title function_">requestAnimationFrame</span>(<span class="hljs-function">() =></span> {<br> lineList.<span class="hljs-title function_">forEach</span>(<span class="hljs-function">(<span class="hljs-params">line,index</span>) =></span> {<br> line.<span class="hljs-property">pointList</span>.<span class="hljs-title function_">forEach</span>(<span class="hljs-function"><span class="hljs-params">item</span> =></span> {<br> line.<span class="hljs-property">c</span> = item.<span class="hljs-property">offset</span> + index * <span class="hljs-number">30</span> <span class="hljs-comment">//index控制偏移量更美观</span><br> item.<span class="hljs-property">offset</span> = item.<span class="hljs-property">offset</span> + <span class="hljs-number">1</span><br> })<br> <span class="hljs-title function_">updatePointList</span>(<span class="hljs-number">.003</span>,visual)<br> })<br> <span class="hljs-title function_">draw</span>(visual)<br> <span class="hljs-title function_">animationFrame</span>(visual)<br> })<br>}<br><span class="hljs-comment">//监听canvas标签创建、因为JS比标签创建更快,所以需要监听。</span><br><span class="hljs-title function_">watch</span>(wave, <span class="hljs-function">(<span class="hljs-params">newValue, oldValue</span>) =></span> {<br> <span class="hljs-keyword">const</span> visual = { <span class="hljs-comment">//观察点设置</span><br> <span class="hljs-attr">x</span>: <span class="hljs-number">0</span>,<br> <span class="hljs-attr">y</span>: -<span class="hljs-number">70</span>,<br> <span class="hljs-attr">z</span>: <span class="hljs-number">500</span><br> }<br> <span class="hljs-title function_">draw</span>(visual);<br> <span class="hljs-title function_">animationFrame</span>(visual)<br>})<br><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
</tags>
</entry>
<entry>
<title>TailwindCSS</title>
<link href="/2023/06/29/TailwindCSS/"/>
<url>/2023/06/29/TailwindCSS/</url>
<content type="html"><![CDATA[<h1 id="Tailwindcss介绍"><a href="#Tailwindcss介绍" class="headerlink" title="Tailwindcss介绍"></a>Tailwindcss介绍</h1><p>Tailwindcss是一种简单好用的css框架,我们在项目中经常遇见只需要赋一次样式的div。</p><p>要么在div上写class后再到css部分去修改样式,这样会相当麻烦(前端人想要6块屏幕呜呜呜),需要上下滑动或者分屏什么什么的。</p><p>要么就在div中使用style去进行修改,但是这样会有两个问题:一个是div中的style不可以配合vscode的插件进行一个自动补全,需要自己去记。另一个是很长很繁杂。</p><p>Tailwindcss就可以解决这样的问题,灵活、没有运行时的负担。</p><p>配置很简单,配置和学习使用半小时可以完成。</p><h1 id="Tailwindcss快速入门"><a href="#Tailwindcss快速入门" class="headerlink" title="Tailwindcss快速入门"></a>Tailwindcss快速入门</h1><p><a href="https://www.tailwindcss.cn/docs/installation/framework-guides">Framework Guides - TailwindCSS中文文档 | TailwindCSS中文网</a></p><p>此处点击选择进入相应的前端框架(我使用的Vite,然后呢进去有vue和react,一开始我没看见用的react配置,然后就没成。)</p><p>然后文档写得很详细了,缺点是他的中文文档似乎没有完全中文化,需要自己进行一个翻译。</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><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">h1</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"text-3xl font-bold underline"</span>></span>Home<span class="hljs-tag"></<span class="hljs-name">h1</span>></span><br></code></pre></td></tr></table></figure><h2 id="Vite快速配置"><a href="#Vite快速配置" class="headerlink" title="Vite快速配置"></a>Vite快速配置</h2><figure class="highlight bash"><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><code class="hljs bash">//在工作区安装tailwindcss<br>npm install -D tailwindcss postcss autoprefixer<br>npx tailwindcss init -p<br></code></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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//新创建的tailwind.config.js下复制如下代码</span><br><span class="hljs-comment">/** <span class="hljs-doctag">@type</span> {<span class="hljs-type">import('tailwindcss').Config</span>} */</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {<br> <span class="hljs-attr">content</span>: [<br> <span class="hljs-string">"./index.html"</span>,<br> <span class="hljs-string">"./src/**/*.{vue,js,ts,jsx,tsx}"</span>,<br> ],<br> <span class="hljs-attr">theme</span>: {<br> <span class="hljs-attr">extend</span>: {},<br> },<br> <span class="hljs-attr">plugins</span>: [],<br>}<br></code></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></pre></td><td class="code"><pre><code class="hljs css">//在style<span class="hljs-selector-class">.css</span>中加入<br><span class="hljs-keyword">@tailwind</span> base;<br><span class="hljs-keyword">@tailwind</span> components;<br><span class="hljs-keyword">@tailwind</span> utilities;<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>工具使用</category>
</categories>
<tags>
<tag>工具</tag>
<tag>前端</tag>
<tag>速通</tag>
</tags>
</entry>
<entry>
<title>Vue</title>
<link href="/2023/06/24/Vue/"/>
<url>/2023/06/24/Vue/</url>
<content type="html"><![CDATA[<h1 id="Webpack"><a href="#Webpack" class="headerlink" title="Webpack"></a>Webpack</h1><h3 id="前端工程化"><a href="#前端工程化" class="headerlink" title="前端工程化"></a>前端工程化</h3><p>(本来记录这个没什么意义,但是很符合我,就记下来了)</p><p>实际的前端开发:</p><ul><li>模块化(js的模块化,css模块化,资源的模块化)</li><li>组件化(复用现有的UI结构、样式、行为)</li><li>规范化(目录结构的划分、编码规范化、接口规范化、文档规范化、Git分支管理)</li><li>自动化(自动化构建、自动部署、自动化测试)</li></ul><p>而不是一开始所以为的缺什么组件或API直接去拿</p><h1 id="Vue"><a href="#Vue" class="headerlink" title="Vue"></a>Vue</h1><h3 id="vue简介"><a href="#vue简介" class="headerlink" title="vue简介"></a>vue简介</h3><p>Vue是一套用于构建用户界面的前端框架。</p><p>Vue框架的特性,主要体现在如下两个方面:</p><h5 id="数据驱动视图"><a href="#数据驱动视图" class="headerlink" title="数据驱动视图"></a>数据驱动视图</h5><p>在使用了vue的界面中,vue会监听数据的变化,从而自动重新渲染页面的结构。即当页面数据发生变化时,页面会自动重新渲染。</p><h5 id="双向数据绑定"><a href="#双向数据绑定" class="headerlink" title="双向数据绑定"></a>双向数据绑定</h5><p>在填写表单时,双向数据绑定可以辅助开发者在不操作DOM的前提下,自动把用户填写的内容同步到数据源中。开发者不需要再手动操作来获取表单元素的最新值。</p><h3 id="Vue的基本使用"><a href="#Vue的基本使用" class="headerlink" title="Vue的基本使用"></a>Vue的基本使用</h3><ul><li>导入Vue.js的script脚本文件</li><li>在页面中声明一个将要被Vue控制的DOM区域</li><li>创建vm实例对象</li></ul><h3 id="Vue的指令和过滤器"><a href="#Vue的指令和过滤器" class="headerlink" title="Vue的指令和过滤器"></a>Vue的指令和过滤器</h3><p>==过滤器只能在Vue2.x使用==</p><h5 id="指令"><a href="#指令" class="headerlink" title="指令"></a>指令</h5><p>指令时Vue为开发者提供的模板语法,用于辅助者渲染界面的基本结构</p><p>Vue中的指令按照不同的用途可以分为如下6大类:</p><ul><li><p>内容渲染指令</p><ul><li>v-text 覆盖原有的指令</li><li>双括号 插值</li><li>v-html 渲染含有标签的文本</li></ul></li><li><p>属性绑定指令</p><ul><li>如果需要为元素的属性动态绑定属性值,则需要用到v-bind属性绑定指令。可以简写成冒号:</li></ul></li><li><p>事件绑定指令</p><ul><li>v-on用于绑定事件,简写@,事件修饰符可以快速完成methods中定义的某些函数</li><li>常见的事件修饰符有:.stop阻止冒泡,.prevent阻止默认事件,.capture添加事件侦听器时使用事件捕获模式,.self只当事件在该元素本身触发时回调,.once事件只触发一次</li></ul></li><li><p>双向绑定指令</p><ul><li>v-model</li></ul></li><li><p>条件渲染指令</p><ul><li>v-if/v-show</li></ul></li><li><p>列表渲染指令</p></li></ul><h5 id="过滤器"><a href="#过滤器" class="headerlink" title="过滤器"></a>过滤器</h5><p>过滤器是vue为开发者提供的功能,常用于文本的格式化。过滤器可以用在两个地方:插值表达式 和 v-bind 属性绑定</p><p>和 el data methods 同级,filters 为过滤器,本质上还是一个函数,过滤器中,必须要有一个返回值</p><p>芝士私有过滤器</p><p>全局过滤器可以让任何一个vue实例使用</p><p>怎么定义呢?</p><p>Vue.filter(‘过滤器名称’,(str)=>{<br>balabalabala<br>})</p><h3 id="侦听器"><a href="#侦听器" class="headerlink" title="侦听器"></a>侦听器</h3><p>和 el data methods 同级,watch 为侦听器 可以随时观察数据变化 定义时用data中的数据定义 表示的是“如果改变就”</p><p>如果是data中的对象的对象 那定义时就是 单引号 对象.对象 单引号 这样</p><h3 id="计算属性"><a href="#计算属性" class="headerlink" title="计算属性"></a>计算属性</h3><p>计算属性指的时通过一系列运算之后,最终得到一个属性值。</p><p>这个动态计算出来的属性值可以被模板结构或methods方法使用</p><p>和 el data methods 同级,computed 为计算属性</p><h3 id="Axios"><a href="#Axios" class="headerlink" title="Axios"></a>Axios</h3><p>方法类似于Ajax 多了一个params用于传参 和data一样 data用不了就用params</p><p>这个的话 我有点不理解 好像用到了 es6 的语法 </p><p>我干脆抄一段现成的代码下来吧 以后对着改 </p><p>document.querySelector(“#btnPOST”).addEventListener(‘click’,==async== fucntion(){<br>const { data: res } = ==await== axios.post(“URL”,{ JSON })<br>console.log(res)<br>}) </p><h3 id="生命周期"><a href="#生命周期" class="headerlink" title="生命周期"></a>生命周期</h3><ul><li><p>生命周期又名生命周期回调函数、生命周期函数、生命周期钩子</p></li><li><p>它是Vue在关键时刻帮我们调用的一些特殊名称的函数</p></li><li><p>生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的</p></li><li><p>生命周期函数中的this指向是vm 或 组件实例对象</p><img src="https://cn.vuejs.org/assets/lifecycle_zh-CN.W0MNXI0C.png"></li></ul><h5 id="挂载流程"><a href="#挂载流程" class="headerlink" title="挂载流程"></a>挂载流程</h5><p>new一个vue </p><p>然后初始化生命周期和事件</p><blockquote><p>beforeCreate: 但此时数据代理还未开始,无法通过vm访问到data中的数据、methods中的方法</p></blockquote><p>然后初始化数据监测和数据代理</p><blockquote><p>created: 这个时候就可以通过vm访问到data中的数据、methods中的方法</p></blockquote><p>然后Vue开始解析你的模板 </p><blockquote><p>就是你.vue文件中的script,但此时页面还不能显示解析好的内容</p></blockquote><ul><li>会判断有无el,无就看$amount()</li><li>会判断有无template(和直接挂载不同 这个会直接把目标标签也给杀死),无就不管</li></ul><blockquote><p>beforeMount: 此时页面显示的是未经Vue编译的DOM结构</p><p>此时所有对DOM的操作,最终都不奏效</p></blockquote><p>然后Vue 将内存中 虚拟的DOM转化为 真实的DOM 插入页面</p><blockquote><p>mounted: 此时页面中显示的是经过Vue编译的DOM</p><p>对DOM的操作均有效(尽可能避免)。至此初始化过程结束,一般在此开启定时器、发送网络请求、订阅消息、绑定自定义事件等初始化操作</p></blockquote><h5 id="更新流程"><a href="#更新流程" class="headerlink" title="更新流程"></a>更新流程</h5><blockquote><p>此时Vue处于Mounted 挂载中的状态 </p></blockquote><p>当页面数据更新</p><blockquote><p>beforeUpdata: 此时:数据是新的,但页面是旧的,即:页面尚未和数据保持同步。</p></blockquote><p>根据新数据,生成新的虚拟DOM,随后与旧的虚拟DOM进行比较,最终完成页面更新,即:完成了Model => View的更新</p><blockquote><p>updated: 此时:数据是新的,页面也是新的,即:页面和数据保持同步</p></blockquote><h5 id="销毁流程"><a href="#销毁流程" class="headerlink" title="销毁流程"></a>销毁流程</h5><p>当遇见.$destory()时</p><blockquote><p>beforeDestory: 此时vm中的所有的:data、methods、指令等等,都处于可用状态,即将执行销毁过程,一般在此阶段:关闭定时器、取消订阅消息、解绑自定义事件等收尾工作。</p></blockquote><p>然后移出所有的侦听器、子组件、事件监听器</p><h3 id="单页面应用程序"><a href="#单页面应用程序" class="headerlink" title="单页面应用程序"></a>单页面应用程序</h3><p>单页面应用程序 简称 SPA,顾名思义,指的是一个 Web 网站中只有唯一的一个 HTML 页面,所有的功能与交互都在这唯一的一个页面内完成。</p><h3 id="VUE组件"><a href="#VUE组件" class="headerlink" title="VUE组件"></a>VUE组件</h3><p>巧妙了解组件的优点:</p><p>传统方法编写应用</p><ul><li>依赖关系混乱、不好维护</li><li>代码复用率不高</li></ul><blockquote><p>比如你写的一些footer啊之类的 之前的操作就是新建一个页面就复制粘贴HTML 再对应的引用CSS文件和JS文件</p><p>这样就比较混乱 不好管理 而Vue就是为了解决这个的 它是提供一个框架 把做项目所需要用到的都给我们搭建出来</p></blockquote><h5 id="vue组件的三个组成部分"><a href="#vue组件的三个组成部分" class="headerlink" title="vue组件的三个组成部分"></a>vue组件的三个组成部分</h5><p>每个.vue组件都由 3 部分组成,分别是:</p><ul><li>template -> 组件的模板结构</li><li>script -> 组件的JavaScript</li><li>style -> 组件的样式</li></ul><h5 id="组件的父子关系"><a href="#组件的父子关系" class="headerlink" title="组件的父子关系"></a>组件的父子关系</h5><ul><li>组件在被封装好之后,彼此之间是相互独立的,不存在父子关系。</li><li>在使用组件时,根据彼此的嵌套关系,形成了父子关系、兄弟关系。</li></ul><h5 id="使用组件的三个步骤"><a href="#使用组件的三个步骤" class="headerlink" title="使用组件的三个步骤"></a>使用组件的三个步骤</h5><ul><li>使用 import 语法导入需要的组件</li><li>使用 components 节点注册<ul><li>通过 components 注册的是 私有子组件,即在 组件A 的 components 节点下,注册了 组件F 。则 组件F 只能用于 组件A 不能用于 组件C</li></ul></li><li>以 标签形式 使用刚才的注册的组件</li></ul><h5 id="注册全局组件"><a href="#注册全局组件" class="headerlink" title="注册全局组件"></a>注册全局组件</h5><p>在vue项目的 main.js 入口文件中,通过 Vue.component()方法 </p><h5 id="组件的props"><a href="#组件的props" class="headerlink" title="组件的props"></a>组件的props</h5><p>props 是组件的自定义属性,在封装通用组件的时候,合理的使用 props 可以极大的提高组件的复用性</p><h3 id="VUE-CLI-脚手架"><a href="#VUE-CLI-脚手架" class="headerlink" title="VUE-CLI(脚手架)"></a>VUE-CLI(脚手架)</h3><p>cli = command + line + interface.</p><p>vue-cli 是 Vue.js 开发的标准工具。它简化了程序员基于 webpack 创建工程化的 Vue 项目的过程</p><h5 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h5><p>vue cerate 项目的名称</p><h5 id="vue中src目录的构成"><a href="#vue中src目录的构成" class="headerlink" title="vue中src目录的构成"></a>vue中src目录的构成</h5><ul><li>assets 文件夹:存放项目用到的静态资源文件,例如css样式表、图片资源</li><li>components 文件夹:程序员封装的、可复用的组件</li><li>main.js 是项目的入口文件。整个项目的运行,要先执行main.js</li></ul><h5 id="vue项目的运行流程"><a href="#vue项目的运行流程" class="headerlink" title="vue项目的运行流程"></a>vue项目的运行流程</h5><p>在工程化的项目中,vue要做的事情非常单纯:通过main.js 把 App.vue 渲染到 index.html 的指定区域中</p><h5 id="render函数"><a href="#render函数" class="headerlink" title="render函数"></a>render函数</h5><p>在 import vue from ‘vue’ 时,我们会引用到不完整的、残缺的vue文件 (当然vue.js是完整的)</p><p>缺什么呢 缺的就是 模板解析器 (作用就是 把你的东西渲染到主页面上) 这时候就需要render函数来帮忙</p><h5 id="修改默认配置"><a href="#修改默认配置" class="headerlink" title="修改默认配置"></a>修改默认配置</h5><p>在 vue.config.js 里面是可以写对脚手架的默认修改的,具体可以阅读文档</p><h5 id="插件"><a href="#插件" class="headerlink" title="插件"></a>插件</h5><p>在 main.js 同目录下创建,本质是 对象 ,需要使用 install 安装</p><p>使用 Vue.use( 插件名 )</p><h3 id="组件化编码流程(通用)"><a href="#组件化编码流程(通用)" class="headerlink" title="组件化编码流程(通用)"></a>组件化编码流程(通用)</h3><h5 id="实现静态组件"><a href="#实现静态组件" class="headerlink" title="实现静态组件"></a>实现静态组件</h5><p>抽取组件,使用组件实现静态页面效果</p><h3 id="全局事件总线实现"><a href="#全局事件总线实现" class="headerlink" title="全局事件总线实现"></a>全局事件总线实现</h3><p>实现任意组件之间的通信</p><p>安装全局事件总线</p><figure class="highlight plaintext"><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><code class="hljs vue"> new Vue({<br>beforeCreate(){<br>Vue.prototype.$bus = this<br>}<br>})<br></code></pre></td></tr></table></figure><p>使用全局事件总线</p><figure class="highlight autoit"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs autoit">$bus.$emit 传参<br>$bus.$on 接收<br></code></pre></td></tr></table></figure><blockquote><p>EventBus已经弃用,官方文档中推荐使用mitt</p></blockquote><h3 id="插槽"><a href="#插槽" class="headerlink" title="插槽"></a>插槽</h3><h3 id="Vuex"><a href="#Vuex" class="headerlink" title="Vuex"></a>Vuex</h3><p>vuex是专门在Vue中实现集中式状态管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理,也是一种组件间通信的方式,且适用于任意组件间通信</p><p>当多个组件依赖于同一状态,来自不同组件的行为需要变更同一状态时我们启用Vuex</p><h3 id="路由"><a href="#路由" class="headerlink" title="路由"></a>路由</h3><p>一个路由就是一组映射关系</p><p>key 为路径,value 可能是 function 或 component </p><h5 id="路由分类"><a href="#路由分类" class="headerlink" title="路由分类"></a>路由分类</h5><ul><li><p>后端路由:</p><ul><li><p>value 是 function ,用于处理客户端提交的请求。</p></li><li><p>服务器接收到一个请求时</p></li></ul></li><li><p>前端路由:</p><ul><li>value 是 component,用于展示页面。</li><li>当浏览器的路径发生改变时,对应的组件就会显示。</li></ul></li></ul><h5 id="路由的基本使用"><a href="#路由的基本使用" class="headerlink" title="路由的基本使用"></a>路由的基本使用</h5><p>引用 vue-router 组件并新建一个router文件夹用于存放index.js 写路由器</p><p>创建并暴露一个路由器</p><figure class="highlight plaintext"><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><code class="hljs vue">export default new Vue Router({<br>routes:[<br>{<br>path:'/路径',<br>component:组件<br>},<br>{<br>//嵌套路由的话<br>path:'/路径',<br>component:组件,<br>children:[<br>{<br>path:'路径',<br>component:组件<br>}<br>]<br>}<br>]<br>})<br></code></pre></td></tr></table></figure><p>并在点击切换的 a标签 处改为 router-link 并将 href 改为 to=”/路径” 这样的写法</p><h3 id="setup函数"><a href="#setup函数" class="headerlink" title="setup函数"></a>setup函数</h3><p>Vue3中一个新的配置项,值为一个函数。</p><p>setup 是所有Composition API(组合API)</p><p>组件中使用的 数据 方法 皆需要配置在 setup 中</p><p>setup若返回一个对象,则对象中的属性、方法,在模板中均可以直接使用。</p><p>setup尽量不要与Vue2.x配置混用</p><h3 id="ref函数"><a href="#ref函数" class="headerlink" title="ref函数"></a>ref函数</h3><p>传参的时候 如</p><figure class="highlight csharp"><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><code class="hljs csharp"><span class="hljs-keyword">let</span> name = <span class="hljs-keyword">ref</span>(<span class="hljs-string">'张三'</span>)<br><span class="hljs-keyword">let</span> job = <span class="hljs-keyword">ref</span>({<br>type:<span class="hljs-string">'123'</span>,<br>epyt:<span class="hljs-string">"321"</span><br>})<br></code></pre></td></tr></table></figure><p>这个时候就需要用到ref函数 </p><h3 id="reactive函数"><a href="#reactive函数" class="headerlink" title="reactive函数"></a>reactive函数</h3><p>定义一个对象类型的响应式数据(基本类型不用,用<code>ref</code>函数)</p><p>语法 <code>const 代理对象 = reactive(源对象)</code> 接收一个对象(或数组),返回一个代理对象(Proxy对象)</p><p>reactive定义的响应式数据是“深层次”的</p>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
<tag>迁移</tag>
</tags>
</entry>
<entry>
<title>Postman</title>
<link href="/2023/06/24/Postman/"/>
<url>/2023/06/24/Postman/</url>
<content type="html"><![CDATA[<h1 id="接口"><a href="#接口" class="headerlink" title="接口"></a>接口</h1><p>接口测试-发什么回什么-><strong><a href="https://postman-echo.com/post">https://postman-echo.com/post</a></strong></p><h3 id="接口简介"><a href="#接口简介" class="headerlink" title="接口简介"></a>接口简介</h3><p>接口:就是软件提供给外部的一种服务。用作数据传输。 在硬件方面USB、投影机被称为接口,在软件方面统称API,如微信的支付和提现。(统称鉴权码,有token、key、appkey)</p><p>内部接口:开发人员自己开发的对自身系统提供的接口</p><p>外部接口:开发系统调用外部的,微信、支付宝,其它的接口</p><p>接口测试的本质:就是测试接口能否正常的交互数据,权限控制以及异常场景。</p><h3 id="软件为什么需要接口"><a href="#软件为什么需要接口" class="headerlink" title="软件为什么需要接口"></a>软件为什么需要接口</h3><p>因为接口能够让内部的数据被外部进行修改</p><h3 id="为什么要做接口测试"><a href="#为什么要做接口测试" class="headerlink" title="为什么要做接口测试"></a>为什么要做接口测试</h3><ul><li>现在很多系统都是前后端分离,开发的进度不一样,需要把一开始开发出来的接口进行测试</li><li>基于安全考虑,前端有验证很容易绕过,直接请求接口</li><li>测试推崇的是测试左移,即尽早测试。</li></ul><h3 id="接口测试的简介和分类"><a href="#接口测试的简介和分类" class="headerlink" title="接口测试的简介和分类"></a>接口测试的简介和分类</h3><p>接口测试就是测试系统组件接口之间的一种测试</p><p>分类:</p><ul><li>测试外部接口:测试被测系统和外部系统之间的接口(只需要测试正例即可)</li><li>测试内部接口:<ul><li>内部接口只提供给内部系统使用。(预算系统,承保系统)(只需要测试正例即可)</li><li>内部接口提供给外部系统使用(测试必须非常全面)</li></ul></li></ul><h3 id="接口测试的流程以及用例的设计"><a href="#接口测试的流程以及用例的设计" class="headerlink" title="接口测试的流程以及用例的设计"></a>接口测试的流程以及用例的设计</h3><ul><li>拿到接口api文档(通过抓包工具获取),熟悉接口业务,接口地址,鉴权方式,入参,码</li><li>编写接口用例以及评审</li><li>使用接口测试工具Postman实现接口测试</li><li>Postman-+Newman+Jenkins实现持续集成,并且输出测试报告并且发送邮件,并且输出测试报告并且发送邮件</li></ul><h3 id="接口返回数据和JSON详解"><a href="#接口返回数据和JSON详解" class="headerlink" title="接口返回数据和JSON详解"></a>接口返回数据和JSON详解</h3><ul><li>json格式:三组数据<ul><li>{error_code:0,msg:”0”,data:[]}</li><li>error_code:错误码</li><li>msg:对错误码的中文说明</li><li>data:真正的返回的数据</li></ul></li><li>jsonj就是一种数据类型,整形,小数,字符串</li><li>JSON由两组数据组成<ul><li>MAP对象,键值对</li><li>数组</li></ul></li></ul><h1 id="Postman界面介绍"><a href="#Postman界面介绍" class="headerlink" title="Postman界面介绍"></a>Postman界面介绍</h1><ul><li>Home主页</li><li>workspaces 工作空间<ul><li>Collections 项目集合</li><li>ApiS api文档</li><li>Environments 全局变量</li><li>Mock Server 虚拟服务器</li><li>Monitors 监听器</li><li>History 历史记录</li></ul></li></ul><h1 id="常见的请求头"><a href="#常见的请求头" class="headerlink" title="常见的请求头"></a>常见的请求头</h1><h3 id="Accept"><a href="#Accept" class="headerlink" title="Accept"></a>Accept</h3><p>常用,它的作用是:客户端接收的数据格式;</p><p>比方说你的参数值填写的是application/json,就说明浏览器所接收的数据是json类型的数据,当你加了Accept请求头之后,你会发现你得到的数据和你没有加Accept请求头的数据是完全不一样的。如果你没有加Accept这个请求头,你得到的数据可能就是一个简单的网页。Accept它可以影响你返回的数据。</p><h3 id="X-Requested-With"><a href="#X-Requested-With" class="headerlink" title="X-Requested-With"></a>X-Requested-With</h3><p>它的作用是:异步请求;</p><p>如果对开发有一定的了解的话,前端里面有这样一个技术Ajax异步请求。现在很多的功能都会用到这个异步请求,比如说登录。</p><p>简单的举个列子:如果现在你想去上海,只有一条路的话,你只能走唯一的一条路。那么如果有两条路或者多条路,可以坐飞机,高铁,汽车等等。那么它们就相当于异步,也就是说你可以通过飞机到上海,也可以坐高铁到上海,这样通俗的理解异步请求。</p><p>异步请求的特点:无刷新。就是说登录的时候是需要进行页面跳转的,而异步请求它不需要跳转也可以做到这样的请求。</p><h3 id="User-Aget"><a href="#User-Aget" class="headerlink" title="User-Aget"></a>User-Aget</h3><p>它的作用是:发送请求的客户端的类型;</p><p>比如说我们可以通过postman去发送请求类型,也可通过浏览器去发送请求等等,那么有的接口你通过非浏览器去请求它是无法通过的</p><h3 id="Content-type"><a href="#Content-type" class="headerlink" title="Content-type"></a>Content-type</h3><p>它的作用是:请求的报文格式;</p><h3 id="Cookie"><a href="#Cookie" class="headerlink" title="Cookie"></a>Cookie</h3><p>Cookie信息;</p><p>有的接口需要登录之后才会生成Cookie信息,必须要保持登录的状态。这种情况我们就需要对Cookie信息进行管理。</p><h1 id="Postman执行接口测试"><a href="#Postman执行接口测试" class="headerlink" title="Postman执行接口测试"></a>Postman执行接口测试</h1><h3 id="请求页签"><a href="#请求页签" class="headerlink" title="请求页签"></a>请求页签</h3><ul><li>Params:get请求传参</li><li>authorization:鉴权</li><li>headers:请求头</li><li>Body:<ul><li>post 请求传参</li><li>none 没有参数</li><li>form-data:既可以传键值对参数也可以传文件</li><li>x-www-from-urlencoded:只能够传键值对参数</li><li>raw:json,text,xml,html,javascript</li><li>binary:把文件以二进制的方式传参</li></ul></li><li>pre-request-script:请求之前的脚本</li><li>tests:请求之后的断言</li><li>cookies:用于管理cookie信息</li></ul><h3 id="响应页签"><a href="#响应页签" class="headerlink" title="响应页签"></a>响应页签</h3><ul><li>Body:接口返回的数据<ul><li>Pretty:以Json、html、XML…不同格式查看返回的数据</li><li>Raw:以文本的方式查看返回的数据</li><li>PreView:以网页的方式查看返回的数据</li></ul></li><li>Cookies:响应的cookies信息</li><li>Headers:响应头</li><li>Test Results:断言的结果</li><li>200是状态码 Ok是状态信息 681MS是响应的时间 343B是响应的字节数</li></ul><h1 id="环境变量和全局变量"><a href="#环境变量和全局变量" class="headerlink" title="环境变量和全局变量"></a>环境变量和全局变量</h1><p>可以在Environments那里设置不同情况的环境</p><p>比如开发环境、测试环境、生成环境</p><p>并且使用来使用你的环境</p><p>比如:https:///路径</p><p>然后再在右上角选择你需要的环境即可</p><p>环境变量:环境变量就是全局变量</p><p>全局变量:全局变量就是能够在任何接口里面访问的变量</p><h1 id="接口关联"><a href="#接口关联" class="headerlink" title="接口关联"></a>接口关联</h1><ul><li>json提取器实现接口关联<ul><li>在请求页签:Tests中使用var 变量名=JSON.parse(responseBody),json提取器将得到数据提取成json格式,这样可以设置一个全局变量,然后使用</li></ul></li><li>使用正则表达式提取器实现接口关联<ul><li>在请求页签:Tests中使用var 变量名=responseBody.match(new RegExp(‘复制Raw并把Value改为(*?)’)),这样可以设置一个全局变量,然后使用(记得是变量名[1])</li></ul></li></ul><h1 id="postman内置动态参数以及自定义的动态参数"><a href="#postman内置动态参数以及自定义的动态参数" class="headerlink" title="postman内置动态参数以及自定义的动态参数"></a>postman内置动态参数以及自定义的动态参数</h1><ul><li> 生成当前时间的时间戳</li><li> 生成0-1000之间的随机数</li><li> 生成速记GUID字符串</li></ul>]]></content>
<categories>
<category>工具使用</category>
</categories>
<tags>
<tag>工具</tag>
<tag>前端</tag>
<tag>迁移</tag>
</tags>
</entry>
<entry>
<title>JavaScript</title>
<link href="/2023/06/24/JavaScript/"/>
<url>/2023/06/24/JavaScript/</url>
<content type="html"><![CDATA[<h1 id="JavaScript"><a href="#JavaScript" class="headerlink" title="JavaScript"></a>JavaScript</h1><h2 id="JS的作用"><a href="#JS的作用" class="headerlink" title="JS的作用"></a>JS的作用</h2><p>JS本身是一个脚本语言,主要作用于Web,由ECMAScript、DOM、BOM构成。</p><blockquote><p>可以拿来 表单动态校验、网页特效、服务端开发、桌面程序、APP、控制硬件、游戏开发等。</p></blockquote><h2 id="浏览器怎么执行JS"><a href="#浏览器怎么执行JS" class="headerlink" title="浏览器怎么执行JS"></a>浏览器怎么执行JS</h2><ul><li>渲染引擎:用于解析HTML和CSS,俗称内核</li><li>JS引擎:也称为JS解释器。用于读取网页中的JS代码,对其处理后运行。</li></ul><blockquote><p> 浏览器本身并不会执行JS代码,而是通过内置的JS引擎来执行JS代码,JS引擎执行代码时逐行解释每一句源码,然后由计算机去执行,所以JS语言归为脚本语言,会逐行解释执行。</p></blockquote><h1 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h1><p>JS时一种弱类型或者说动态的语言,这意味着不用提前声明变量的类型,在程序运行的过程中,类型会被自动锁定。</p><h2 id="Null-类型-amp-Undefined-类型"><a href="#Null-类型-amp-Undefined-类型" class="headerlink" title="Null 类型 & Undefined 类型"></a>Null 类型 & Undefined 类型</h2><p>这俩都只有本身即 <code>null</code> & <code>underfined</code> 。</p><blockquote><p>从概念上讲,<code>undefined</code> 表示<em>值</em>的缺失,<code>null</code> 表示<em>对象</em>的缺失,当某些东西没有值时,该语言通常默认为 <code>undefined</code>。</p></blockquote><h2 id="Boolean-类型"><a href="#Boolean-类型" class="headerlink" title="Boolean 类型"></a>Boolean 类型</h2><p><code>Boolean</code> 类型表示一个逻辑实体并且包括两个值:<code>true</code> 和 <code>false</code>。</p><h2 id="Number-类型"><a href="#Number-类型" class="headerlink" title="Number 类型"></a>Number 类型</h2><p><code>Number</code> 类型能存储±(2^-1074 ~2^1024)之间的浮点数,超过会自动转换为 ±Infinity.</p><blockquote><p>NaN是一种特殊的数值,当目前运算的结果不为数值的时候就会输出NaN</p></blockquote><h2 id="BigInt-类型"><a href="#BigInt-类型" class="headerlink" title="BigInt 类型"></a>BigInt 类型</h2><p><code>BigInt</code>类型在JS中是一个数字的原始值,它可以表示任意大小的整数。使用BigInt可以安全地存储和操作巨大的整数。</p><h2 id="String-类型"><a href="#String-类型" class="headerlink" title="String 类型"></a>String 类型</h2><p>字符串一般可以用来表示任何数据结构。但这并不总是一个好主意。例如,使用一个分隔符,可以模拟一个列表(而 JavaScript 数组可能更适合)。</p><h2 id="Symbol类型"><a href="#Symbol类型" class="headerlink" title="Symbol类型"></a>Symbol类型</h2><p><code>Symbol</code> 是<strong>唯一</strong>并且<strong>不可变</strong>的原始值并且可以用来作为对象属性的键(如下)。在某些程序语言当中,Symbol 也被称作“原子(atom)类型”。symbol 的目的是去创建一个唯一属性键,保证不会与其他代码中的键产生冲突。</p><h2 id="Object-类型"><a href="#Object-类型" class="headerlink" title="Object 类型"></a>Object 类型</h2><p>在JS中,对象是唯一可变的值。</p><blockquote><p>函数也是具有可以被调用能力的对象。</p></blockquote><h1 id="JS基础"><a href="#JS基础" class="headerlink" title="JS基础"></a>JS基础</h1><h2 id="Input-x2F-Output"><a href="#Input-x2F-Output" class="headerlink" title="Input/Output"></a>Input/Output</h2><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><code class="hljs JS"><span class="hljs-comment">//浏览器弹出警示框</span><br><span class="hljs-title function_">alert</span>(<span class="hljs-string">"msg"</span>)<br><span class="hljs-comment">//浏览器控制台打印输出信息---->程序员测试用</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(msg)<br><span class="hljs-comment">//浏览器弹出输入框,用户可以输入--->取到的值是字符串</span><br><span class="hljs-title function_">prompt</span>(info)<br><span class="hljs-comment">//可以打印我们返回的元素对象 更好的查看里面的属性和方法</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">dir</span>(msg)<br></code></pre></td></tr></table></figure><blockquote><p>有趣的是,Hacker有一种方法也是通过I/O,内嵌JS语句对网站或者对主机进行骇入。</p></blockquote><h2 id="正则表达式"><a href="#正则表达式" class="headerlink" title="正则表达式"></a>正则表达式</h2><h3 id="正则表达式概述"><a href="#正则表达式概述" class="headerlink" title="正则表达式概述"></a>正则表达式概述</h3><p>正则表达式是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也是对象。</p><h3 id="正则表达式的特点"><a href="#正则表达式的特点" class="headerlink" title="正则表达式的特点"></a>正则表达式的特点</h3><ul><li>灵活性、逻辑性和功能性非常的强。</li><li>可以迅速地用极为简单的方式达到字符串的复杂控制</li><li>对于刚接触的人来说,比较晦涩难懂。</li><li>实际开发中,一般都是直接复制写好的正则表达式,但是要求会使用正则表达式并且根据实际情况修改正则表达式。</li></ul><h3 id="正则表达式的组成"><a href="#正则表达式的组成" class="headerlink" title="正则表达式的组成"></a>正则表达式的组成</h3><p>一个正则表达式可以由简单的字符构成,也可以是简单和特殊字符的组合,其中特殊字符也被称为元字符,在正则表达式中是具有特殊意义的专用符号。</p><p>特殊字符可以参考:MDN</p><h1 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h1><h2 id="函数的使用"><a href="#函数的使用" class="headerlink" title="函数的使用"></a>函数的使用</h2><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><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">fuctionName</span>(<span class="hljs-params"></span>){<br> <span class="hljs-keyword">return</span> {<span class="hljs-string">"message"</span>:<span class="hljs-string">"hello"</span>}<br>}<br><span class="hljs-comment">//ECMAScript6</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">fuctionName</span> = (<span class="hljs-params"></span>) => {<br> <span class="hljs-keyword">return</span> {<span class="hljs-string">"message"</span>:<span class="hljs-string">"hello"</span>}<br>}<br></code></pre></td></tr></table></figure><h2 id="函数的返回"><a href="#函数的返回" class="headerlink" title="函数的返回"></a>函数的返回</h2><p>如果函数没有返回值就会返回undefined。</p><blockquote><p>在Vue3中,如果在行内使用@click = “functionName”之类的指令,带括号表示需要返回值,不带就是不需要。</p></blockquote><h1 id="对象"><a href="#对象" class="headerlink" title="对象"></a>对象</h1><h2 id="创建对象"><a href="#创建对象" class="headerlink" title="创建对象"></a>创建对象</h2><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><code class="hljs JS"><span class="hljs-keyword">const</span> objectName = {<br><span class="hljs-string">"kid"</span>:<span class="hljs-string">"isme"</span>,<br> <span class="hljs-string">"man"</span>:<span class="hljs-string">"isyou"</span><br>}<br><span class="hljs-comment">//使用New Object,值得一提的是该方法里是什么类型的数据创建出来的就是什么类型。</span><br><span class="hljs-keyword">const</span> objectName = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>({<br> <span class="hljs-string">"kid"</span>:<span class="hljs-string">"isme"</span>,<br> <span class="hljs-string">"man"</span>:<span class="hljs-string">"isyou"</span><br>})<br></code></pre></td></tr></table></figure><h2 id="遍历对象"><a href="#遍历对象" class="headerlink" title="遍历对象"></a>遍历对象</h2><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><code class="hljs js"><span class="hljs-comment">//for in</span><br><span class="hljs-keyword">for</span>(item <span class="hljs-keyword">in</span> <span class="hljs-title class_">ObjectName</span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(item)<br>}<br><span class="hljs-comment">//Object.keys() 返回属性名数组</span><br><span class="hljs-title class_">Object</span>.<span class="hljs-title function_">keys</span>(<span class="hljs-title class_">ObjectName</span>)<br><span class="hljs-comment">//Object.values() 返回属性值数组</span><br><span class="hljs-title class_">Object</span>.<span class="hljs-title function_">values</span>(<span class="hljs-title class_">ObjectName</span>)<br><span class="hljs-comment">//Object.entries() 返回嵌套数组</span><br><span class="hljs-title class_">Object</span>.<span class="hljs-title function_">entries</span>(<span class="hljs-title class_">ObjectName</span>)<br></code></pre></td></tr></table></figure><h1 id="内置对象"><a href="#内置对象" class="headerlink" title="内置对象"></a>内置对象</h1><ul><li>内置对象就是JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)</li><li>内置对象的最大优点就是帮助我们快速开发</li><li>JS提供了多个内置对象:Math、Data、Array、String等</li></ul><h1 id="DOM"><a href="#DOM" class="headerlink" title="DOM"></a>DOM</h1><ul><li>文档对象模型</li><li>DOM就是把文档当作一个对象来看待</li><li>DOM的顶级对象是document</li><li>DOM主要学习的是操作页面元素</li><li>DOM是W3C标准规范</li></ul><p>1.对于JS,为了能够使JS操作HTML,JS就有了一套自己的dom编程接口。</p><p>2.对于HTML,dom使得html形成一棵dom树。包括文档、元素、节点。</p><h2 id="什么是DOM"><a href="#什么是DOM" class="headerlink" title="什么是DOM"></a>什么是DOM</h2><p>文档对象模型(DOM),是一种标准编程接口。W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结果、样式。</p><h2 id="DOM树"><a href="#DOM树" class="headerlink" title="DOM树"></a>DOM树</h2><ul><li>文档:一个页面就是一个文档,DOM中使用document表示</li><li>元素:页面中的所有标签都是元素,DOM中用element表示</li><li>节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中用node表示</li></ul><p>==DOM把以上内容都看成对象==</p><h2 id="获取元素"><a href="#获取元素" class="headerlink" title="获取元素"></a>获取元素</h2><h3 id="根据ID获取"><a href="#根据ID获取" class="headerlink" title="根据ID获取"></a>根据ID获取</h3><ul><li>样式为:element.getElementById(’id’)</li></ul><h3 id="根据标签名获取"><a href="#根据标签名获取" class="headerlink" title="根据标签名获取"></a>根据标签名获取</h3><ul><li><p>样式为:element.getElementsTagName(’元素’)</p></li><li><p>得到的是对象的集合</p></li><li><p>输出要在元素后面加s</p></li></ul><h3 id="通过HTML5新增的方法获取"><a href="#通过HTML5新增的方法获取" class="headerlink" title="通过HTML5新增的方法获取"></a>通过HTML5新增的方法获取</h3><ul><li>考虑兼容性不可使用</li><li>样式为:element.getElementsClassName(’元素’)//根据类名返回元素对象集合</li><li>样式为:element.querySelector(’选择器’) //根据指定选择器返回第一个元素对象—>比如.什么什么就是类选择器<ul><li>只能返回第一个元素对象</li><li>返回全部的话:element.querySelectorAll(’选择器’)</li></ul></li></ul><h3 id="特殊元素获取"><a href="#特殊元素获取" class="headerlink" title="特殊元素获取"></a>特殊元素获取</h3><ul><li>获取body标签<ul><li>样式element.body;</li></ul></li><li>获取html元素<ul><li>样式element.documentElement;</li></ul></li></ul><h2 id="事件基础"><a href="#事件基础" class="headerlink" title="事件基础"></a>事件基础</h2><h3 id="事件概述"><a href="#事件概述" class="headerlink" title="事件概述"></a>事件概述</h3><p>JS使我们有能力创建动态页面,而事件是可以被JS侦测到的行为</p><p>简单理解:触发—响应机制</p><p>事件由三部分组成: 事件源 事件类型 事件处理程序</p><ul><li>事件源 事件被触发的对象 如 按钮<ul><li>var btn=button.getElementById(‘btn’)</li></ul></li><li>事件类型 如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下</li><li>事件处理程序 通过一个函数赋值的方式完成<ul><li>btn.onclick=function( ){…..}</li></ul></li></ul><h3 id="执行事件的步骤"><a href="#执行事件的步骤" class="headerlink" title="执行事件的步骤"></a>执行事件的步骤</h3><ul><li>获取事件源</li><li>注册事件(绑定事件)</li><li>添加事件处理程序</li></ul><h3 id="鼠标事件操作"><a href="#鼠标事件操作" class="headerlink" title="鼠标事件操作"></a>鼠标事件操作</h3><ul><li>onclick鼠标点击左键触发。</li><li>onmouseover鼠标经过触发</li><li>onmouseout鼠标离开触发</li><li>onfocus获得鼠标焦点触发</li><li>onblur失去鼠标焦点触发</li><li>onmousemove鼠标移动触发</li><li>onmouseup鼠标弹起触发</li><li>onmousedown鼠标按下触发</li></ul><h2 id="操作元素"><a href="#操作元素" class="headerlink" title="操作元素"></a>操作元素</h2><h3 id="改变元素内容"><a href="#改变元素内容" class="headerlink" title="改变元素内容"></a>改变元素内容</h3><ul><li><p>element.innerText= 可以改变元素内容(不识别html标签)</p></li><li><p>element.innerHTML= 可以改变元素内容(识别html标签)——使用最多</p></li></ul><h3 id="样式属性操作"><a href="#样式属性操作" class="headerlink" title="样式属性操作"></a>样式属性操作</h3><ul><li>element.style=行内样式操作</li><li>element.className=类名样式操作</li></ul><h3 id="改变元素类名"><a href="#改变元素类名" class="headerlink" title="改变元素类名"></a>改变元素类名</h3><ul><li>在JS中想一下子改很多,而且有多个项目要更改时,可以用更改类名。</li><li>正常是element.style修改的样式,但是你可以先定义一个类名是你要修改后的样式,然后写this.className=’该类名’,就可以做到修改了。(会进行覆盖)</li><li>如果想要保留原来的类名,可以用this.className=’原来的类名 该类名’ 这样。</li></ul><h3 id="自定义属性的操作"><a href="#自定义属性的操作" class="headerlink" title="自定义属性的操作"></a>自定义属性的操作</h3><ul><li>获取属性值<ul><li>element.属性 获取属性值</li><li>element.getAttribute(‘属性’);</li></ul></li><li>区别:<ul><li>element.属性 获取内置属性值(元素本身自带的属性)</li><li>element.getAttribute(‘属性’); 主要获得自定义的(标准)我们程序员自定义的属性(没错,属性是可以自定义的)</li></ul></li><li>设置属性值<ul><li>element.属性=“值” 设置内置属性值。</li><li>element.setAttribute(‘属性’,’值’)</li></ul></li></ul><h2 id="节点"><a href="#节点" class="headerlink" title="节点"></a>节点</h2><h3 id="节点概述"><a href="#节点概述" class="headerlink" title="节点概述"></a>节点概述</h3><p>一般的,节点至少拥有nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)这三个基本属性。</p><ul><li>元素节点 nodeType 为 1;</li><li>属性节点 nodeType 为 2;</li><li>文本节点 nodeType 为 3(文本节点包含文字、空格、换行等);</li></ul><p><strong>我们在实际开发中,节点操作的主要操作的是元素节点</strong></p><p>为什么要用节点操作呢?</p><p>因为在利用我们节点层次关系获取元素的时候会更简单一些。</p><h3 id="节点层级"><a href="#节点层级" class="headerlink" title="节点层级"></a>节点层级</h3><p>利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系</p><ul><li>element.parentNode就可以直接代替var …………(得到的是离元素最近的父节点)</li><li>element.childNodes返回包含指定节点的子节点的集合,该集合为即时更新的集合。而且childNodes返回的是所有子节点 包括元素节点、文本节点等等。</li><li>element.children返回所有元素子节点,虽然看着很不兼容,但是各个浏览器都是允许使用的。其中对第一个元素子节点和最后一个子节点有特殊的获取方式:(包括元素节点、文本节点等等)<ul><li>第一个子节点:element.firstChild即为获取第一个子节点。</li><li>最后的子节点:element.lastChild即为获取最后一个子节点。</li><li>第一个元素子节点:element.firstElementChild即为获取第一个元素子节点。(有兼容性问题IE9+支持)</li><li>最后的元素子节点:element.lastElementChild即为获取最后的元素子节点。(有兼容性问题IE9+支持)</li><li>正常开发的写法都是element.children[number]这样。</li></ul></li><li>兄弟节点:<ul><li>下一个兄弟节点:element.nextSibling返回当前元素的下一个兄弟节点,找不到则返回NULL</li><li>上一个兄弟节点:element.previousSibling返回当前元素上一个兄弟节点,找不到则返回null</li><li>下一个元素兄弟节点:element.nextElementSibling返回当前元素的下一个元素兄弟节点(有兼容性问题IE9+支持)</li><li>上一个元素兄弟节点:element.previousElementSibling返回当前元素的上一个元素兄弟节点(有兼容性问题IE9+支持)</li></ul></li></ul><h3 id="节点操作"><a href="#节点操作" class="headerlink" title="节点操作"></a>节点操作</h3><ul><li>创建元素节点:var 节点名字=document.creatElement(‘需要创建的节点’) (innerHTML也可以创建节点,但是innerHTML的原理是拼接字符串,creatElement是创建新节点,所以,creatElement会相对快很多。</li><li>添加元素节点:<ul><li>element.appendChild(child)其中element是父级,child是子级 将一个节点添加到指定父节点的子节点列表末尾,类似于CSS中的after伪元素。</li><li>element.insertBefore(child,指定元素) 将一个节点添加到父节点的指定子节点前面。类似于CSS里面的before伪元素。</li></ul></li><li>删除元素节点:element.remove(需要删除的元素节点);(例如某某元素[])</li><li>克隆元素节点:element.cloneNode(); 复制元素节点,但是复制后需要添加,相当于var name=node.cloneNode(); 然后再使用添加元素节点的知识进行添加。<ul><li>括号为空或为false则为浅拷贝,即只复制节点本身,不copy里面的子节点。</li><li>括号里为ture则为深拷贝,可以复制节点里面的所有东西。</li></ul></li></ul><h3 id="事件高级"><a href="#事件高级" class="headerlink" title="事件高级"></a>事件高级</h3><h4 id="注册事件"><a href="#注册事件" class="headerlink" title="注册事件"></a>注册事件</h4><ul><li><p>注册事件概述:给元素添加事件,称为注册事件或者绑定事件。</p></li><li><p>注册事件有两种方式:传统方式和方法监听注册方式。</p></li><li><p>传统注册方式:</p><ul><li><p>利用on开头的事件onclick</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"alert('hi~')"</span>></span><span class="hljs-tag"></<span class="hljs-name">button</span>></span><br></code></pre></td></tr></table></figure></li><li><p>btn.onclick=function(){}</p></li><li><p>特点注册事件的唯一性</p></li><li><p>同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数。</p></li></ul></li><li><p>方法监听注册方式:</p><ul><li>w3c标准 推荐方法</li><li>addEventListener()它是一个方法</li><li>IE9之前的IE不支持此方法,可使用attachEvent()代替</li><li>特点:同一个元素,同一个事件可以注册多个监听器。</li><li>按注册顺序依次执行。</li></ul></li><li><p>addEventListener事件监听方式</p><ul><li>eventTarget.addEventListener(type,listener[,useCapture])方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会触发执行事件处理函数。</li><li>该方法接收三个参数:<ul><li>type:事件类型字符串,比如click,mouseover,注意这里不要带on</li><li>listener:事件处理函数,事件发生时,会调用该监听函数。</li><li>useCapture:可选参数,用于描述事件是冒泡还是捕获,是一个布尔值,默认是false。</li></ul></li></ul></li><li><p>attachEvent事件监听方式(IE9前版本支持)</p><ul><li>eventTarget.attachEvent(eventNameWithOn,callback)方法将指定的监听器注册到eventTarget上,当该对象触发指定的事件时,指定的回调函数就会被执行。</li><li>该方法接受两个函数:<ul><li>eventNameWithOn:事件类型字符串,比如onclick,onmouseover这里要带on</li><li>callback:事件处理函数,当目标触发事件时回调函数被调用。</li></ul></li></ul></li></ul><h4 id="解绑事件"><a href="#解绑事件" class="headerlink" title="解绑事件"></a>解绑事件</h4><ul><li><p>传统注册方式:eventTarget.onclick=null;</p></li><li><p>方法监听注册方式:</p><ul><li><p>eventTargrt.removeEventListener(type,listener[,useCapture]);</p><p>其中listener要写函数的名称,这也就意味着注册的时候也要用函数的名称。</p></li><li><p>eventTargrt.detachEventListener(type,listener[,useCapture]);</p><p>此为IE9前适用</p></li></ul></li></ul><h2 id="DOM事件流"><a href="#DOM事件流" class="headerlink" title="DOM事件流"></a>DOM事件流</h2><p>事件流描述的是从页面中接收事件的顺序。</p><p>事件发生时会在元素节点之间按照待定的顺序传播,这个传播过程即为DOM事件流。</p><p>DOM事件流分为三个阶段:1.捕获阶段。2.当前目标阶段。3.冒泡阶段。</p><ul><li><p>事件冒泡:IE最早提出,事件开始时由最具体的元素接收,然后<strong>逐级上</strong>传到DOM最顶层节点的过程。</p><p>有些事件是没有冒泡的:例如onblur、onfocus、onmouseenter、onmouseleave</p></li><li><p>事件捕获:网景最早提出,由DOM最顶层节点开始,然后<strong>逐级向下</strong>传播到最具体的元素接收过程。</p></li><li><p>结合useCapture,若useCapture为true则为事件捕获,false为事件冒泡</p></li></ul><h2 id="事件对象"><a href="#事件对象" class="headerlink" title="事件对象"></a>事件对象</h2><p>div.onclick=function(event){}</p><p>1.event就是一个事件对象,写到我们侦听函数的小括号里面,当形参来看。即事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象event,他有很多的属性和方法。</p><p>2.事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数。</p><p>3.事件对象是我们事件的一系列相关数据的集合,跟事件相关的,比如鼠标点击里面就包含鼠标的相关信息,鼠标坐标之类的,如果是键盘事件里面就包含的键盘事件的信息,比如判断用户按下了哪个键。</p><p>4.这个事件对象我们可以自己命名 比如event、evt、e(你第一次写的空洞骑士界面音乐盒就是e)</p><p>5.事件对象也有兼容性问题 IE678通过window.event</p><p>兼容性写法e=e||window.event</p><h3 id="事件对象的常见属性和方法"><a href="#事件对象的常见属性和方法" class="headerlink" title="事件对象的常见属性和方法"></a>事件对象的常见属性和方法</h3><ul><li><p>e.target 返回触发事件的对象 标准</p><p>e.target返回的是触发事件的对象(元素) this返回的是绑定事件的对象(元素)如绑定ul但触发的li</p></li><li><p>e.srcElement 返回触发事件的对象 非标准IE6~8使用</p></li><li><p>e.type 返回事件的类型 比如click mouseover不带on</p></li><li><p>e.cancelBubble 该属性阻止冒泡 非标准 IE6~8使用</p></li><li><p>e.stopPropagation 该方法阻止冒泡 标准</p></li><li><p>e.returnValue 该属性阻止默认事件 非标准IE6~8使用 比如不让链接跳转</p></li><li><p>e.preventDefault 该方法阻止默认事件 标准 比如不让链接跳转</p></li></ul><h3 id="事件委托(代理、委派)"><a href="#事件委托(代理、委派)" class="headerlink" title="事件委托(代理、委派)"></a>事件委托(代理、委派)</h3><p>事件委托也称为事件代理,在jQuery里面称为事件委派。</p><ul><li>事件委托的原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响每一个子节点(面试时用得到!!!!!!) </li><li>事件委托的作用:只操作了一次DOM,提高了程序的性能。</li></ul><h2 id="常用的鼠标事件"><a href="#常用的鼠标事件" class="headerlink" title="常用的鼠标事件"></a>常用的鼠标事件</h2><h3 id="常见的鼠标事件"><a href="#常见的鼠标事件" class="headerlink" title="常见的鼠标事件"></a>常见的鼠标事件</h3><ul><li><p>contextmenu是鼠标右键的菜单</p></li><li><p>selectstart是鼠标的选中(拉动的选中)</p></li><li><p>click 单击鼠标左键时发生,如果右键也按下则不会发生。当用户的焦点在按钮上并按了 Enter 键时,同样会触发这个事件</p></li><li><p>mousedown 单击任意一个鼠标按钮时发生</p></li><li><p>mouseout 鼠标指针位于某个元素上且将要移出元素的边界时发生</p></li><li><p>mouseover 鼠标指针移出某个元素到另一个元素上时发生</p></li><li><p>mouseup 松开任意一个鼠标按钮时发生</p></li><li><p>mousemove 鼠标在某个元素上时持续发生</p></li></ul><h3 id="鼠标事件对象"><a href="#鼠标事件对象" class="headerlink" title="鼠标事件对象"></a>鼠标事件对象</h3><ul><li>e.clientX 返回鼠标相对于浏览器窗口可视区的X坐标</li><li>e.clientY 返回鼠标相对于浏览器窗口可视区的Y坐标</li><li>e.pageX 返回鼠标相对于文档页面的X坐标 IE9+支持</li><li>e.pageY 返回鼠标相对于文档页面的Y坐标 IE9+支持</li><li>e.screenX 返回鼠标相对于电脑屏幕的X坐标</li><li>e.screenY 返回鼠标相对于电脑屏幕的Y坐标</li></ul><h3 id="mouseenter和mouseover的区别"><a href="#mouseenter和mouseover的区别" class="headerlink" title="mouseenter和mouseover的区别"></a>mouseenter和mouseover的区别</h3><p>mouseover经过自身盒子会触发,经过子盒子还会触发。</p><p>mouseenter只有经过自身盒子才会触发。(不会冒泡)</p><h2 id="常用的键盘事件"><a href="#常用的键盘事件" class="headerlink" title="常用的键盘事件"></a>常用的键盘事件</h2><h3 id="常用键盘事件"><a href="#常用键盘事件" class="headerlink" title="常用键盘事件"></a>常用键盘事件</h3><ul><li>onkeyup 某个键盘按键被松开时触发</li><li>onkeydown 某个键盘按键被按下时触发</li><li>onkeypress 某个键盘按键被按下时触发 但是不能识别功能键 如ctrl shift 箭头等</li></ul><h3 id="键盘事件对象"><a href="#键盘事件对象" class="headerlink" title="键盘事件对象"></a>键盘事件对象</h3><ul><li>KeyCode 返回键盘按下键的ASCII码值<ul><li>keyup和keydown事件不区分字母大小写,都按照大写来看</li><li>keypress事件区分字母大小写</li></ul></li></ul><h1 id="BOM"><a href="#BOM" class="headerlink" title="BOM"></a>BOM</h1><ul><li>浏览器对象模型</li><li>把浏览器当作一个对象来看待</li><li>BOM的顶级对象是window</li><li>BOM学习的是浏览器窗口交互的一些对象</li><li>BOM是浏览器厂商在各自浏览器上定义的,兼容性较差</li></ul><h2 id="BOM概述"><a href="#BOM概述" class="headerlink" title="BOM概述"></a>BOM概述</h2><p>BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象时window。</p><p>BOM由一系列相关的对象构成,并且每个对象都提供了很多方法和属性。</p><p>BOM缺乏标准,JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C</p><h2 id="BOM的构成"><a href="#BOM的构成" class="headerlink" title="BOM的构成"></a>BOM的构成</h2><p>window对象是浏览器的顶级对象,它具有双重角色</p><p>1.它是JS访问浏览器窗口的一个接口</p><p>2.他是一个全局对象。定义在全局作用域中的变量、函数都会变成window对象的属性和方法。</p><p>在调用的时候可以省略window,前面学习的对话框都属于window对象方法,如alert、prompt等</p><h2 id="window对象的常见事件"><a href="#window对象的常见事件" class="headerlink" title="window对象的常见事件"></a>window对象的常见事件</h2><h3 id="窗口加载事件"><a href="#窗口加载事件" class="headerlink" title="窗口加载事件"></a>窗口加载事件</h3><ul><li>window.onload=function(){}</li></ul><p>或者</p><ul><li><p>window.addEventListener(“load”,function(){});</p></li><li><p>window.onload是窗口(页面)加载事件,当文档内容完全加载会触发该事件(包括图像、脚本文件、CSS文件等),就调用的处理函数。</p></li><li><p>document.addEventListener(‘DOMCotentLoaded’,function(){})</p><ul><li>DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表、图片、flash等。</li><li>IE9以上才支持</li><li>如果页面的图片很多的话,从用户访问到onload触发可能需要较长时间,交互效果就不能实现,必然影响用户体验,此时用DOMCotentLoaded事件比较合适。</li></ul></li></ul><p>注意:</p><ul><li>有了window.onload就可以把JS代码写到页面元素的上方,因为onload是等页面内容全部加载完毕,再去执行处理函数。</li><li>window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload为准。(addEventListener则没有限制)</li></ul><h3 id="调整窗口大小事件"><a href="#调整窗口大小事件" class="headerlink" title="调整窗口大小事件"></a>调整窗口大小事件</h3><ul><li>window.onresize=function(){}</li><li>window.addEventListener(“resize”,function(){})</li><li>window.onresize是调整窗口大小加载事件,当触发时就调用的处理函数。<ul><li>只要窗口大小发生像素变化,就会触发这个事件。</li><li>我们经常利用这个事件完成响应式布局。window.innerWidth为当前屏幕的宽度</li></ul></li></ul><h3 id="定时器"><a href="#定时器" class="headerlink" title="定时器"></a>定时器</h3><h4 id="setTimeout-定时器"><a href="#setTimeout-定时器" class="headerlink" title="setTimeout()定时器"></a>setTimeout()定时器</h4><p>window.setTimeout(调用函数,[延迟的毫秒数]); </p><p>setTimeout()方法用于设置一个定时器,在该定时器在定时器到期后会执行调用函数。</p><ul><li>window可以省略</li><li>这个调用函数可以直接写函数,或者写函数名或者采取字符串‘函数名()’三种形式。第三种不推荐。</li><li>延迟的毫秒数省略默认为0,如果写,必须是毫秒。</li><li>因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。</li></ul><h4 id="停止setTimeout-定时器"><a href="#停止setTimeout-定时器" class="headerlink" title="停止setTimeout()定时器"></a>停止setTimeout()定时器</h4><p>window.clearTimeout(timeout ID)</p><ul><li>window可以省略</li><li>里面的参数就是定时器的名字</li></ul><h4 id="setlnterval-定时器"><a href="#setlnterval-定时器" class="headerlink" title="setlnterval()定时器"></a>setlnterval()定时器</h4><p>window.setInterval(调用函数,[延迟的毫秒数]); </p><p>setlnterval()方法重复调用一个函数,每隔这个时间,就去调用一次回调函数。</p><ul><li>window可以省略</li><li>这个调用函数可以直接写函数,或者写函数名或者采取字符串‘函数名()’三种形式。</li><li>延迟的毫秒数省略默认为0,如果写,必须是毫秒。</li><li>因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。</li></ul><h4 id="停止setInterval-定时器"><a href="#停止setInterval-定时器" class="headerlink" title="停止setInterval()定时器"></a>停止setInterval()定时器</h4><p>window.clearInterval(interval ID)</p><ul><li>window可以省略</li><li>里面的参数就是定时器的名字</li></ul><h3 id="this"><a href="#this" class="headerlink" title="this"></a>this</h3><p>this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向的是那个调用它的对象</p><ul><li>全局作用域或者普通函数中this指向全局对象window、</li><li>方法调用中谁调用就指向谁</li></ul><h2 id="JS执行机制"><a href="#JS执行机制" class="headerlink" title="JS执行机制"></a>JS执行机制</h2><h3 id="JS是单线程"><a href="#JS是单线程" class="headerlink" title="JS是单线程"></a>JS是单线程</h3><p>Javascript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为Javascript这门脚本语言诞生的使命所致——Javascript是为处理页面中用户的交互以及操作DOM而诞生的。</p><p>单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。</p><h3 id="同步和异步"><a href="#同步和异步" class="headerlink" title="同步和异步"></a>同步和异步</h3><p>为了解决这个问题,利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程。于是JS出现了同步和异步。</p><ul><li>同步任务:同步任务都在主线程上执行,形成一个执行栈。</li><li>异步任务:JS的异步是通过回调函数实现的。一般而言,异步事件有以下三种类型:<ul><li>普通事件:如click,resize</li><li>资源加载:如load,error</li><li>定时器:如setInterval,setTimeout</li></ul></li></ul><p>JS 设计之初就是一个单线程的编程语言,单线程的异步编程方式有无需考虑线程同步和资源竞争的问题,从源头上避免了线程切换。</p><h3 id="异步编程"><a href="#异步编程" class="headerlink" title="异步编程"></a>异步编程</h3><p>如果我们需要依次进行多个异步操作,使用回调函数会一层一层的嵌套下去,可读性会变得非常的差,这种情况也叫做“回调地狱”。Promise应运而生。</p><blockquote><p>Fetch函数就是Promise很好的例子,fetch先向目标服务器发送请求,<code>.then()</code>中表示如果服务器返回了,则会执行下面的语句。</p></blockquote><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><code class="hljs js"><span class="hljs-comment">//举个异步例子</span><br><span class="hljs-title function_">fetch</span>(<span class="hljs-string">"https://...."</span>)<br>.<span class="hljs-title function_">then</span>( <span class="hljs-function">()=></span> { <span class="hljs-comment">//获取到数据之后做什么</span><br>})<br>.<span class="hljs-title function_">catch</span>(<span class="hljs-function">()=></span> { <span class="hljs-comment">//抛出错误后做什么</span><br>})<br>.<span class="hljs-title function_">finally</span>(<span class="hljs-function">()=></span> { <span class="hljs-comment">//异步结束后做什么</span><br>})<br><span class="hljs-comment">//异步中的错误使用.catch() then不会执行。</span><br><span class="hljs-comment">//.finally()是Promise结束时调用无论失败与否,可以做清除工作。</span><br></code></pre></td></tr></table></figure><p>async和await是ES17的语法糖。</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></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//举个例子</span><br><span class="hljs-comment">//async 可以直接用在 function前面用于标记 ,await 只能在 async函数中使用。</span><br><span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">test</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-comment">//可以用await直接获得异步函数的返回值,await过程中还是异步</span><br><span class="hljs-keyword">const</span> res1 = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>(<span class="hljs-string">"https://...."</span>)<br> <span class="hljs-keyword">const</span> res2 = <span class="hljs-keyword">await</span> <span class="hljs-title function_">fetch</span>(<span class="hljs-string">"https://...."</span>)<br> <span class="hljs-comment">//如果需要同时异步多个,不然像上面这样就是同步</span><br> <span class="hljs-keyword">const</span> [a,b] = <span class="hljs-keyword">await</span> <span class="hljs-title class_">Promise</span>.<span class="hljs-title function_">all</span>([res1,res2])<br> <span class="hljs-comment">//如果在循环中执行异步操作,是不可以直接调用forEach和map这类方法,还是用for,如果需要循环中每个步骤都异步执行,使用for await</span><br> <span class="hljs-keyword">for</span> <span class="hljs-keyword">await</span> (<span class="hljs-keyword">let</span> test <span class="hljs-keyword">of</span> tests){ }<br>}<br></code></pre></td></tr></table></figure><h3 id="执行机制"><a href="#执行机制" class="headerlink" title="执行机制"></a>执行机制</h3><p>1.先执行执行栈中的同步任务</p><p>2.异步任务放入任务队列</p><p>3.一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。</p><h2 id="location对象"><a href="#location对象" class="headerlink" title="location对象"></a>location对象</h2><h3 id="location对象概述"><a href="#location对象概述" class="headerlink" title="location对象概述"></a>location对象概述</h3><p>window对象给我们提供了一个location属性用于获取或设置窗体的URL,并且可以解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象。</p><h3 id="URL"><a href="#URL" class="headerlink" title="URL"></a>URL</h3><p>统一资源定位符(Uniform Resource Locator,URL)是互联网上标准资源的地址。互联网上的每个文件都有唯一的一个URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。</p><p>URL的一般语法格式为:</p><p>protocol://host[:port]/path/[?query]#fragment</p><p>如<a href="http://www.itcast.cn/index.html?name=andy&age=18#link">http://www.itcast.cn/index.html?name=andy&age=18#link</a></p><ul><li>protocol:通信协议 常用的http,ftp,maito</li><li>host:主机(域名)</li><li>port:端口号 可选,省略时使用方案的默认端口 如http的默认端口为80</li><li>path:路径 由0或多个/符号分割开的字符串,一般用来表示主机上的一个目录或文件地址</li><li>query:参数 以键值对的形式,通过&符号分开</li><li>fragment:片段 #后内容常见于锚点 链接</li></ul><h3 id="location对象的属性"><a href="#location对象的属性" class="headerlink" title="location对象的属性"></a>location对象的属性</h3><ul><li>location.href:获取或设置整个URL</li><li>location.host:返回主机(域名)</li><li>location.port:返回端口号 如果未写返回 空字符串</li><li>location.pathname:返回路径</li><li>location.search:返回参数</li><li>location.hash:返回片段 #后面内容</li></ul><h3 id="location对象的方法"><a href="#location对象的方法" class="headerlink" title="location对象的方法"></a>location对象的方法</h3><ul><li>location.assign():跟href一样,可以转跳页面</li><li>location.replace():替换当前页面,因为不记录历史,所以不能后退页面。</li><li>location.reload():重新加载当前页面,相当于刷新按钮或者F5如果参数为true 强制刷新ctrl+f5</li></ul><h2 id="navigator对象"><a href="#navigator对象" class="headerlink" title="navigator对象"></a>navigator对象</h2><p>navigator对象包含有关浏览器的信息,它有很多属性,我们最常用的是userAgent,该属性可以返回由客户机发送的user-agent头部的值。</p><p>下面前端代码可以判断用户哪个终端打开界面,实现转跳:</p><p>if((navigator.userAgent.match(/(phone|pad|pod|iPhone|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|WOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))){</p><p>window.location.href=””; //手机</p><p>}else{<br>window.location.href=””;//电脑</p><p>}</p><h2 id="history对象"><a href="#history对象" class="headerlink" title="history对象"></a>history对象</h2><p>window对象给我们提供了一个history对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL</p><ul><li>history.back()可以使用后退功能</li><li>history.forward()前进功能</li><li>history.go(参数)前进后退功能 参数如果是1前进一个页面,如果是-1 后退一个页面。</li></ul>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
<tag>迁移</tag>
</tags>
</entry>
<entry>
<title>JQuery</title>
<link href="/2023/06/24/JQuery/"/>
<url>/2023/06/24/JQuery/</url>
<content type="html"><![CDATA[<h1 id="JQuery"><a href="#JQuery" class="headerlink" title="JQuery"></a>JQuery</h1><p>但是他已经过时了,不建议去学,了解即可(2024)</p><p><a href="https://jquery.cuishifeng.cn/">jQuery API 中文文档链接</a></p><h3 id="JavaScript库"><a href="#JavaScript库" class="headerlink" title="JavaScript库"></a>JavaScript库</h3><p>即library,是一个封装好的特定的集合(方法和函数)。从封装一大堆函数的角度理解库,就是在这个库中,封装了很多预先定义好的函数在里面,比如动画animate、hide、show。</p><p>简单理解:就是一个JS文件,里面对我们原生的JS代码进行了封装,存放到里面。这样我们可以快速高效的使用封装好的功能。</p><h3 id="jQuery的优点"><a href="#jQuery的优点" class="headerlink" title="jQuery的优点"></a>jQuery的优点</h3><ul><li>轻量级。</li><li>跨浏览器兼容</li><li>链式编程、隐式迭代</li><li>对事件、样式、动画支持,大大简化了DOM操作。</li><li>支持插件扩展开发。有着丰富的第三方插件,例如:树形菜单、日期控件、轮播图等。</li><li>免费开源。</li></ul><h3 id="jQuery的顶级对象"><a href="#jQuery的顶级对象" class="headerlink" title="jQuery的顶级对象$"></a>jQuery的顶级对象$</h3><p>1.$是jQuery的别称,在代码中可以使用jQuery代替它,但一般为了方便都是直接使用。</p><p>2.$是jQuery的顶级对象,相当于原生JavaScript中的window。把元素利用它包装成jQuery对象,就可以调用jQuery的方法。</p><h3 id="jQuery对象和DOM对象"><a href="#jQuery对象和DOM对象" class="headerlink" title="jQuery对象和DOM对象"></a>jQuery对象和DOM对象</h3><p>DOM对象与jQuery对象之间是可以相互转换的。</p><p>因为原生JS比jQuery更大,原生的一些属性和方法jQuery没有给我们封装,想要使用这些属性和方法需要把jQuery对象转换为DOM对象才能使用。</p><ul><li><p>DOM对象转换为jQuery对象</p><ul><li>$(‘div’)</li></ul></li><li><p>jQuery对象转化为DOM对象(两种方式)</p><ul><li>$(‘div’)[index]index是索引号</li><li>$(‘div’).get(index) index是索引号</li></ul></li></ul><h3 id="jQuery选择器"><a href="#jQuery选择器" class="headerlink" title="jQuery选择器"></a>jQuery选择器</h3><h5 id="jQuery基础选择器"><a href="#jQuery基础选择器" class="headerlink" title="jQuery基础选择器"></a>jQuery基础选择器</h5><p>原生JS获取元素的方式有很多、很杂,而且兼容情况不一样,因此jQuery给我们做了封装,使获取元素统一标准。</p><p>$(“选择器”)//里面选择器直接写CSS选择器即可,但要加引号</p><h5 id="jQuery设置样式"><a href="#jQuery设置样式" class="headerlink" title="jQuery设置样式"></a>jQuery设置样式</h5><p>$(“div”).css(“属性”,”值”)</p><h5 id="隐式迭代(重要)"><a href="#隐式迭代(重要)" class="headerlink" title="隐式迭代(重要)"></a>隐式迭代(重要)</h5><p>遍历内部DOM元素(伪数组形式存储)的过程就叫做隐式迭代。</p><p>简单理解:给匹配到的所有元素进行循环遍历,执行相应的方法,而不用我们再进行循环,简化我们的操作,方便我们调用。</p><h5 id="jQuery筛选选择器"><a href="#jQuery筛选选择器" class="headerlink" title="jQuery筛选选择器"></a>jQuery筛选选择器</h5><p>用法如$(“li:first”)</p><ul><li>:first 获取第一个元素</li><li>:last 获取最后一个元素</li><li>:eq(index) 获取到的元素中,选择索引号为2的元素,index从0开始。</li><li>:odd 获取到的元素中,索引号为奇数的元素</li><li>:even 获取到的元素中,索引号为偶数的元素</li></ul><h5 id="jQuery筛选方法"><a href="#jQuery筛选方法" class="headerlink" title="jQuery筛选方法"></a>jQuery筛选方法</h5><p>用法如$(“li”).parent()</p><ul><li>parent() 查找父级</li><li>children(selector) 相当于$(“ul>li”),最近一级(亲儿子)</li><li>find(selector) 相当于$(“ul li”), 后代选择器</li><li>siblings(selector) 查找兄弟节点,不包括自己本身</li><li>nextAll([expr]) 查找当前元素之后所有的同辈元素</li><li>prevAll([expr]) 查找当前元素之前所有的同辈元素</li><li>hasClass(class) 检查当前的元素是否含有某个特定的类,如果有,返回true</li><li>eq(index) 相当于$(“li:eq(2)”),index从0开始.</li></ul><h5 id="链式编程"><a href="#链式编程" class="headerlink" title="链式编程"></a>链式编程</h5><p>链式编程是为了节省代码量,看起来更优雅。</p><h3 id="jQuery样式操作"><a href="#jQuery样式操作" class="headerlink" title="jQuery样式操作"></a>jQuery样式操作</h3><h5 id="操作CSS方法"><a href="#操作CSS方法" class="headerlink" title="操作CSS方法"></a>操作CSS方法</h5><p>jQuery可以使用css方法来修改简单元素样式;也可以操作类,修改多个样式。</p><ul><li>参数只写属性名,则是返回属性值。</li><li>参数是属性名,属性值,逗号分隔,是设置一组样式,属性必须加引号,值如果是数字可以不用跟单位和引号。</li><li>参数可以是对象形式,方便设置多组样式。属性名和属性值用冒号隔开,属性可以不用加引号。如$(“div”).css({width:400,height:400})</li></ul><h5 id="设置类样式方法"><a href="#设置类样式方法" class="headerlink" title="设置类样式方法"></a>设置类样式方法</h5><ul><li>添加类:$(“div”).addClass(“current”);</li><li>移除类:$(“div”).removeClass(“current”);</li><li>切换类:$(“div”).toggleClass(“current”);</li></ul><h5 id="类操作与className区别"><a href="#类操作与className区别" class="headerlink" title="类操作与className区别"></a>类操作与className区别</h5><p>原生JS中className会覆盖元素原先里面的类名</p><p>jQuery里面类操作只是对指定类进行操作,不影响原先的类名。</p><h3 id="jQuery效果"><a href="#jQuery效果" class="headerlink" title="jQuery效果"></a>jQuery效果</h3><h5 id="显示隐藏"><a href="#显示隐藏" class="headerlink" title="显示隐藏"></a>显示隐藏</h5><ul><li><p>显示语法规范:show([speed],[easing],[fn])</p></li><li><p>显示参数:</p><ul><li>参数都可以省略,无动画直接显示</li><li>speed:三种预定速度之一的字符串(“slow”,”normal”,”fast”)或是表示动画时长的毫秒数值</li><li>easing:用于指定切换效果,默认是”swing”</li><li>fn:回调函数,在动画完成时执行的函数,每个元素执行一次。</li></ul></li><li><p>show()</p></li><li><p>hide()</p></li><li><p>toggle()</p></li></ul><h5 id="滑动"><a href="#滑动" class="headerlink" title="滑动"></a>滑动</h5><ul><li><p>滑动语法规范:slideDown([speed],[easing],[fn])</p></li><li><p>滑动参数:</p><ul><li>参数都可以省略,无动画直接显示</li><li>speed:三种预定速度之一的字符串(“slow”,”normal”,”fast”)或是表示动画时长的毫秒数值</li><li>easing:用于指定切换效果,默认是”swing”</li><li>fn:回调函数,在动画完成时执行的函数,每个元素执行一次。</li></ul></li><li><p>slideDown()</p></li><li><p>slideUp()</p></li><li><p>slideToggle()</p></li></ul><h5 id="淡入淡出"><a href="#淡入淡出" class="headerlink" title="淡入淡出"></a>淡入淡出</h5><ul><li><p>淡入淡出语法规范:fadeIn([speed],[easing],[fn])</p></li><li><p>淡入淡出参数:</p><ul><li>参数都可以省略,无动画直接显示</li><li>speed:三种预定速度之一的字符串(“slow”,”normal”,”fast”)或是表示动画时长的毫秒数值</li><li>easing:用于指定切换效果,默认是”swing”</li><li>fn:回调函数,在动画完成时执行的函数,每个元素执行一次。</li></ul></li><li><p>fadeIn()</p></li><li><p>fadeOut()</p></li><li><p>fadeToggle()</p></li><li><p>fadeTo()</p><ul><li>渐进方式调整到指定的不透明度:fadeTo([speed],opacity,[easing],[fn])</li><li>opacity透明度必须写,取值0~1之间。</li><li>speed:三种预定速度之一的字符串(“slow”,”normal”,”fast”)或是表示动画时长的毫秒数值</li><li>easing:用于指定切换效果,默认是”swing”</li><li>fn:回调函数,在动画完成时执行的函数,每个元素执行一次。</li></ul></li></ul><h5 id="自定义动画"><a href="#自定义动画" class="headerlink" title="自定义动画"></a>自定义动画</h5><ul><li>animate(params,[speed],[easing],[fn])</li><li>参数<ul><li>params:想要更改的样式属性,以对象形式传递,必须写。属性名可以不用带引号,如果是复合属性则需要采取驼峰命名法</li><li>speed:三种预定速度之一的字符串(“slow”,”normal”,”fast”)或是表示动画时长的毫秒数值</li><li>easing:用于指定切换效果,默认是”swing”</li><li>fn:回调函数,在动画完成时执行的函数,每个元素执行一次。</li></ul></li></ul><h5 id="事件切换"><a href="#事件切换" class="headerlink" title="事件切换"></a>事件切换</h5><ul><li>hover([over],out);<ul><li>over:鼠标移到元素上要触发的函数(相当于mouseenter)</li><li>out:鼠标移出元素要触发的函数(相当于mouseleave)</li></ul></li></ul><h5 id="动画队列以及停止排队的方法"><a href="#动画队列以及停止排队的方法" class="headerlink" title="动画队列以及停止排队的方法"></a>动画队列以及停止排队的方法</h5><ul><li>动画或效果队列:动画或者效果一旦触发就会执行,如果多次触发,就造成多个动画或者效果排队执行。</li><li>停止排队<ul><li>stop()</li><li>stop()方法用于停止动画或效果</li><li>注意:stop()写到动画或者效果的前面,相当于停止结束上一次的动画。</li></ul></li></ul><h3 id="jQuery属性操作"><a href="#jQuery属性操作" class="headerlink" title="jQuery属性操作"></a>jQuery属性操作</h3><h5 id="设置或获取元素固有属性值prop"><a href="#设置或获取元素固有属性值prop" class="headerlink" title="设置或获取元素固有属性值prop()"></a>设置或获取元素固有属性值prop()</h5><p>所谓元素固有属性就是元素本身自带的属性,比如<a>元素中的href</p><ul><li>获取属性语法:prop(“属性”)</li><li>设置属性语法:prop(“属性”,”属性值”)</li></ul><h5 id="设置或获取元素自定义属性值attr"><a href="#设置或获取元素自定义属性值attr" class="headerlink" title="设置或获取元素自定义属性值attr()"></a>设置或获取元素自定义属性值attr()</h5><p>用户自己给元素添加的属性</p><ul><li>获取属性语法:attr(“属性”) //类似原生getAttribute()</li><li>设置属性语法:attr(“属性”,”属性值”)</li></ul><h3 id="jQuery内容文本值"><a href="#jQuery内容文本值" class="headerlink" title="jQuery内容文本值"></a>jQuery内容文本值</h3><p>主要针对元素的内容还有表单的值操作</p><h5 id="普通元素内容html-(相当于inner-HTML)"><a href="#普通元素内容html-(相当于inner-HTML)" class="headerlink" title="普通元素内容html()(相当于inner HTML)"></a>普通元素内容html()(相当于inner HTML)</h5><p>html()—->获取元素的内容</p><p>html(“内容”)—->设置元素的内容</p><h5 id="普通元素文本内容text-(相当于inner-Text)"><a href="#普通元素文本内容text-(相当于inner-Text)" class="headerlink" title="普通元素文本内容text()(相当于inner Text)"></a>普通元素文本内容text()(相当于inner Text)</h5><p>text()—->获取元素的文本内容</p><p>text(“内容”)—->设置元素的文本内容</p><h5 id="表单的值val-(相当于原生value)"><a href="#表单的值val-(相当于原生value)" class="headerlink" title="表单的值val()(相当于原生value)"></a>表单的值val()(相当于原生value)</h5><p>val()—->获取表单的值</p><p>val(“内容”)—->设置表单的值</p><h3 id="jQuery元素操作"><a href="#jQuery元素操作" class="headerlink" title="jQuery元素操作"></a>jQuery元素操作</h3><p>主要是遍历、创建、添加、删除元素操作。</p><h5 id="遍历元素"><a href="#遍历元素" class="headerlink" title="遍历元素"></a>遍历元素</h5><p>jQuery隐式迭代是对同一类元素做了同样的操作。如果想要给同一类元素做不同操作,就要用到遍历。</p><ul><li>$(“div”).each(function(index,domEle){xxx;})<ul><li>each()方法遍历匹配的每一个元素。主要用DOM处理。</li><li>里面的回调函数有两个参数:index是每一个元素的索引号;domEle是每一个DOM元素对象,不是jQuery对象</li><li>所以要想使用jQuery方法,需要给这个dom元素转换为jQuery对象$(domEle)</li></ul></li></ul><h5 id="创建元素"><a href="#创建元素" class="headerlink" title="创建元素"></a>创建元素</h5><ul><li>$(“<li></li>“)</li><li>动态创建了一个<li></li></ul><h5 id="添加元素"><a href="#添加元素" class="headerlink" title="添加元素"></a>添加元素</h5><ul><li>内部添加<ul><li>element.appent(“内容”) 把内容放入匹配元素后面,类似原生appendChild</li></ul></li><li>外部添加<ul><li>element.after(“内容”)</li><li>element.before(“内容”)</li></ul></li></ul><h5 id="删除元素"><a href="#删除元素" class="headerlink" title="删除元素"></a>删除元素</h5><ul><li>element.remove() //删除匹配的元素</li><li>element.empty() //删除匹配的元素集合中所有的子节点</li><li>element.html(“”) //清空匹配的元素内容</li></ul><h3 id="jQuery尺寸、位置操作"><a href="#jQuery尺寸、位置操作" class="headerlink" title="jQuery尺寸、位置操作"></a>jQuery尺寸、位置操作</h3><h5 id="jQuery尺寸"><a href="#jQuery尺寸" class="headerlink" title="jQuery尺寸"></a>jQuery尺寸</h5><ul><li><p>width()/height()取得匹配元素宽度和高度值 只算width/height</p></li><li><p>innerWidth()/innerHeight()取得匹配元素宽度和高度值 包含padding</p></li><li><p>outerWidth()/outerHeight()取得匹配元素宽度和高度值 包含padding、border</p></li><li><p>outerWidth(true)/outerHeight(true)取得匹配元素宽度和高度值 包含padding、border、margin</p></li><li><p>以上参数为空,则是获取相应值,返回的是数字型</p></li><li><p>如果参数为数字,则是修改相应值</p></li><li><p>参数可以不必写单位</p></li></ul><h5 id="jQuery位置"><a href="#jQuery位置" class="headerlink" title="jQuery位置"></a>jQuery位置</h5><p>位置主要有三个:offset()、position()、scrollTop()/scrollLeft()</p><ul><li>offset()设置或获取元素偏移<ul><li>此方法设置或返回被选元素相当于文档的偏移坐标,跟父级没有关系。</li><li>该方法有两个属性left、top。</li><li>可以设置元素的偏移:offset({top:10,left:10})</li></ul></li><li>position()获取元素偏移<ul><li>position()方法用于被选元素相对于带有定位的父级偏移坐标,如果父级都没有定位,则以文档为标准</li></ul></li><li>scrollTop()/scrollLeft()设置或获取元素被卷去的头部和左侧<ul><li>scrollTop()方法设置或返回被选元素被卷去的头部。</li></ul></li></ul><h3 id="jQuery事件"><a href="#jQuery事件" class="headerlink" title="jQuery事件"></a>jQuery事件</h3><h5 id="单个事件注册"><a href="#单个事件注册" class="headerlink" title="单个事件注册"></a>单个事件注册</h5><ul><li>语法:element.事件(function(){})</li></ul><h5 id="单个事件处理"><a href="#单个事件处理" class="headerlink" title="单个事件处理"></a>单个事件处理</h5><p>事件处理on()绑定事件—->on()方法在匹配元素上绑定一个或多个事件的事件处理函数。</p><p>element.on(events,[selector],fn)</p><ul><li><p>events:一个或多个用空格分隔的事件类型,如”click”或”keydown”</p></li><li><p>selector:元素的子元素选择器。</p></li><li><p>fn:回调函数,即绑定在元素上的侦听函数</p></li><li><p>优势</p><ul><li>一:可以绑定多个事件,多个处理事件处理程序。$(“div”).on({mouseover:function(){},mouseout:function(){}})</li><li>二:可以事件委派操作。事件委派的定义就是,把原来加给子元素身上的事件绑定在父元素身上,就是把事件委派给父元素。</li><li>三:动态创建的元素,click()没有办法绑定事件,on()可以给动态生成的元素绑定事件</li></ul></li></ul><p>off()方法可以移出通过on()方法添加的事件处理程序。</p><p>如果有的事件只想触发一次,可以使用one()来绑定事件</p><h5 id="自动触发事件trigger"><a href="#自动触发事件trigger" class="headerlink" title="自动触发事件trigger()"></a>自动触发事件trigger()</h5><p>有些事件希望自动触发,比如轮播图自动播放功能跟点击右侧按钮一致。可以利用定时器自动触发右侧按钮点击事件,不必鼠标点击触发</p><p>element.trigger(“type”)</p><h3 id="jQuery事件对象"><a href="#jQuery事件对象" class="headerlink" title="jQuery事件对象"></a>jQuery事件对象</h3><p>事件被触发,就会有事件对象的产生。</p><p>阻止默认行为:event.preventDefault() 或者 return false</p><p>阻止冒泡:event.stopPropagation()</p><h3 id="jQuery其他方法"><a href="#jQuery其他方法" class="headerlink" title="jQuery其他方法"></a>jQuery其他方法</h3><h5 id="jQuery对象拷贝"><a href="#jQuery对象拷贝" class="headerlink" title="jQuery对象拷贝"></a>jQuery对象拷贝</h5><p>如果想要把某个对象拷贝给另一个对象使用,此时可以使用$.extend()方法</p><p>$extend([deep],target,object1,[objectn])</p><ul><li>deep:如果设为true为深拷贝,默认为false浅拷贝</li><li>target:要拷贝的目标对象</li><li>object1:待拷贝到的第一个对象</li><li>objectn:待拷贝到的第N个对象</li><li>浅拷贝是把拷贝的对象复杂数据类型中的地址拷贝给目标对象,修改目标对象会影响被拷贝对象。</li></ul><h5 id="jQuery多库共存"><a href="#jQuery多库共存" class="headerlink" title="jQuery多库共存"></a>jQuery多库共存</h5><ul><li><p>问题概述:jQuery使用$作为标识符,随着jQuery的流行,其他js库也会用其作为标识符,这样一起使用会起冲突。</p></li><li><p>客观需求:需要一个解决方案,让jQuery和其他的js库不存在冲突,可以同时存在,这就叫做多库共存。</p></li><li><p>jQuery解决方案:</p><ul><li>把里面的$符号统一改为jQuery,例如jQuery(“div”)</li><li>jQuery变量规定新的名称:$.noConflict()</li></ul></li></ul><h5 id="jQuery插件"><a href="#jQuery插件" class="headerlink" title="jQuery插件"></a>jQuery插件</h5><p>jQuery功能比较有限,想要更复杂的特技效果,可以借助jQuery插件完成。</p><p>注意这些插件也是依赖jQuery来完成的,所以必须要先引入jQuery文件,因此页被称为jQuery插件。</p><ul><li><p>常用网站:</p><ul><li><a href="https://www.jq22.com/">jQuery插件库</a></li><li><a href="https://www.htmleaf.com/">jQuery之家</a></li></ul></li><li><p>jQuery插件使用步骤</p><ul><li>引入相关文件。(jQuery文件和插件文件)</li><li>复制相关html、css、js(调用插件)</li></ul></li><li><p>插件演示</p><ul><li>瀑布流</li><li>懒加载:页面滑动到可视区域,再加载图片。我们使用jQuery插件库EazyLazyLoad。注意,此时的js引入文件和js调用必须写到DOM元素(图片)后面 </li><li>全屏滚动(明日方舟)(fullpage.js):github:<a href="https://github.com/alvarotrigo/fullPage.js">https://github.com/alvarotrigo/fullPage.js</a></li></ul></li><li><p>bootstrap JS插件:bootstrap插件也是依赖于jQuery开发的,因此里面的js插件使用,也必须引入jQuery文件。<a href="https://v3.bootcss.com">Bootstrap中文文档</a></p></li></ul>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
<tag>迁移</tag>
</tags>
</entry>
<entry>
<title>HTML</title>
<link href="/2023/06/24/HTML/"/>
<url>/2023/06/24/HTML/</url>
<content type="html"><![CDATA[<h1 id="标签"><a href="#标签" class="headerlink" title="标签"></a>标签</h1><ul><li>单标签</li><li>双标签</li></ul><h1 id="文字样式变形"><a href="#文字样式变形" class="headerlink" title="文字样式变形"></a>文字样式变形</h1><ul><li>strong <strong>加粗</strong></li><li>em <em>倾斜</em></li><li>del <del>删除线</del></li><li>ins 下划线</li><li>p> </p>换行</li></ul><h1 id="插入图片"><a href="#插入图片" class="headerlink" title="插入图片"></a>插入图片</h1><ul><li><pre><code class="hljs">img src="链接" alt="若显示失败输入的字符" width="左右大小" height="高低" title="鼠标放在图片上显示的字"/>(src必须)</code></pre></li></ul><h1 id="路径"><a href="#路径" class="headerlink" title="路径"></a>路径</h1><ul><li>相对路径<ul><li>下一条路径img src=”本路径中含有图片的文件夹/图片名称(包含后缀)”/></li><li>上一条路径img src=”../图片名称(包含后缀)”/></li></ul></li><li>绝对路径</li><li>此电脑中的文件img src=”C.........\图片名称(包含后缀)”>(注意相对和绝对的斜杠不一样)</li><li>完整的网络地址img src=”直接将网址输入”/></li></ul><h1 id="链接标签"><a href="#链接标签" class="headerlink" title="链接标签"></a>链接标签</h1><table><thead><tr><th>链接类型</th><th>说明</th><th>标签</th></tr></thead><tbody><tr><td>外部链接</td><td>target中为下划线self就是关本界面开新界面,下划线blank就是直接开一个新界面</td><td>a href=”直接将网址输入” target=”…”>显示出的字符</a></td></tr><tr><td>内部链接</td><td>即自己多个网页之间转跳的链接</td><td>a href=”直接输入html的名字(加后缀”>显示出的字符</a></td></tr><tr><td>空链接</td><td>常用于页面尚未完善时的框架</td><td>a href=”#”>显示出的字符</a></td></tr><tr><td>下载链接</td><td>当href指向一个zip或exe文件时,点击链接会直接下载,如果需要不点击,可以使用a.download来实现</td><td></td></tr><tr><td>网页元素链接</td><td>文本、表格、音频、视频都能进行超链接</td><td>a href=”…”> img src=”…”/></a></td></tr><tr><td>锚点链接</td><td>可以直接转跳到页面内上下文 首先要对跳的地方进行设置 然后进行设置超链接</td><td>h1 id=”…”>显示出的字符</h1> a href=”#…”>显示出的字符</a></td></tr><tr><td>注释</td><td>ctrl+/</td><td>!–输入想要输入的注释–></td></tr></tbody></table><table><thead><tr><th>特殊字符</th><th>描述</th><th>字符的代码(前面都加&)</th></tr></thead><tbody><tr><td></td><td>空格</td><td>nbsp;</td></tr><tr><td><</td><td>小于号</td><td>lt;</td></tr><tr><td>></td><td>大于号</td><td>gt;</td></tr><tr><td>&</td><td>和号</td><td>amp;</td></tr><tr><td>¥</td><td>人民币号</td><td>yen;</td></tr><tr><td>©</td><td>版权</td><td>copy;</td></tr><tr><td></td><td>注册商标</td><td>reg;</td></tr><tr><td>°</td><td>摄氏度</td><td>deg;</td></tr><tr><td>+-</td><td>正负号</td><td>plusmn;</td></tr><tr><td>×</td><td>乘号</td><td>times;</td></tr><tr><td>➗</td><td>除号</td><td>divide;</td></tr><tr><td>^2^</td><td>二次方</td><td>sup2;</td></tr><tr><td>^3^</td><td>三次方</td><td>sup3;</td></tr></tbody></table><h1 id="表格标签"><a href="#表格标签" class="headerlink" title="表格标签"></a>表格标签</h1><ul><li><p>表格的基本语法 </p><ul><li>table></table>是用于定义表格的标签。</li><li>tr></tr>标签用于定义表格中的行,必须嵌套在table标签中。</li><li>td></td>标签用于定义表格中的单元格,必须嵌套在tr标签中。</li><li>th></th>标签用于制作表头,必须嵌套在tr标签中。</li><li>thead></thead>标签用于制作表头区域,必须嵌套在table标签中。</li><li>tbody></tbody>用于制作表格主体部分,必须嵌套在table标签中。</li></ul></li><li><p>表格属性(都要写到table标签中,CSS还会学,小小掌握即可)</p><ul><li>align=”…”表示表格与文字的对齐方式</li><li>border=”…”表示边框厚度</li><li>cellpadding=”…” 规定文字与表格之间的空白,默认为一像素</li><li>cellspacing=”…”规定单元格之间的空隙,默认为2像素</li><li>width、height=”…” 规定单元格的宽度、高度</li></ul></li><li><p>合并单元格(必须在第一行和第一列添加标签 且记得删除多余的单元格,必须用于td标签中)</p><ul><li><p>rowspan=”要合并的行”</p></li><li><p>colspan=”要合并的列”</p></li></ul></li></ul><h1 id="列表标签"><a href="#列表标签" class="headerlink" title="列表标签"></a>列表标签</h1><ul><li>无序列表(重点)–>整齐简单不要求顺序用无需列表<ul><li>ul></ul>表示无序列表,一般以项目符号呈现列表项(ul标签中只能存放li标签)</li><li>li></li>定义列表项 可以存放任何元素 相当于一个容器</li></ul></li><li>有序列表<ul><li>ol></ol>表示有序列表 同样使用li标签</li></ul></li><li>自定义列表(重点)–>当有很多小分支对一个大分支进行说明时使用自定义列表<ul><li>dl></dl>用于描述自定义列表(dl标签中只能存在dt和dd标签)</li><li>dt></dt>用于描述名词</li><li>dd></dd>用于对名词进行解释</li></ul></li></ul><h1 id="表单标签"><a href="#表单标签" class="headerlink" title="表单标签"></a>表单标签</h1><h5 id="表单域"><a href="#表单域" class="headerlink" title="表单域"></a>表单域</h5><ul><li>form action=”url地址” method=”提交方式” name=”表单域名称”></form><ul><li>action属性用于指定接收并处理表单数据的服务器程序的url地址 <strong>还没学完后面会扩展</strong></li><li>method属性用于设置表单数据的提交方式,其取值为get或post</li><li>name属性用于指定表单的名称,以区分同一个页面中的多个表单域</li></ul></li></ul><h5 id="表单控件(表单元素)"><a href="#表单控件(表单元素)" class="headerlink" title="表单控件(表单元素)"></a>表单控件(表单元素)</h5><ul><li><p>input type=”属性值” name=”名称” value=”用户自定义” checked=”checked” maxlength=”一个正整数”>输入表单元素</p><ul><li><p>type的属性值:</p><table><thead><tr><th>属性值</th><th>作用</th></tr></thead><tbody><tr><td>button</td><td>定义可点击按钮(多数情况下用于通过javascript启动脚本)</td></tr><tr><td>checkbox</td><td>定义复选框(与radio相对)</td></tr><tr><td>file</td><td>定义输入字段和浏览按钮,供文件上传</td></tr><tr><td>hidden</td><td>定义隐藏的输入字段</td></tr><tr><td>image</td><td>定义图像形式的提交按钮</td></tr><tr><td>password</td><td>定义密码字段,该字段中的字符被掩码</td></tr><tr><td>radio</td><td>定义单选按钮(与checkbox相对,多选一必须有相同name)</td></tr><tr><td>reset</td><td>定义重置按钮,重置按钮会清除表单中的所有数据</td></tr><tr><td>submit</td><td>定义提交按钮,提交按钮会把表单数据发送到服务器</td></tr><tr><td>text</td><td>定义单行的输入字段,用户可在其中输入文本,默认宽度为20个字符</td></tr></tbody></table></li><li><p>name属性:定义input元素的名称</p></li><li><p>value属性:规定input元素的值</p></li><li><p>checked属性:规定此input元素首次加载时应当被选中 (用于单选和多选按钮 页面一打开就被选中就加这个属性)</p></li><li><p>maxlength属性:规定输入字段中的字符的最大长度</p></li></ul></li><li><p>label for=”名称”>要点击的字符或图片</label>标签:用于绑定一个表单元素,当点击label标签内的文本时,浏览器就会自动将焦点(光标)转到或者选择对应的表单元素上,增加用户体验。</p><ul><li>id属性:与label标签搭配使用 放在input里面</li></ul></li><li><p>select></select>下拉表单元素用于多个选项选一个简洁页面 </p><ul><li>option>选项</option>只能嵌套在select元素中 (在option标签中定义selected=”selected”,当前项为默认选项)</li></ul></li><li><p>textarea></textarea>文本域元素用于键入大量内容时</p></li></ul><h5 id="提示信息"><a href="#提示信息" class="headerlink" title="提示信息"></a>提示信息</h5><ul><li>记得添加增加用户体验的提示信息</li></ul><h1 id="emmet语法"><a href="#emmet语法" class="headerlink" title="emmet语法"></a>emmet语法</h1><ul><li>标签*n+tab可以快速生成n个标签</li><li>父子级关系输入标签一>标签二+tab可以快速生成父子级标签</li><li>兄弟级关系输入标签1+标签二+tab可以快速生成兄弟级标签</li><li>输入标签.类名可以快速生成有类名的标签(类名后面加$*n可以生成很多不同的类名)</li></ul><h1 id="HTML5新特性"><a href="#HTML5新特性" class="headerlink" title="HTML5新特性"></a>HTML5新特性</h1><p>新特性虽然强大 但是都有兼容问题 基本是IE9+以上的版本才支持,如果不考虑兼容性问题,可以大量使用这些新特性</p><h3 id="HTML5新增的语义化标签"><a href="#HTML5新增的语义化标签" class="headerlink" title="HTML5新增的语义化标签"></a>HTML5新增的语义化标签</h3><p>参见CSS规范使用标签 打*的是语义化</p><h3 id="HTML5新增的多媒体文件"><a href="#HTML5新增的多媒体文件" class="headerlink" title="HTML5新增的多媒体文件"></a>HTML5新增的多媒体文件</h3><h5 id="视频"><a href="#视频" class="headerlink" title="视频"></a>视频</h5><ul><li><p>尽量放mp4文件</p></li><li><p>样式为video src=””是一个双标签</p></li><li><p>常见属性为autoplay(自动播放)/controls(播放控件显示)/width/height/loop(循环播放)/preload(是否预加载 属性值为auto/none)/src/poster(等待加载的画面图片)/muted(静音播放)</p></li></ul><h5 id="音频"><a href="#音频" class="headerlink" title="音频"></a>音频</h5><ul><li>尽量放mp3文件</li><li>样式基本同视频 属性只有autoplay/controls/loop/src</li></ul><h3 id="HTML新增的表单类型"><a href="#HTML新增的表单类型" class="headerlink" title="HTML新增的表单类型"></a>HTML新增的表单类型</h3><ul><li><p>input type后面的属性值增加了很多 例如email/url/date/time/month/week/number/tel/search/color</p></li><li><p>新增了很多表单属性 </p><ul><li>required:required;表示该表单不能为空 </li><li>placeholder:提示文本; 表示表单的提示信息 </li><li>autofocus:autofocus;自动聚焦</li><li>autocomplete:on/off; 当用户在字段开始键入时,浏览器基于之前键入过的值,显示出字段中填写的选项</li><li>mutiple:mutiple; 可以多选文件提交</li></ul></li></ul>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
<tag>迁移</tag>
</tags>
</entry>
<entry>
<title>ES6</title>
<link href="/2023/06/24/ES6/"/>
<url>/2023/06/24/ES6/</url>
<content type="html"><![CDATA[<p>ES 是脚本语言的规范,而平时经常编写的 JS 是 ES 的一种体现,所以 ES 的新特性其实指的就是 JS 的新特性</p><h3 id="let"><a href="#let" class="headerlink" title="let"></a>let</h3><p>相当于局部变量</p><h3 id="const"><a href="#const" class="headerlink" title="const"></a>const</h3><p>常量,不可修改</p><h3 id="解构赋值"><a href="#解构赋值" class="headerlink" title="解构赋值"></a>解构赋值</h3><p>可以用 let [ …… ] = 数组名、let { ……. } = 对象名 ,这样的方式来快速取值</p><h3 id="模板字符串"><a href="#模板字符串" class="headerlink" title="模板字符串"></a>模板字符串</h3><p>通常情况下你str是没办法换行的,想要换行的话就要用”” + 这样 但是 ES6 中给到了``反引号 在反引号中可以随便换行 :laughing:</p><h3 id="对象的简便写法"><a href="#对象的简便写法" class="headerlink" title="对象的简便写法"></a>对象的简便写法</h3><p>如果对象的名字和值一样 就可以直接写一个</p><p>还有就是对象函数 可以省略function 直接写 名字(){} 这样</p><h3 id="箭头函数"><a href="#箭头函数" class="headerlink" title="箭头函数"></a>箭头函数</h3><p>函数声明 变成了</p><blockquote><p>let fn = (a,b) => {<br> return a+b;<br>} </p></blockquote><p>这样 省略了function</p><ul><li><p>this 是静态的 this 始终指向函数声明时所在作用域下的 this 的值</p></li><li><p>不能作为构造函数实名化对象</p></li><li><p>不能使用 arguments 变量</p></li><li><p>当形参只有一个的时候可以省略小括号,当代码体只有一个的时候可以省略花括号</p></li></ul><h3 id="函数参数的默认值设置"><a href="#函数参数的默认值设置" class="headerlink" title="函数参数的默认值设置"></a>函数参数的默认值设置</h3><p>在小括号里可以直接等于</p><blockquote><p>add = (c=1) =><br> return c;</p><p>结果是1 </p></blockquote><p>与结构赋值结合</p><blockquote><p>connect = (username,password) => {<br> console.log(username)<br>}<br>connect({<br> username:”111”<br> password:”222”<br>})</p></blockquote><p>可以这样使用</p><h3 id="rest参数"><a href="#rest参数" class="headerlink" title="rest参数"></a>rest参数</h3><p>ES6引用 rest 参数,用于获取函数的实参,用来代替 arguments </p><p>用法如下</p><blockquote><p>fn = (a,b,…args){<br> 输出…<br>}<br>fn(传值)</p></blockquote><p>值得一提的是 rest 函数必须要放到参数最后</p><h3 id="扩展运算符"><a href="#扩展运算符" class="headerlink" title="扩展运算符"></a>扩展运算符</h3><p>… 运算符可以把数组转化为逗号分割的参数序列</p><h3 id="symbol"><a href="#symbol" class="headerlink" title="symbol"></a>symbol</h3><p>symbol是一种类似于字符串的数据类型</p><h3 id="迭代器-interator"><a href="#迭代器-interator" class="headerlink" title="迭代器 interator"></a>迭代器 interator</h3><p>一个用于快速遍历数组的 新属性<br>next()会迭代调用数组元素,每次迭代一个,直到用完</p><blockquote><p>const num = [1,2,3,4];<br>let it = num[Symbol.interator] ();//调用必须<br>console.log(it.next());<br>console.log(it.next());<br>console.log(it.next());<br>console.log(it.next());// 这样就会快速生成四个对象 value 会遍历 对象中还有一个 done 值 如果被遍历完了 done 就会变成true</p></blockquote><h3 id="生成器"><a href="#生成器" class="headerlink" title="生成器"></a>生成器</h3><p>其实就是一个特殊的函数,异步编程 纯回调函数</p><blockquote><p>function * gen(){<br> part1;<br> yield ‘sign1’;<br> part2;<br> yield ‘sign2’;<br> part3;<br>}</p><p>let it = gen();<br>it.next();<br>it.next();<br>it.next();</p></blockquote><p>这样的话会逐渐执行part1,然后part2,然后part3</p><p>甚至可以用 yield 来传参,这里截取片段来展示</p><blockquote><p>let one = yield 111;<br>console.log(one);</p><p>…</p><p>it.next(‘AAA’) //这样就会输出AAA</p></blockquote><h3 id="Promise-比较重要-面试常问"><a href="#Promise-比较重要-面试常问" class="headerlink" title="Promise (比较重要 面试常问)"></a>Promise (比较重要 面试常问)</h3><p>Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果</p><p>使用Promise方案主要有以下好处</p><ul><li>可以很好的解决回调地狱的问题(避免了层层嵌套的回调函数</li><li>语法非常简洁。promise对象提供了简洁的API 使得控制异步操作更加容易</li></ul><p>==简单学学 如果想要了解还可以再看==</p><h3 id="Set"><a href="#Set" class="headerlink" title="Set"></a>Set</h3><p>ES6提供了新的数据结构 Set (集合)。类似于数组,但是成员的值都是唯一的,集合实现了 iterator 接口 所以可以使用扩展运算符和for of进行遍历</p><p>会自动去重 类似数学中的集合 </p><p>.size是个数 .add增加 .delete删除 .has检测 .clear清空</p><h3 id="Map"><a href="#Map" class="headerlink" title="Map"></a>Map</h3><p>ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了 iterator 接口,所以可以使用 扩展运算符 和 for of 进行遍历</p><h3 id="class"><a href="#class" class="headerlink" title="class"></a>class</h3><p>ES6 提供了更接近传统语言的写法,引入了 Class 这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上 ES6 的 class 可以看作 只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更面向对象编程的语法而已。</p><h3 id="对象方法扩展"><a href="#对象方法扩展" class="headerlink" title="对象方法扩展"></a>对象方法扩展</h3><ul><li><p>Object.assign(a,b) 对象的合并<br>该方法可以使两个对象合并 由后面的覆盖前面的 </p></li><li><p>Object.setPrototypeOf 设置原型对象 可以放到_proto_中去</p></li></ul><h3 id="模块化"><a href="#模块化" class="headerlink" title="模块化"></a>模块化</h3><p>模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小的文件组合起来</p><p>模块化的优势有以下几点:</p><ul><li>防止命名冲突</li><li>代码复用</li><li>高维护性</li></ul><h5 id="ES6模块化语法"><a href="#ES6模块化语法" class="headerlink" title="ES6模块化语法"></a>ES6模块化语法</h5><p>模块化语法主要由两个命令构成:export 和 import</p><ul><li>export 命令用于规范模块的对外接口</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><code class="hljs javascript"><span class="hljs-keyword">let</span> name = <span class="hljs-string">"name"</span>;<br><span class="hljs-keyword">let</span> <span class="hljs-title function_">teach</span> = (<span class="hljs-params"></span>) => {<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(name);<br>}<br><span class="hljs-keyword">export</span> {name,teach};<br></code></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></pre></td><td class="code"><pre><code class="hljs JS"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {<br><span class="hljs-attr">name</span>:<span class="hljs-string">"name"</span>;<br> <span class="hljs-attr">teach</span>:<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(name);<br>}<br>}<br></code></pre></td></tr></table></figure><ul><li>import 命令用于输入其他模块提供的功能</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs JS"><span class="hljs-keyword">import</span> {name,teach} <span class="hljs-keyword">from</span> <span class="hljs-string">"url"</span><br></code></pre></td></tr></table></figure><p>==ES7~ES11没学==</p>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
<tag>迁移</tag>
</tags>
</entry>
<entry>
<title>CSS</title>
<link href="/2023/06/24/CSS/"/>
<url>/2023/06/24/CSS/</url>
<content type="html"><![CDATA[<p>CSS参考手册:<a href="https://www.w3school.com.cn/cssref/index.asp">Ctrl+单击</a></p><h1 id="特殊样式制作方案"><a href="#特殊样式制作方案" class="headerlink" title="特殊样式制作方案"></a>特殊样式制作方案</h1><p>这里是一些CSS特殊样式设计的方案。</p><h2 id="CSS三角形绘制"><a href="#CSS三角形绘制" class="headerlink" title="CSS三角形绘制"></a>CSS三角形绘制</h2><ul><li><p>方案一🎯:<strong>使用边框实现三角形</strong>:</p><p>原理:设置一个高宽为0的div,然后设置border-方向即可。</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><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-selector-tag">div</span> {<br> <span class="hljs-attribute">border-top</span>: <span class="hljs-number">50px</span> solid yellowgreen;<br> <span class="hljs-attribute">border-bottom</span>: <span class="hljs-number">50px</span> solid deeppink;<br> <span class="hljs-attribute">border-left</span>: <span class="hljs-number">50px</span> solid bisque;<br> <span class="hljs-attribute">border-right</span>: <span class="hljs-number">50px</span> solid chocolate;<br>}<br></code></pre></td></tr></table></figure><p>优点:快捷简单。</p><p>缺点:只能实现45deg的三角形。</p></li><li><p>方案二🎯:<strong>使用背景渐变颜色实现三角形</strong></p><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><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><code class="hljs css"><span class="hljs-comment">/* 线性渐变 */</span><br><span class="hljs-selector-tag">div</span> {<br> <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;<br> <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;<br> <span class="hljs-attribute">background</span>: <span class="hljs-built_in">linear-gradient</span>(<span class="hljs-number">45deg</span>, deeppink, deeppink <span class="hljs-number">50%</span>, yellowgreen <span class="hljs-number">50%</span>, yellowgreen <span class="hljs-number">100%</span>);<br>}<br><br><span class="hljs-comment">/* 角向渐变 */</span><br><span class="hljs-selector-tag">div</span> {<br> <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;<br> <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;<br> <span class="hljs-attribute">background</span>: <span class="hljs-built_in">conic-gradient</span>(from <span class="hljs-number">90deg</span> at <span class="hljs-number">50%</span> <span class="hljs-number">0</span>, deeppink <span class="hljs-number">0</span>, deeppink <span class="hljs-number">45deg</span>, transparent <span class="hljs-number">45.1deg</span>);<br>}<br></code></pre></td></tr></table></figure><p>优点:可以多角度自由斜角。</p><p>缺点:三角形形态比较难以调试。</p></li><li><p>方案三🎯:<strong>使用盒子旋转实现三角形</strong></p><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><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><code class="hljs css"><span class="hljs-selector-class">.triangle</span> {<br> <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;<br> <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;<br> <span class="hljs-attribute">position</span>: relative;<br> <span class="hljs-attribute">overflow</span>: hidden;<br> <br> &<span class="hljs-selector-pseudo">::before</span> {<br> <span class="hljs-attribute">content</span>: <span class="hljs-string">""</span>;<br> <span class="hljs-attribute">position</span>: absolute;<br> <span class="hljs-attribute">top</span>: <span class="hljs-number">0</span>;<br> <span class="hljs-attribute">left</span>: <span class="hljs-number">0</span>;<br> <span class="hljs-attribute">right</span>: <span class="hljs-number">0</span>;<br> <span class="hljs-attribute">bottom</span>: <span class="hljs-number">0</span>;<br> <span class="hljs-attribute">background</span>: deeppink;<br> <span class="hljs-attribute">transform-origin</span>: left bottom;<br> <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">rotate</span>(<span class="hljs-number">45deg</span>);<br> }<br>}<br></code></pre></td></tr></table></figure><p>优点:直观、可塑性高。</p><p>缺点:盒子容易偏移。</p></li><li><p>方案四🎯:<strong>使用容器剪裁实现三角形</strong></p><p>原理:有一个css属性叫做clip-path,适用于创建一个只有元素部分区域可以显示的剪切区域。</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><code class="hljs css"><span class="hljs-selector-tag">div</span> {<br> <span class="hljs-attribute">background</span>: deeppink;<br> <span class="hljs-attribute">clip-path</span>: <span class="hljs-built_in">polygon</span>(<span class="hljs-number">0</span> <span class="hljs-number">0</span>, <span class="hljs-number">100%</span> <span class="hljs-number">0</span>, <span class="hljs-number">0</span> <span class="hljs-number">100%</span>, <span class="hljs-number">0</span> <span class="hljs-number">0</span>);<br>}<br></code></pre></td></tr></table></figure><p>优点:不只是三角形,能剪裁出任何想要的图形。</p><p>缺点:操作量大。</p></li><li><p>方案五🎯:<strong>使用icon实现三角形</strong></p><p>原理:直接使用字体中的icon。</p><p>优点:太快了,什么都不用想直接输入一个字符即可。</p><p>缺点:三角形不可调整,三角形可能随着不同字体变形。</p></li></ul><h2 id="缺角盒子实现"><a href="#缺角盒子实现" class="headerlink" title="缺角盒子实现"></a>缺角盒子实现</h2><ul><li><p>方案一:<strong>盒子遮挡实现</strong></p><p>原理:做两个同背景颜色的三角形进行遮挡。</p><p>优点:快速。</p><p>缺点:颜色死板,背景是图片则没办法。</p></li><li><p>方案二:<strong>使用背景渐变颜色实现三角形</strong></p><p>原理:同三角形绘制。</p><p>优点:不用定位。</p><p>缺点:同上方案。</p></li><li><p>方案三:<strong>使用盒子旋转实现缺角盒子</strong></p><p>原理:使用一个较长的div和元素溢出隐藏样式。</p><p>优点:可以设置缺角的边框。</p><p>缺点:调试麻烦。</p></li></ul><h2 id="计算器类型数码字体实现"><a href="#计算器类型数码字体实现" class="headerlink" title="计算器类型数码字体实现"></a>计算器类型数码字体实现</h2><ul><li><p>方案:<strong>直接去寻找对应字体</strong></p><p>原理:使用字体更改数字字体比自己手写js+css容易太多了。</p><figure class="highlight markdown"><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><code class="hljs markdown">1.可以在https://www.dafont.com/上找到喜欢的字体。<br>2.字体的文件一般都是以.tff为后缀,可以改成.eot或者.woff格式,兼容浏览器。<br>3.在style.css中使用@font-face配置,如<br>@font-face{font-family: 'digital';src:url('/public/DS-DIGIT.woff') format('woff')}<br>4.在需要使用的地方使用font-family属性。<br></code></pre></td></tr></table></figure><p>优点:快速有效。</p><p>缺点:字体寻找花费时间。</p></li></ul><h2 id="毛玻璃"><a href="#毛玻璃" class="headerlink" title="毛玻璃"></a>毛玻璃</h2><ul><li><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><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-attribute">width</span>: <span class="hljs-number">400px</span>;<br><span class="hljs-attribute">height</span>: auto;<br><span class="hljs-attribute">background</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, .<span class="hljs-number">7</span>);<br>webkit-backdrop-<span class="hljs-attribute">filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">10px</span>);<br>backdrop-<span class="hljs-attribute">filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">10px</span>);<br></code></pre></td></tr></table></figure></li></ul><h2 id="文字颜色渐变"><a href="#文字颜色渐变" class="headerlink" title="文字颜色渐变"></a>文字颜色渐变</h2><ul><li><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><code class="hljs css"><span class="hljs-attribute">background</span>: <span class="hljs-built_in">linear-gradient</span>(to right, #颜色, #颜色); <br>-webkit-<span class="hljs-attribute">background-clip</span>: text;<br>-webkit-text-fill-<span class="hljs-attribute">color</span>: transparent;<br></code></pre></td></tr></table></figure></li><li><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><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><code class="hljs css"><span class="hljs-attribute">background</span>: <span class="hljs-built_in">-webkit-linear-gradient</span>(<br> <span class="hljs-number">0deg</span>,<br> #颜色<span class="hljs-number">1</span>,<br> #颜色<span class="hljs-number">2</span> <span class="hljs-number">25%</span>,<br> #颜色<span class="hljs-number">3</span> <span class="hljs-number">50%</span>,<br> #颜色<span class="hljs-number">4</span> <span class="hljs-number">75%</span>,<br> #颜色<span class="hljs-number">1</span><br>);<br>-webkit-<span class="hljs-attribute">background-clip</span>: text;<br><span class="hljs-attribute">color</span>: transparent;<br></code></pre></td></tr></table></figure></li></ul><h2 id="自由图形制作"><a href="#自由图形制作" class="headerlink" title="自由图形制作"></a>自由图形制作</h2><ul><li>方案:使用<code>clip-path</code>属性,搭配figma或者其他工具效果更佳。</li></ul><h1 id="CSS规范"><a href="#CSS规范" class="headerlink" title="CSS规范"></a>CSS规范</h1><p><a href="https://developer.mozilla.org/zh-CN/docs/Learn/CSS/Building_blocks/Organizing">组织CSS</a></p><h2 id="基本样式"><a href="#基本样式" class="headerlink" title="基本样式"></a>基本样式</h2><p>CSS规则由两个主要的部分构成:选择器及一条或多条声明,属性和属性值以”键值对“的形式出现,属性和属性值之间用英文冒号来分割,多个”键值对“之间用英文分号进行区分。</p><h2 id="书写顺序"><a href="#书写顺序" class="headerlink" title="书写顺序"></a>书写顺序</h2><p>无论是原子类还是原始CSS写法,为了方便后期维护,也是为了让代码更加优雅。我们遵循下面书写顺序:</p><ul><li>位置属性(position, top, right, z-index, display, float等)</li><li>大小(width, height, padding, margin)</li><li>文字系列(font, line-height, letter-spacing, color- text-align等)</li><li>背景(background, border等)</li><li>其他(animation, transition等)</li></ul><blockquote><p>尽量缩写,例如margin-left、margin-right可以合并成一句margin-inline。</p></blockquote><p>CSS规范不是必须的,而是为了让你代码更具有条理性。如果按照一个已经由很多人使用过,诸多项目检测过的代码编写习惯去编写代码,那么团队中的其他成员有可能会更容易理解你的代码。</p><h2 id="注释跳转"><a href="#注释跳转" class="headerlink" title="注释跳转"></a>注释跳转</h2><p>写CSS的时候(特别是大项目)会发现CSS越堆越多。可以考虑使用以下方法划区:</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><code class="hljs css"><span class="hljs-comment">/* ☁️:part1 */</span><br>...<br><span class="hljs-comment">/* ☁️:part2 */</span><br>...<br></code></pre></td></tr></table></figure><p>好处是可以用<code>ctrl+F</code>搜索<code>☁️:</code>在多个块中快速跳转。</p><h2 id="OOCSS"><a href="#OOCSS" class="headerlink" title="OOCSS"></a>OOCSS</h2><p>OOCSS(面向对象的CSS)基本理念是将CSS分解成可复用的对象,然后在一个div中使用多个类。</p><h1 id="CSS选择器"><a href="#CSS选择器" class="headerlink" title="CSS选择器"></a>CSS选择器</h1><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><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><code class="hljs css"><span class="hljs-comment">/* 群组选择器:同时编写多个选择器 */</span><br><span class="hljs-selector-tag">p</span>,<span class="hljs-selector-class">.nav</span> {<span class="hljs-attribute">z-index</span>:<span class="hljs-number">1</span>}<br><br><span class="hljs-comment">/* 后代选择器:用于命中某一块选择器,注意后代选择器是可以跨盒子的,如</span><br><span class="hljs-comment"><h1></span><br><span class="hljs-comment"><p>样式生效</p></span><br><span class="hljs-comment"><div></span><br><span class="hljs-comment"><p>样式生效</p></span><br><span class="hljs-comment"></div></span><br><span class="hljs-comment"></h1></span><br><span class="hljs-comment">*/</span><br><span class="hljs-selector-tag">h1</span> <span class="hljs-selector-tag">p</span> {<span class="hljs-attribute">font-size</span>:<span class="hljs-number">1.5rem</span>}<br><br><span class="hljs-comment">/* 子代选择器:用于精确命中某一块选择器,后代选择器不可跨盒子,如</span><br><span class="hljs-comment"><h1></span><br><span class="hljs-comment"><p>样式生效</p></span><br><span class="hljs-comment"><div></span><br><span class="hljs-comment"><p>样式不生效</p></span><br><span class="hljs-comment"></div></span><br><span class="hljs-comment"></h1></span><br><span class="hljs-comment">*/</span><br><span class="hljs-selector-tag">h1</span>><span class="hljs-selector-tag">p</span> {<span class="hljs-attribute">font-size</span>:<span class="hljs-number">1.5rem</span>}<br><br><span class="hljs-comment">/* 兄弟选择器:同时选中所有兄弟盒子 */</span><br><span class="hljs-selector-tag">h1</span>~<span class="hljs-selector-tag">p</span> {<span class="hljs-attribute">font-size</span>:<span class="hljs-number">1.5rem</span>}<br><br><span class="hljs-comment">/* 相邻兄弟选择器:同时选中两个兄弟盒子,只选择h1后紧挨着的p标签 */</span><br><span class="hljs-selector-tag">h1</span>+<span class="hljs-selector-tag">p</span> {<span class="hljs-attribute">font-size</span>:<span class="hljs-number">1.5rem</span>}<br></code></pre></td></tr></table></figure><h2 id="选择器权重"><a href="#选择器权重" class="headerlink" title="选择器权重"></a>选择器权重</h2><table><thead><tr><th align="center">选择器</th><th align="center">优先级</th></tr></thead><tbody><tr><td align="center">!important</td><td align="center">最高优先级</td></tr><tr><td align="center">内联样式</td><td align="center">1,0,0,0</td></tr><tr><td align="center">id选择器</td><td align="center">0,1,0,0</td></tr><tr><td align="center">类、属性、伪类选择器</td><td align="center">0,0,1,0</td></tr><tr><td align="center">元素选择器</td><td align="center">0,0,0,1</td></tr><tr><td align="center">通配选择器</td><td align="center">0,0,0,0</td></tr><tr><td align="center">继承的样式</td><td align="center">最低优先级</td></tr></tbody></table><h2 id="标签选择器"><a href="#标签选择器" class="headerlink" title="标签选择器"></a>标签选择器</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-selector-tag">p</span> {<span class="hljs-attribute">z-index</span>:<span class="hljs-number">1</span>;}<br></code></pre></td></tr></table></figure><p>用HTML标签名称作为选择器,按标签名称分类,为页面中某一类标签指定。</p><h2 id="类选择器"><a href="#类选择器" class="headerlink" title="类选择器"></a>类选择器</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-selector-class">.nav</span> {<span class="hljs-attribute">z-index</span>:<span class="hljs-number">1</span>;}<br></code></pre></td></tr></table></figure><p>如果想要差异化选择不同的标签,单独选择一个或者某几个标签,可以使用类选择器。</p><blockquote><p>不能使用标签名作为类选择器的类名,可以使用中横线命名,不使用纯数字、中文、包括下划线(部分浏览器不兼容情况)进行命名。</p></blockquote><h2 id="ID选择器"><a href="#ID选择器" class="headerlink" title="ID选择器"></a>ID选择器</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-selector-id">#user</span> {<span class="hljs-attribute">z-index</span>:<span class="hljs-number">1</span>;}<br></code></pre></td></tr></table></figure><p>在HTML中只能调用一次,如果有调用一次后,别的标签不允许再次使用。(可以考虑与JS结合使用)</p><h2 id="通配选择器"><a href="#通配选择器" class="headerlink" title="通配选择器"></a>通配选择器</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css">* {<span class="hljs-attribute">z-index</span>:<span class="hljs-number">1</span>;}<br></code></pre></td></tr></table></figure><p>对所有的标签进行修改(可结合后代选择器使用)</p><h2 id="属性选择器"><a href="#属性选择器" class="headerlink" title="属性选择器"></a>属性选择器</h2><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><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><code class="hljs css"><span class="hljs-comment">/* 有该属性改变样式 */</span><br><span class="hljs-selector-tag">a</span><span class="hljs-selector-attr">[title]</span><span class="hljs-selector-attr">[lang]</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 属性值匹配zh改变样式 */</span><br><span class="hljs-selector-tag">a</span><span class="hljs-selector-attr">[lang=<span class="hljs-string">"zh"</span>]</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 属性值以en开头改变样式 */</span><br><span class="hljs-selector-tag">a</span><span class="hljs-selector-attr">[lang^=<span class="hljs-string">"en"</span>]</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 属性值以en开头改变样式 */</span><br><span class="hljs-selector-tag">a</span><span class="hljs-selector-attr">[lang^=<span class="hljs-string">"en"</span>]</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 属性值以en结尾改变样式 */</span><br><span class="hljs-selector-tag">a</span><span class="hljs-selector-attr">[class$=<span class="hljs-string">"en"</span>]</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 属性值有en改变样式 */</span><br><span class="hljs-selector-tag">a</span><span class="hljs-selector-attr">[class*=<span class="hljs-string">"en"</span>]</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 属性值存在完整en改变样式 */</span><br><span class="hljs-selector-tag">a</span><span class="hljs-selector-attr">[class~=<span class="hljs-string">"en"</span>]</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 属性值只有en或者以en-开头改变样式 */</span><br><span class="hljs-selector-tag">a</span><span class="hljs-selector-attr">[class|=<span class="hljs-string">"en"</span>]</span>{<span class="hljs-attribute">color</span>:black}<br></code></pre></td></tr></table></figure><h2 id="伪类选择器"><a href="#伪类选择器" class="headerlink" title="伪类选择器"></a>伪类选择器</h2><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><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></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-comment">/* 第一个子元素 */</span><br><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:first</span>-child{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 最后一个子元素 */</span><br><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:last-child</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 第n个子元素,括号可以填n、2n、2n+1 */</span><br><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:nth-child</span>(){<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 第一类子元素 */</span><br><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:first</span>-of-type{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/*最后一类子元素 */</span><br><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:last-of-type</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 第n类子元素 */</span><br><span class="hljs-selector-tag">li</span><span class="hljs-selector-pseudo">:nth-of-type</span>(){<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 未访问过的a标签 */</span><br><span class="hljs-selector-tag">a</span><span class="hljs-selector-pseudo">:link</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 访问过的a标签,只能改变链接颜色 */</span><br><span class="hljs-selector-tag">a</span><span class="hljs-selector-pseudo">:visited</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 鼠标移入 */</span><br><span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:hover</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 鼠标点击 */</span><br><span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:active</span>{<span class="hljs-attribute">color</span>:black}<br><br><span class="hljs-comment">/* 鼠标选定 */</span><br><span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:focus</span>{<span class="hljs-attribute">color</span>:black}<br></code></pre></td></tr></table></figure><h2 id="伪元素选择器"><a href="#伪元素选择器" class="headerlink" title="伪元素选择器"></a>伪元素选择器</h2><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></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-comment">/* 第一个字母 */</span><br><span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">::first-letter</span>{<span class="hljs-attribute">font-size</span>:<span class="hljs-number">32px</span>}<br><br><span class="hljs-comment">/* 第一行 */</span><br><span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">::first-line</span>{<span class="hljs-attribute">font-size</span>:<span class="hljs-number">32px</span>}<br><br><span class="hljs-comment">/* 选中的元素 */</span><br><span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">::selection</span>{<span class="hljs-attribute">font-size</span>:<span class="hljs-number">32px</span>}<br><br><span class="hljs-comment">/* 元素开始的位置前 */</span><br><span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">::before</span>{<span class="hljs-attribute">font-size</span>:<span class="hljs-number">32px</span>}<br><br><span class="hljs-comment">/* 元素开始的位置后 */</span><br><span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">::after</span>{<span class="hljs-attribute">font-size</span>:<span class="hljs-number">32px</span>}<br></code></pre></td></tr></table></figure><p>伪元素一般用于做盒子的遮罩。</p><h1 id="CSS引入方式"><a href="#CSS引入方式" class="headerlink" title="CSS引入方式"></a>CSS引入方式</h1><h2 id="行内样式表"><a href="#行内样式表" class="headerlink" title="行内样式表"></a>行内样式表</h2><p>在某个标签内写入style,优先级非常高。原子类同理。</p><h2 id="内部样式表"><a href="#内部样式表" class="headerlink" title="内部样式表"></a>内部样式表</h2><p>放在head的style 新手练习时使用的方式</p><h2 id="外部样式表"><a href="#外部样式表" class="headerlink" title="外部样式表"></a>外部样式表</h2><p>单独写一个CSS文件,再将此文件引入到HTML中。(使用方法为建一个CSS的文件,直接在里面写样式,但要在引用的HTML文件中加入link标签) </p><h1 id="CSS背景相关处理"><a href="#CSS背景相关处理" class="headerlink" title="CSS背景相关处理"></a>CSS背景相关处理</h1><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><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></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-comment">/* 复合写法 */</span><br><span class="hljs-attribute">background</span>::<background-clip> <background-color> <background-image> <background-origin> <background-position> <background-repeat> <background-size> <background-attachment><br><br><span class="hljs-comment">/* 设置背景延伸情况 */</span><br>background-clip: <span class="hljs-built_in">border-box</span>(延伸到边框外沿,在边框下方)/<span class="hljs-built_in">padding-box</span>(到内边距外沿)/<span class="hljs-built_in">content-box</span>(到内容外沿)/<span class="hljs-built_in">text</span>(剪影成文字);<br><br><span class="hljs-comment">/* 设置背景颜色 */</span><br><span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">value</span>(对应颜色的英文)/#<span class="hljs-built_in">xxxxxx</span>(对应颜色的十六进制码)/<span class="hljs-built_in">rgba</span>(x,x,x,x)(对应颜色的RGBA值)/<span class="hljs-built_in">hsla</span>(x,x,x,x)(对应颜色的HSLA值);<br><br><span class="hljs-comment">/* 设置背景图像 */</span><br><span class="hljs-attribute">background-image</span>: <span class="hljs-built_in">url</span>()(图片url,可以使用多个,靠前的z-index值大)/<span class="hljs-built_in">linear-gradient</span>()(特殊的image格式,颜色渐变)<br><br><span class="hljs-comment">/* 设置背景起始点 */</span><br>background-origin: <span class="hljs-built_in">border-box</span>(延伸到边框外沿,在边框下方)/<span class="hljs-built_in">padding-box</span>(到内边距外沿)/<span class="hljs-built_in">content-box</span>(到内容外沿)<br><br><span class="hljs-comment">/* 设置背景位置 */</span><br>background-position: X/Y X/Y.Client Y/X Y/X.Client (X/Y指关键字top/left/bottom/right/center X/Y.Client指对应偏移量)<br><br><span class="hljs-comment">/* 设置背景重复设置 */</span><br>background-repeat: <span class="hljs-built_in">repeat-x</span>(X轴平铺)/<span class="hljs-built_in">repeat-y</span>(Y轴平铺)/<span class="hljs-built_in">repeat</span>(重复平铺)/<span class="hljs-built_in">space</span>(尽可能重复,不会被剪裁)/<span class="hljs-built_in">round</span>(尽可能重复,允许图像改变尺寸)/<span class="hljs-built_in">no-repeat</span>(不重复)<br><br><span class="hljs-comment">/* 设置背景大小 */</span><br>background-size: <span class="hljs-built_in">value</span>(实际取值)/auto/<span class="hljs-built_in">cover</span>(缩放,尽可能覆盖)/<span class="hljs-built_in">contain</span>(缩放,尽可能完全装入)<br><br><span class="hljs-comment">/* 设置背景固定 */</span><br>background-attachment: <span class="hljs-built_in">fixed</span>(表示背景相对于视口固定)/<span class="hljs-built_in">local</span>(表示背景相对于元素的内容固定)/<span class="hljs-built_in">scroll</span>(表示背景相对于元素本身固定)<br></code></pre></td></tr></table></figure><blockquote><p><code>background-attachment</code> <code>scroll-padding</code> 这些属性一般用于视差滚动。</p></blockquote><p>对于背景图片我们一般使用background-size的cover和contain有时候都不是很符合我们的要求,现代化的CSS新属性<code>object-fit</code>和<code>aspect-ratio</code>解决这个问题。</p><p>这两个属性是对于img标签来说的:</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-attribute">object-fit</span>:<span class="hljs-built_in">cover</span>(覆盖整个元素)/<span class="hljs-built_in">scale-down</span>(保持原来的大小)<br>aspect-ratio: <span class="hljs-built_in">value</span>(屏幕的长宽比)<br></code></pre></td></tr></table></figure><h1 id="CSS的三大特性"><a href="#CSS的三大特性" class="headerlink" title="CSS的三大特性"></a>CSS的三大特性</h1><h2 id="层叠性"><a href="#层叠性" class="headerlink" title="层叠性"></a>层叠性</h2><ul><li><p>相同选择器给设置相同的样式,此时一个样式就会覆盖另一个冲突的样式。</p></li><li><p>样式冲突,遵循的是就近原则,哪个样式离结构近,就执行哪个样式。</p></li><li><p>样式不冲突,不层叠。</p></li></ul><h2 id="继承性"><a href="#继承性" class="headerlink" title="继承性"></a>继承性</h2><ul><li><p>子标签会继承父标签中的某些样式。(恰当使用可以降低CSS的复杂性)</p></li><li><p>通常继承:text font line color这些属性</p></li><li><p>特殊继承:font: 12px/24px;表示行高为24px,但可以写成font:12px/1.5;表示行高为当前字体的1.5倍,子代继承同样适用1.5倍。</p></li></ul><h2 id="优先级"><a href="#优先级" class="headerlink" title="优先级"></a>优先级</h2><ul><li><p>当同一个元素指定多个选择器,就会有优先级的产生</p></li><li><p>选择器相同,则执行层叠性</p></li><li><p>优先级为:!important>行内样式(直接在标签里面写style)>id>类>伪类=标签=属性选择>继承>通配符;</p></li><li><p>复合选择器有权重叠加的问题,如子元素选择器就会相当于两个标签选择器的叠加。</p></li></ul><h1 id="网页布局"><a href="#网页布局" class="headerlink" title="网页布局"></a>网页布局</h1><p><a href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/Layout_cookbook">CSS 布局手册</a></p><h2 id="常见网页布局"><a href="#常见网页布局" class="headerlink" title="常见网页布局"></a>常见网页布局</h2><p>常见布局有 流式布局/网格布局/弹性布局.</p><blockquote><p>流式布局中 行/块/行内块级元素的区别:</p><p>行级元素可以与其他元素保持在同一行,不可以自动换行,但是不能设置他的宽高(例如a\span\strong\u\em\i\sub\sup);</p><p>块级元素不可以和其他元素保持在同一行(独占一行),可以自动换行,可以设置宽高(例如div\p\h1~6\ui\li);</p><p>行内块元素可以与其他元素保持在一行,还能设置宽高(例如textarea\input\img\button)</p></blockquote><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><code class="hljs css"><span class="hljs-comment">/* 关键值可以被分为六个种类 */</span><br><span class="hljs-comment">/* 外部表现,指这个盒子和这个盒子之外的元素的布局情况 */</span><br><span class="hljs-attribute">display</span>: <span class="hljs-built_in">block</span>(该元素之前和之后产生换行)/<span class="hljs-built_in">inline</span>(该元素之前和之后不产生换行)<br><br><span class="hljs-comment">/* 内部表现,指这个盒子内的元素布局情况 */</span><br>display: <span class="hljs-built_in">flow</span>(使用流式布局)/<span class="hljs-built_in">flow-root</span>(生成一个块级元素盒,会建立一个新的区块格式化上下文[<span class="hljs-number">1</span>])/<span class="hljs-built_in">table</span>(类似于table标签)/<span class="hljs-built_in">flex</span>(使用弹性布局)/<span class="hljs-built_in">grid</span>(使用网格布局)/<span class="hljs-built_in">ruby</span>(同ruby标签,用于注音)<br><br></code></pre></td></tr></table></figure><blockquote><p>[1]:<strong>区块格式化上下文</strong>(Block Formatting Context,BFC),是为了解决外边距折叠(区块上下外边距折叠为单个边距,取上下两个的最大值)、浮动元素覆盖、高度塌陷(子元素为浮动且高于父元素就会撑出去)而出现的,触发BFC的方式有浮动元素、绝对定位、overflow不为visible、display为flow-root等。</p></blockquote><h3 id="盒子模型"><a href="#盒子模型" class="headerlink" title="盒子模型"></a>盒子模型</h3><ul><li><p>所谓盒子模型:就是将HTML页面中的布局元素看作是一个矩形的盒子,也就是一个盛装内容的容器</p></li><li><p>CSS盒子模型本质上是一个盒子,封装周围的HTML元素,它包括:边框、外边距、内边距和实际内容</p></li><li><p>盒子模型的组成 每个元素都可以只设置上下左右 在元素后加-top/bottom/left/right即可</p><ul><li><p>border边框 可以使用复合写法 边框会影响盒子实际大小 测量要减去边框宽度</p><ul><li>border-width设置边框粗细</li><li>border-style设置边框样式 solid实线边框 dashed虚线边框 dotted点线边框 outset3D边框</li><li>border-color设置边框颜色</li><li>border-collapse用于合并相邻的边框</li></ul></li><li><p>content内容</p></li><li><p>padding内边距(内边距影响盒子的大小,当有宽度和高度属性时使用padding会撑大盒子,解决方法用宽度、高度减去padding*2 )(当高、宽未指定时padding不再影响) </p><ul><li>改变盒子边框和盒子内容距离</li><li>可单写也可上下左右一起</li><li>值个数为1一圈,值个数为2上下 左右,值个数为3上 左右 下,值个数为4顺时针</li></ul></li><li><p>margin外边距</p><ul><li><p>改变盒子与盒子之间的距离</p></li><li><p>输入方式和padding基本一样 </p></li><li><p>常见应用:块级盒子居中对齐 条件:有宽度、左右外边距写为auto;行内、行内块元素水平居中给其父级元素添加text-align:center;即可。</p></li><li><p><a href="https://blog.csdn.net/weixin_43334673/article/details/107177421">嵌套块元素塌陷</a>:父元素和子元素的外边距会合并 解决方案:为父元素添加overflow:hidden或定义上内边距或定义上边框</p></li></ul></li></ul></li><li><p>CSS第一行代码就是清除内外边距即*{padding:0;margin:0;}且行内元素尽量只设置左右边距(因为上下不起作用)。</p></li></ul><h5 id="圆角边框"><a href="#圆角边框" class="headerlink" title="圆角边框"></a>圆角边框</h5><ul><li><p>样式:border-radius:…;</p></li><li><p>radius意为半径后面输入的值越大盒子越圆;</p></li><li><p>可以输入4个值表示四个角</p></li></ul><h5 id="盒子阴影"><a href="#盒子阴影" class="headerlink" title="盒子阴影"></a>盒子阴影</h5><ul><li><p>样式为 box-shadow:…; 盒子的阴影不占空间。</p></li><li><p>h-shadow 表示水平位置的阴影</p></li><li><p>v-shadow 表示竖直方向的阴影</p></li><li><p>blur 表示阴影的模糊距离</p></li><li><p>spread 表示阴影的尺寸</p></li><li><p>color 表示阴影的颜色</p></li><li><p>inset 改为内部阴影</p></li></ul><h5 id="文字阴影"><a href="#文字阴影" class="headerlink" title="文字阴影"></a>文字阴影</h5><ul><li>样式为 text-shadow:…;</li><li>属性值为盒子阴影的前三个和color</li></ul><h3 id="浮动"><a href="#浮动" class="headerlink" title="浮动"></a>浮动</h3><ul><li>页面由标准流(普通流/文档流)、浮动、定位构成。</li><li>为什么需要浮动?1.将多个块级盒子在一行显示且不留空隙。2.实现两个盒子的左右对其。</li><li>网页布局第一准则:多个块级元素纵向排列找标准流,多个块级元素横向排列找浮动。</li><li>样式为 float:属性值; 属性值可以为left和right和none float是用于创建浮动框的,将其移动到一边,直到左边缘或右边缘触及块或者另一个浮动框的边缘。</li><li>浮动元素经常和标准流父级搭配使用 先用标准流的父元素排列上下位置,之后内部子元素采取浮动排列左右位置</li></ul><h5 id="浮动特性"><a href="#浮动特性" class="headerlink" title="浮动特性"></a>浮动特性</h5><ul><li><p>浮动的元素会脱离标准流</p><ul><li>脱离标准普通流的控制(浮)移动到指定位置(动)(俗称脱标)</li><li>浮动的盒子不再保留原先的位置</li></ul></li><li><p>浮动的元素会一行内显示并且元素顶部对齐</p><ul><li>当父级元素装不下时,多出的盒子会另起一行。</li></ul></li><li><p>浮动的元素会具有行内块元素的特性</p><ul><li>任何种类的元素都可以加浮动,但是加了浮动之后就会变成行内块元素。</li><li>如果块级元素没有设置宽度,默认宽度是和父级一样宽,但是添加浮动后,它的大小根据内容决定。</li></ul></li></ul><h5 id="浮动布局的注意点"><a href="#浮动布局的注意点" class="headerlink" title="浮动布局的注意点"></a>浮动布局的注意点</h5><ul><li><p>通常是规定父级元素是标准流,然后子元素再规定为浮动。</p></li><li><p>==理论上一个元素浮动了,其他兄弟元素也需要浮动。==</p></li><li><p>浮动的盒子只会影响后面的标准流</p></li></ul><h5 id="清除浮动"><a href="#清除浮动" class="headerlink" title="清除浮动"></a>清除浮动</h5><ul><li>由于父级盒子很多情况下不方便给高度,但是盒子浮动又不占有位置,最后父级盒子高度为0时,就会影响下面的标准流盒子</li><li>由于浮动元素不再占有原文档流的位置,所以它会对后面的元素排版产生影响</li><li>样式 选择器{clear:left/right/both;}</li><li>清除浮动方法<ul><li>额外标签法(隔墙法 不常用):在需要清除浮动的最后一个元素后写一个盒子(必须是块级元素 div最好),加上clear both。</li><li>父级添加overflow:可以给父级元素添加overflow属性,将其属性值设置为hidden、auto、或scroll。hidden可以清除浮动。</li><li>after伪元素法:在父元素后面插入一个新盒子。</li><li>双伪元素清除浮动:在新盒子的内部前面后面都插入一个盒子。</li></ul></li></ul><h3 id="定位"><a href="#定位" class="headerlink" title="定位"></a>定位</h3><h5 id="定位的应用"><a href="#定位的应用" class="headerlink" title="定位的应用"></a>定位的应用</h5><p>用于使盒子自由的在某个盒子内移动位置或者固定屏幕中的某个位置,并且可以压住盒子。</p><h5 id="定位的组成"><a href="#定位的组成" class="headerlink" title="定位的组成"></a>定位的组成</h5><ul><li>定位模式 属性为position<ul><li>static为静态定位 相当于无定位 按照标准流摆放 通常不使用</li><li>==relative为相对定位== 相对于自己原来的位置进行移动 只与自己原来的位置有关系 且原来在标准流的位置继续占有(人飞了,但是后面的人还给他留空)用于限制绝对定位(父相子绝)</li><li>==absolute为绝对定位== 要看祖先元素 <ul><li>若无祖先 以浏览器界面对齐 </li><li>若祖先元素有定位 以最近一级的有定位祖先元素对齐</li><li>绝对定位的位置不再进行保留</li></ul></li><li>==fixed为固定定位== 固定住盒子 即使滑动页面也不会改变盒子 以可视窗口的距离来移动位置<ul><li>让固定的盒子以版心对其:先让固定的盒子left50%,然后margin版心宽度的一半</li></ul></li><li>sticky为粘性定位 刚开始相对定位 拉到盒子即将出可视空间时就变成固定定位</li></ul></li><li>边偏移 是定位的一个属性 有top/bottom/left/right 后面可以直接加距离</li></ul><h5 id="定位的叠放次序"><a href="#定位的叠放次序" class="headerlink" title="定位的叠放次序"></a>定位的叠放次序</h5><ul><li>使用z-index属性值可以控制盒子的叠放顺序 </li><li>数值可以时正整数、负整数、或是0,默认是auto,数值越大,盒子越靠上</li><li>如果属性值相同,则按照书写顺序,后来者居上</li><li>数字后面不可以加单位</li><li>只有定位的盒子才有z-index属性</li></ul><h5 id="定位的扩展"><a href="#定位的扩展" class="headerlink" title="定位的扩展"></a>定位的扩展</h5><ul><li>加了绝对定位的盒子不可以通过margin水平居中 但是可以通过left50%+margin-left半个盒子的距离来实现居中(垂直居中同理)</li><li>行内元素添加固定或者绝对定位,可以直接设置高度和宽度</li><li>浮动元素、绝对定位元素都不会触发外边距合并的问题</li><li>浮动元素只会压住其底下标准流的盒子,但是不会压住下面标准流盒子里面的文字和图片,但绝对定位会完全压住下面标准流中的所有内容。(浮动不会压住文字图片的原因是,浮动本来就是用于文字围绕图片的)</li></ul><p>如果一个盒子既有left属性又有right属性,则会默认执行left属性 同理有top bottom属性会执行top属性</p><h3 id="属性的显示与隐藏"><a href="#属性的显示与隐藏" class="headerlink" title="属性的显示与隐藏"></a>属性的显示与隐藏</h3><p>本质是让一个元素显示或者隐藏</p><ul><li>==display显示隐藏元素==<ul><li>属性值为none时表示隐藏对象</li><li>属性值为block时表示转换为块级元素,同时还有显示元素的意思</li><li>隐藏元素后盒子消失且占有的位置消失</li></ul></li><li>visibility可见性<ul><li>属性值为visible元素可视</li><li>属性值为hidden元素隐藏</li><li>隐藏元素的盒子消失但是占有的位置还在</li></ul></li><li>overflow溢出<ul><li>对内容超过盒子宽度高度的内容进行影响</li><li>属性值visible显示</li><li>属性值hidden隐藏</li><li>属性值scroll溢出部分显示滚动条</li><li>属性值auto自动添加滚动条(溢出显示滚动条,不溢出不显示)</li><li>有定位的盒子慎用hidden属性值,因为其会隐藏多余的部分</li></ul></li></ul><h1 id="滚动"><a href="#滚动" class="headerlink" title="滚动"></a>滚动</h1><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><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><code class="hljs css"><span class="hljs-comment">/* 一整块一整块的滑动 */</span><br><span class="hljs-attribute">scroll-padding</span>/<span class="hljs-attribute">scroll-margin</span>: <span class="hljs-number">0</span>;<br><br><span class="hljs-comment">/* 元素竖向采用滑动格式 */</span><br><span class="hljs-attribute">overflow-y</span>: scroll;<br><br><span class="hljs-comment">/* 滑动条调色,前面是滑条颜色,后面是背景色 */</span><br><span class="hljs-attribute">scrollbar-color</span>: <span class="hljs-number">#007</span> <span class="hljs-number">#bada55</span>;<br><br><span class="hljs-comment">/* 在内嵌滑动条元素滑到底时大滑动条不跟随滑动 */</span><br>overscroll-behavior: contain;<br><br><span class="hljs-comment">/* 留出滑动条位置,不让出现滑动条改变样式 */</span><br><span class="hljs-attribute">scrollbar-gutter</span>: stable both-edges;<br></code></pre></td></tr></table></figure><h1 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h1><h2 id="精灵图"><a href="#精灵图" class="headerlink" title="精灵图"></a>精灵图</h2><p>为了有效的减少服务器接受和发送请求的次数,提高页面的加载速度,出现了CSS精灵技术(也称CSS Sprites)核心原理 将全部图片加载到一个大图片中 包含所有需要请求的小图片</p><h2 id="字体图标"><a href="#字体图标" class="headerlink" title="字体图标"></a>字体图标</h2><p>主要用于显示网页中通用的、常用的一些小图标,一般采用SVG/Unicode格式</p><ul><li>轻量:一个字体图标要比一系列的图像要小。一旦字体加载了,图标就会马上渲染出来,减少了服务器请求</li><li>灵活性:本质其实是文字,可以很随意的改变颜色、产生阴影、透明效果、旋转等</li><li>兼容性:几乎支持所有浏览器</li></ul><h2 id="计算规格"><a href="#计算规格" class="headerlink" title="计算规格"></a>计算规格</h2><p><code>calc</code>函数可以允许宽度进行运算:</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-attribute">width</span>:<span class="hljs-built_in">calc</span>(<span class="hljs-number">100%</span>-<span class="hljs-number">30px</span>);<br></code></pre></td></tr></table></figure><p>如果需要同时设置最大最小值,可以使用<code>clamp</code>函数解决:</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><code class="hljs css"><style><br> <span class="hljs-selector-tag">h1</span> { <span class="hljs-attribute">font-size</span>: <span class="hljs-built_in">clamp</span>(<span class="hljs-number">2.2em</span>, <span class="hljs-number">3vw</span> + <span class="hljs-number">1em</span>, <span class="hljs-number">2.5em</span>) }<br></style><br></code></pre></td></tr></table></figure><h2 id="阶梯值函数"><a href="#阶梯值函数" class="headerlink" title="阶梯值函数"></a>阶梯值函数</h2><p>在2023年年底增加的<code>round()</code>、<code>rem()</code>、<code>mod()</code>阶梯值函数适用于流体设计,流体设计概念则建议使用相对单位和 CSS 数学函数,根据视口大小动态调整整个网站元素。</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><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><code class="hljs css"><style><br><span class="hljs-selector-pseudo">:root</span> { <span class="hljs-attr">--width</span>: <span class="hljs-number">527px</span> }<br><span class="hljs-comment">/* round函数让容器更新为可以被25px整除的像素值 */</span><br><span class="hljs-selector-class">.round</span> {<br> <span class="hljs-attribute">width</span>: <span class="hljs-built_in">round</span>(<span class="hljs-built_in">var</span>(--width), <span class="hljs-number">25px</span>); <span class="hljs-comment">/* 525px */</span><br>}<br><br><span class="hljs-comment">/* rem函数取余 */</span><br><span class="hljs-selector-class">.rem</span> {<br> <span class="hljs-attribute">width</span>: <span class="hljs-built_in">rem</span>(<span class="hljs-built_in">var</span>(--width), <span class="hljs-number">25px</span>); <span class="hljs-comment">/* 2px */</span><br>}<br><br><span class="hljs-comment">/* mod函数取模,同取余,但符号取除数的符号 */</span><br><span class="hljs-selector-class">.mod</span> {<br> <span class="hljs-attribute">width</span>: <span class="hljs-built_in">mod</span>(<span class="hljs-built_in">var</span>(--width), -<span class="hljs-number">25px</span>); <span class="hljs-comment">/* -2px */</span><br>}<br></style> <br></code></pre></td></tr></table></figure><h2 id="主题切换"><a href="#主题切换" class="headerlink" title="主题切换"></a>主题切换</h2><p>除了使用<code>:root</code>选择器设置初值一点一点更改之外,浏览器提供了一种简单的方式用于适配光暗主题颜色:</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><code class="hljs css"><span class="hljs-selector-pseudo">:root</span> {<br> <span class="hljs-attribute">color</span>-scheme: dark/light;<br>}<br></code></pre></td></tr></table></figure><p>可以在单个元素上使用这个属性。</p><h2 id="表单元素颜色定制"><a href="#表单元素颜色定制" class="headerlink" title="表单元素颜色定制"></a>表单元素颜色定制</h2><p>对于表单元素而言我们可以用<code>accent-color</code>值来控制主题色:</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><code class="hljs css"><span class="hljs-selector-pseudo">:root</span> {<br> accent-<span class="hljs-attribute">color</span>: mediumvioletred;<br>}<br></code></pre></td></tr></table></figure><h2 id="大小自适应包裹"><a href="#大小自适应包裹" class="headerlink" title="大小自适应包裹"></a>大小自适应包裹</h2><p>有时候遇到需要盒子里面有文字,希望直接进行一个包裹的,将其宽度自动调整为恰好适应其内容的大小,可以使用以下属性:</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-attribute">width</span>: fit-content;<br></code></pre></td></tr></table></figure><h2 id="边框图片"><a href="#边框图片" class="headerlink" title="边框图片"></a>边框图片</h2><p>边框如果需要用到背景图片,可以采用<code>border-image</code>相关属性。</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-attribute">border-image</span>: <border-image-outset> <border-image-repeat> <border-image-slice> <border-image-source> <border-image-width><br></code></pre></td></tr></table></figure><h2 id="CSS计数器"><a href="#CSS计数器" class="headerlink" title="CSS计数器"></a>CSS计数器</h2><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><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><code class="hljs css"><span class="hljs-selector-pseudo">:root</span> { <span class="hljs-attribute">counter-reset</span>: references }<br><br><span class="hljs-comment">/* 带href的a标签出现过几次after伪元素就会显示对应的值 */</span><br><span class="hljs-selector-tag">a</span><span class="hljs-selector-attr">[href]</span><span class="hljs-selector-pseudo">:empty</span><span class="hljs-selector-pseudo">::after</span> {<br> <span class="hljs-attribute">counter-increment</span>: references;<br> <span class="hljs-attribute">content</span>: <span class="hljs-string">'['</span> <span class="hljs-built_in">counter</span>(references) <span class="hljs-string">']'</span>;<br>}<br></code></pre></td></tr></table></figure><h2 id="盒子模型计算"><a href="#盒子模型计算" class="headerlink" title="盒子模型计算"></a>盒子模型计算</h2><p>通过<code>box-sizing</code>来指定盒子模型:</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-attribute">box-sizing</span>:<span class="hljs-built_in">content-box</span>(默认值,盒子大小按照width和height计算)/<span class="hljs-built_in">border-box</span>(算上padding&border,便于布局用);<br></code></pre></td></tr></table></figure><h2 id="图片滤镜"><a href="#图片滤镜" class="headerlink" title="图片滤镜"></a>图片滤镜</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-attribute">filter</span>: <span class="hljs-built_in">url</span>()/<span class="hljs-built_in">blur</span>()(高斯模糊)/<span class="hljs-built_in">constrast</span>()(对比度)/<span class="hljs-built_in">brightness</span>()(亮度)/<span class="hljs-built_in">drop-shadow</span>()(沿图像的轮廓生成阴影效果,语法类box-shadow)/<span class="hljs-built_in">grayscale</span>()(转灰度图)/<span class="hljs-built_in">hue-rotate</span>()(应用色相旋转)/<span class="hljs-built_in">invert</span>()(反转输入图像)/<span class="hljs-built_in">opacity</span>()(透明度)/<span class="hljs-built_in">saturate</span>()(饱和度)/<span class="hljs-built_in">sepia</span>()(改为深褐色)<br></code></pre></td></tr></table></figure><h2 id="过渡"><a href="#过渡" class="headerlink" title="过渡"></a>过渡</h2><p>盒子执行动作更加自然。</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-attribute">transition</span>: <transition-property> <transition-duration> <transition-timing-function> <transition-delay><br></code></pre></td></tr></table></figure><h2 id="转换"><a href="#转换" class="headerlink" title="转换"></a>转换</h2><p>转换<code>transform</code>是CSS3中具有颠覆性的特征之一,可以实现元素的位移、旋转、缩放等效果</p><p><a href="https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform">transform</a></p><blockquote><p>如果想要在网页中产生3D效果需要透视(理解成3D物体投影在2D平面中)</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><code class="hljs css"><span class="hljs-comment">/* 两个写法作用一样 */</span><br><span class="hljs-attribute">perspective</span>: val;<br><span class="hljs-attribute">transform</span>: <span class="hljs-built_in">perspective</span>();<br></code></pre></td></tr></table></figure><p>透视我们也称为视距:视距就是人的眼睛到屏幕的距离,距离视觉点越近的在电脑平面成像就越大,越远成像越小,==透视写在被观察元素的父盒子上==</p></blockquote><blockquote><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-attribute">transform-style</span>: flat/preserve-<span class="hljs-number">3</span>d;<br></code></pre></td></tr></table></figure><p>设置元素的子元素是位于 3D 空间中还是平面中.</p></blockquote><h2 id="动画"><a href="#动画" class="headerlink" title="动画"></a>动画</h2><p>动画是CSS3中具有颠覆性的特征之一,可通过设置多个节点来精确控制一个或一组动画,通常用于实现复杂的动画效果、相比较过渡,动画可以实现更多变化,更多控制,连续自动播放等效果。</p><p>动画分两步,先<strong>定义</strong>动画,再<strong>使用</strong>动画</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><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-comment">/* 定义动画 */</span><br><span class="hljs-keyword">@keyframes</span> 动画名称{<br><span class="hljs-number">0%</span>{... : ... ;}<br><span class="hljs-number">100%</span>{... : ... ;}<br>}<br></code></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></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-comment">/* 使用动画 */</span><br><span class="hljs-attribute">animation</span>: <animation-name> <animation-duration> <animation-timing-function> <animation-delay> <animation-iteration-count> <animation-direction> <animation-fill-mode> <animation-play-state><br></code></pre></td></tr></table></figure><p>我们也可以在关键帧中更新css变量<code>@property</code>,这样就可以快速动画化多个元素,无需自己手写多个关键帧。</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><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><code class="hljs css"><span class="hljs-comment">/* 定义--t */</span><br><span class="hljs-keyword">@property</span> --t {<br> syntax: <span class="hljs-string">"<number>"</span>;<br> initial-value: <span class="hljs-number">0</span>;<br> inherits: true;<br>}<br><br><span class="hljs-comment">/* 写--t动画逻辑 */</span><br><span class="hljs-keyword">@keyframes</span> tick {<br> <span class="hljs-selector-tag">from</span> { <span class="hljs-attr">--t</span>: <span class="hljs-number">0</span> }<br> <span class="hljs-selector-tag">to</span> { <span class="hljs-attr">--t</span>: <span class="hljs-number">100000</span> }<br>}<br><br><span class="hljs-comment">/* 使--t动画一直运行 */</span><br><span class="hljs-selector-pseudo">:root</span> { <span class="hljs-attribute">animation</span>: tick <span class="hljs-number">86400s</span> linear infinite }<br><br><span class="hljs-comment">/* 进而使盒子位置平滑发生循环移动 */</span><br> <span class="hljs-selector-tag">div</span> > <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:first</span>-child { translate: <span class="hljs-built_in">calc</span>(<span class="hljs-built_in">sin</span>(<span class="hljs-built_in">var</span>(--t)) * <span class="hljs-number">200px</span> + <span class="hljs-number">200px</span>) }<br> <span class="hljs-selector-tag">div</span> > <span class="hljs-selector-tag">div</span><span class="hljs-selector-pseudo">:last-child</span> { translate: <span class="hljs-built_in">calc</span>(<span class="hljs-built_in">cos</span>(<span class="hljs-built_in">var</span>(--t)) * <span class="hljs-number">200px</span> + <span class="hljs-number">200px</span>) }<br></code></pre></td></tr></table></figure><h1 id="项目规划"><a href="#项目规划" class="headerlink" title="项目规划"></a>项目规划</h1><h3 id="样式的模块化开发"><a href="#样式的模块化开发" class="headerlink" title="样式的模块化开发"></a>样式的模块化开发</h3><p>可以写部分CSS用于多个HTML文件 每当使用时就引用</p><h3 id="制作网站favicon图标"><a href="#制作网站favicon图标" class="headerlink" title="制作网站favicon图标"></a>制作网站favicon图标</h3><p>将准备的图标切成png图片</p><p>将png图片转化为ico图标,这需要借助第三方的转化网站</p><p>将制作好的图标放在网页根目录下</p><p>在head标签中复制网站上的代码粘贴即可</p><h3 id="网站TDK三大标签SEO优化"><a href="#网站TDK三大标签SEO优化" class="headerlink" title="网站TDK三大标签SEO优化"></a>网站TDK三大标签SEO优化</h3><p>SEO汉译为搜索引擎优化,是一种利用搜索引擎的规则提高网站在有关搜索引擎内自然排名的方式。</p><p>前端人员不做SEO但是也要符合TDK三大标签优化</p><p>T:title </p><ul><li><p>title具有不可替代性,是我们内页的第一个重要标签,是搜索引擎了解网站的入口和对网页主题归属的最佳判断点</p></li><li><p>建议:网站名(产品名)-网站的介绍(尽量不要超过30个汉字)</p></li></ul><p>D:description</p><ul><li>简要说明网站是干什么的</li><li>提倡description作为网站的总体业务和主题概括</li><li>前端人员只需要准备好meta name=”description” content=””/单标签给准备好就行 接下来交给SEO开发人员</li></ul><p>K:keywords</p><ul><li>keywords是网站的关键词,是搜索引擎的关注点之一</li><li>keywords最好限制在6~8个关键词,关键词之间用英文逗号隔开</li><li>meta name=”keywords” content=””/</li></ul><h3 id="LOGO-SEO-优化"><a href="#LOGO-SEO-优化" class="headerlink" title="LOGO SEO 优化"></a>LOGO SEO 优化</h3><ul><li><p>logo中首先放一个h1标签,目的是提权,告诉搜索引擎,这个地方很重要</p></li><li><p>h1里面再放一个链接 可以返回首页的 把logo的背景图片给链接即可</p></li><li><p>为了搜索引擎收录我们 我们来链接里面要放文字(网站名称),但是名字不要显示出来</p><ul><li>方法是font-size:0; 这样就看不见文字了</li></ul></li><li><p>最后给链接一个title属性,这样鼠标放在logo上就有提示文字了</p></li></ul><h1 id="Flex布局原理"><a href="#Flex布局原理" class="headerlink" title="Flex布局原理"></a>Flex布局原理</h1><ul><li><p>flex是“弹性布局”,用来为盒装模型提供最大的灵活性,任何一个容器都可以指定为flex布局</p></li><li><p>当为父元素设置flex布局之后,子元素的float、clear、vertical-align属性将失效</p></li><li><p>定义为display:flex;</p></li></ul><h3 id="常见父项属性"><a href="#常见父项属性" class="headerlink" title="常见父项属性"></a>常见父项属性</h3><ul><li>flex-direction:设置主轴的方向<ul><li>主轴与侧轴 默认主轴为x 侧轴为y</li><li>属性值为row(x轴)/row-reverse(从右到左)/column(y轴)/column-reverse(从下到上)</li></ul></li><li>justify-content:设置主轴上子元素的排列方式<ul><li>属性值为flex-start(默认)/flex-end(从尾部开始)/center(居中)/space-around(平分空间)/==space-between(先两边贴边 再平分剩余空间)==</li></ul></li><li>flex-wrap:设置子元素是否换行<ul><li>flex布局中 默认的子元素是不换行的 如果装不开 会缩小子元素的宽度 放到父元素里面</li></ul></li><li>align-items:设置侧轴上的子元素的排列方式(单行)<ul><li>属性值为flex-start(默认)/flex-end(从尾部开始)/center(居中)/stretch(拉伸)–>变得和父级一样</li></ul></li><li>align-content:设置侧轴上的子元素的排列方式(多行)<ul><li>设置子项在侧轴上的排列方式并且只能用于子项出现换行的情况,在单行下是没有效果的</li><li>flex-start(默认)/flex-end(从尾部开始)/center(居中)/space-around(平分空间)/space-between(先两边贴边 再平分剩余空间)/stretch(设置子项元素高度平分父元素高度)</li></ul></li><li>flex-flow:复合属性</li></ul><h3 id="常见子项属性"><a href="#常见子项属性" class="headerlink" title="常见子项属性"></a>常见子项属性</h3><ul><li><p>flex子项目占的份数</p><ul><li><p>分配的是==剩余空间==</p></li><li><p>样式为flex:数字;</p></li></ul></li><li><p>align-self控制子项自己在侧轴的排列方式</p><ul><li>align-self允许某单个项目有与其他项目不同的对齐方式 可以覆盖align-items</li></ul></li><li><p>order属性定义子项的排列顺序(先后顺序)</p><ul><li>数值越小 排列越靠前 默认为0</li></ul></li></ul>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
<tag>迁移</tag>
</tags>
</entry>
<entry>
<title>Ajax</title>
<link href="/2023/06/24/Ajax/"/>
<url>/2023/06/24/Ajax/</url>
<content type="html"><![CDATA[<h1 id="客户端和服务端"><a href="#客户端和服务端" class="headerlink" title="客户端和服务端"></a>客户端和服务端</h1><p>服务器:上网过程中,负责存放和对外提供资源的电脑,叫做服务器</p><p>客户端:上网过程中负责获取和消费资源的电脑,叫做客户端</p><h1 id="URL"><a href="#URL" class="headerlink" title="URL"></a>URL</h1><h3 id="地址的概念"><a href="#地址的概念" class="headerlink" title="地址的概念"></a>地址的概念</h3><p>URL中文叫统一资源定位符,用于标识互联网上的每个资源的唯一存放位置。浏览器只有通过URL地址,才能正确定位资源的存放位置,从而正确的访问到对应的资源</p><h3 id="地址的组成部分"><a href="#地址的组成部分" class="headerlink" title="地址的组成部分"></a>地址的组成部分</h3><p>URL地址一般由三部分组成:</p><ul><li>客户端与服务器之间的通信协议(协议)</li><li>存有该资源的服务器名称(域名)</li><li>资源在服务器上具体的存放位置(路径)</li></ul><h1 id="了解Ajax"><a href="#了解Ajax" class="headerlink" title="了解Ajax"></a>了解Ajax</h1><h3 id="什么是Ajax"><a href="#什么是Ajax" class="headerlink" title="什么是Ajax"></a>什么是Ajax</h3><p>Ajax的全程是异步 Javascript 和 XML</p><p>通俗的理解是:在网页中利用XMLHttpRequest对象和服务进行数据交互的方式就是Ajax</p><h3 id="为什么要学Ajax"><a href="#为什么要学Ajax" class="headerlink" title="为什么要学Ajax"></a>为什么要学Ajax</h3><p>之前所学的技术,只能把网页做得更美观。但是Ajax能让我们轻松实现网页与服务器之间的数据交互</p><h3 id="Ajax的典型应用场景"><a href="#Ajax的典型应用场景" class="headerlink" title="Ajax的典型应用场景"></a>Ajax的典型应用场景</h3><ul><li>数据分页显示:当点击页码值的时候,通过ajax的形式,根据页码值动态刷新表格的数据</li><li>数据的增删改查:数据的添加、删除、修改、查询操作,都需要通过ajax的形式,来实现数据的交互</li></ul><h1 id="JQuery中的Ajax"><a href="#JQuery中的Ajax" class="headerlink" title="JQuery中的Ajax"></a>JQuery中的Ajax</h1><h3 id="了解JQuery中的Ajax"><a href="#了解JQuery中的Ajax" class="headerlink" title="了解JQuery中的Ajax"></a>了解JQuery中的Ajax</h3><p>浏览器中提供的XMLHttpRequest用法比较复杂,所以jQuery对XMLHttpRequest进行了封装,提供了一系列Ajax相关的函数,极大地降低了Ajax的使用难度</p><p>jQuery中发送Ajax请求最常用的三个方法如下:</p><ul><li>$.get()</li><li>$.post()</li><li>$.ajax()</li></ul><h3 id="get-函数的语法"><a href="#get-函数的语法" class="headerlink" title="$.get()函数的语法"></a>$.get()函数的语法</h3><p>jQuery中此函数功能单一,专门用来发起get请求,从而将服务器上的资源请求到客户端来使用。</p><p>语法:$.get(url,{data},[callback])</p><ul><li>url:类型为字符串,必选项,指要请求的资源地址</li><li>data:类型为对象,非必选项,指请求资源期间要携带的参数</li><li>callback:类型为函数,非必选项,指请求成功时的回调函数</li></ul><h3 id="post-函数的语法"><a href="#post-函数的语法" class="headerlink" title="$.post()函数的语法"></a>$.post()函数的语法</h3><p>jQuery中此函数功能单一,专门用来发起post请求,从而向服务器提交数据</p><p>语法:$.post(url,{data},[callback])</p><ul><li>url:类型为字符串,必选项,指要请求的资源地址</li><li>data:类型为对象,非必选项,指请求资源期间要携带的参数</li><li>callback:类型为函数,非必选项,指请求成功时的回调函数</li></ul><h3 id="ajax-函数的语法"><a href="#ajax-函数的语法" class="headerlink" title="$.ajax()函数的语法"></a>$.ajax()函数的语法</h3><p>相比于前两个函数,jQuery中提供的此函数,是一个功能比较综合的函数,它允许我们对Ajax请求进行更详细的配置</p><p>$.ajax()函数的基本语法如下:</p><p>$.ajax({<br> type:’‘,//请求的方式,如 GET or POST<br> url:’‘,//请求的URL地址<br> data:{},//这次请求要携带的数据<br> success:function(res){} //请求成功之后的回调函数<br>})</p><h1 id="接口"><a href="#接口" class="headerlink" title="接口"></a>接口</h1><h3 id="接口的概念"><a href="#接口的概念" class="headerlink" title="接口的概念"></a>接口的概念</h3><p>使用Ajax请求数据时,被请求的URL地址,就叫做数据接口,同时每个接口必须有请求方式</p><h3 id="接口文档"><a href="#接口文档" class="headerlink" title="接口文档"></a>接口文档</h3><h5 id="接口文档的概念"><a href="#接口文档的概念" class="headerlink" title="接口文档的概念"></a>接口文档的概念</h5><p>接口文档,顾名思义就是接口的说明文档,它是我们调用接口的依据。好的接口文档包含了对接口URL,参数以及输出内容的说明,我们参照接口文档就能方便的知道接口的作用,以及接口如何进行调用</p><h5 id="接口文档的组成部分"><a href="#接口文档的组成部分" class="headerlink" title="接口文档的组成部分"></a>接口文档的组成部分</h5><p>接口文档可以包含很多信息,一般包含一下内容</p><ul><li>接口名称:用于标识各个接口的简单说明</li><li>接口URL:接口的调用地址</li><li>调用方式:接口的调用方式</li><li>参数格式:接口需要传递的参数</li><li>响应格式:接口的返回值的详细描述</li><li>返回示例:举个成功的例子</li></ul><h1 id="form表单"><a href="#form表单" class="headerlink" title="form表单"></a>form表单</h1><h3 id="表单的概念"><a href="#表单的概念" class="headerlink" title="表单的概念"></a>表单的概念</h3><p>表单在网页中主要负责数据采集。HTML的form就是用于采集用户输入的信息,并通过form标签的提交操作,把采集到的信息提交到服务器端中进行处理。</p><h3 id="表单的组成部分"><a href="#表单的组成部分" class="headerlink" title="表单的组成部分"></a>表单的组成部分</h3><ul><li>表单标签</li><li>表单域</li><li>表单按钮</li></ul><h3 id="form标签的属性"><a href="#form标签的属性" class="headerlink" title="form标签的属性"></a>form标签的属性</h3><h5 id="action"><a href="#action" class="headerlink" title="action"></a>action</h5><ul><li>值:URL地址</li><li>描述:规定当提交表单时,向何处发送表单数据</li></ul><h5 id="method"><a href="#method" class="headerlink" title="method"></a>method</h5><ul><li>值:get或者post</li><li>描述:规定以何种方法把表单数据提交到action URL</li></ul><h5 id="target"><a href="#target" class="headerlink" title="target"></a>target</h5><ul><li>_blank:在新窗口中打开</li><li>_self:默认,在相同的框架中打开</li><li>_parent:在父框架集中打开</li><li>_top:在整个窗口中打开</li><li>framename:在指定框架中打开</li></ul><h5 id="enctype"><a href="#enctype" class="headerlink" title="enctype"></a>enctype</h5><ul><li>application/x-www-form-urlencoded:默认的编码方式。基于uri的percent-encoding编码的,表单里的数据被编码为名称/值对,但是在用文本的传输和MP3等大型文件的时候,使用这种编码就显得 效率低下</li><li>multipart/form-data:指定传输数据为二进制类型,比如图片、mp3、文件。 这个一般文件上传时用。它告诉我们传输的数据要用到多媒体传输协议,由于多媒体传输的都是大量的数据,所以规定上传文件必须是post方法,type=”file”,浏览器会把整个表单以控件为单位分割。并为每个部分加上Content-Disposition(form-data或者file),Content-Type(默认为text/plain),name(控件name)等信息,并加上分割符(boundary)。</li><li>text/plain:纯文体的传输。空格转换为 “+” 加号,但不对特殊字符编码。</li></ul><h3 id="表单的缺点"><a href="#表单的缺点" class="headerlink" title="表单的缺点"></a>表单的缺点</h3><p>如果使用表单提交数据,则会导致页面之前的状态和数据丢失</p><p>解决方案是:表单只负责采集数据,Ajax负责将数据提交到服务器</p><h3 id="快速获取表单中的数据"><a href="#快速获取表单中的数据" class="headerlink" title="快速获取表单中的数据"></a>快速获取表单中的数据</h3><ul><li>serialize函数</li></ul><h1 id="模板引擎"><a href="#模板引擎" class="headerlink" title="模板引擎"></a>模板引擎</h1><h3 id="基本概念"><a href="#基本概念" class="headerlink" title="基本概念"></a>基本概念</h3><p>可以根据程序员指定的模板结构和数据,自动生成一个完整的HTML页面</p><h3 id="好处"><a href="#好处" class="headerlink" title="好处"></a>好处</h3><ul><li>减少了字符串的拼接操作</li><li>使代码结构更加清晰</li><li>使代码更易于阅读和维护</li></ul><h3 id="art-template模板引擎"><a href="#art-template模板引擎" class="headerlink" title="art-template模板引擎"></a>art-template模板引擎</h3><ul><li>导入art-template<ul><li>只要导入模板引擎,在window全局多一个函数,叫做template(‘模板的id’,需要渲染的数据对象)</li></ul></li><li>定义数据</li><li>定义模板<ul><li>例如script type=”text/html” 这样就可以在script里面写html且不报错</li><li>在双括号里面写你调用数据的名字</li></ul></li><li>调用template函数</li><li>渲染HTML<ul><li>再用你要放html的box渲染,element.html()即可</li></ul></li></ul><h3 id="art-template标准语法"><a href="#art-template标准语法" class="headerlink" title="art-template标准语法"></a>art-template标准语法</h3><p>p30</p>]]></content>
<categories>
<category>技术栈</category>
</categories>
<tags>
<tag>前端</tag>
<tag>笔记</tag>
<tag>迁移</tag>
</tags>
</entry>
<entry>
<title>Git</title>
<link href="/2023/06/24/Git/"/>
<url>/2023/06/24/Git/</url>
<content type="html"><![CDATA[<h2 id="从本地到github简易流程"><a href="#从本地到github简易流程" class="headerlink" title="从本地到github简易流程"></a>从本地到github简易流程</h2><figure class="highlight bash"><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><code class="hljs bash">//首先对于你的工作文件夹<br>git init<br>//添加所有文件或者添加某个文件到缓存区<br>git add .<br>//然后commit到本地仓库<br>git commit -m <span class="hljs-string">"本次上传的信息"</span><br>//添加远程仓库位置<br>git remote add origin https://github.com/.......<br>//修改分支<br>git branch -m main<br>//提交<br>git push -u origin main<br></code></pre></td></tr></table></figure><h2 id="Git基础使用"><a href="#Git基础使用" class="headerlink" title="Git基础使用"></a>Git基础使用</h2><h3 id="初始化"><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h3><figure class="highlight bash"><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><code class="hljs bash">//git初始化<br>git init <br>//clone仓库,在init之后<br>git <span class="hljs-built_in">clone</span> <repo> <<span class="hljs-built_in">dir</span>><br>//查看git状态<br>git status<br></code></pre></td></tr></table></figure><h3 id="上传到暂存区"><a href="#上传到暂存区" class="headerlink" title="上传到暂存区"></a>上传到暂存区</h3><figure class="highlight bash"><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><code class="hljs bash">git add <file><br>//上传所有文件就是<br>git add .<br></code></pre></td></tr></table></figure><h3 id="提交到本地仓库"><a href="#提交到本地仓库" class="headerlink" title="提交到本地仓库"></a>提交到本地仓库</h3><figure class="highlight bash"><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><code class="hljs bash">//提交到仓库<br>git commit -m <span class="hljs-string">"信息"</span><br>//查看提交记录<br>git <span class="hljs-built_in">log</span> --oneline<br></code></pre></td></tr></table></figure><h3 id="远程仓库"><a href="#远程仓库" class="headerlink" title="远程仓库"></a>远程仓库</h3><figure class="highlight bash"><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><code class="hljs bash">//查看所有仓库<br>git remote<br>//查看所有仓库详细信息<br>git remote -v<br>//添加仓库<br>git remote add <name> https://github.com/.......<br>//删除仓库<br>git remote <span class="hljs-built_in">rm</span> <name><br>//显示某仓库信息<br>git show <name><br>//修改仓库名字<br>git rename <old_name> <new_name><br></code></pre></td></tr></table></figure><h3 id="分支"><a href="#分支" class="headerlink" title="分支"></a>分支</h3><figure class="highlight bash"><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><code class="hljs bash">//查看分支<br>git branch<br>//新建分支<br>git branch <name><br>//修改当前分支<br>git branch -m <name><br>//删除本分支<br>git branch -d<br>//创建新分支的同时进入分支<br>git branch -b<br>//切换分支命令/返回历史版本命令<br>git checkout <branch><br>//将当前分支合并到目标分支<br>git merge <new_branch><br><br>//更清晰的切换分支<br>git switch <branch><br>//创建新分支并且切换<br>git switch -c <branch><br>//回到前一个分支<br>git switch -<br></code></pre></td></tr></table></figure><h3 id="拉取"><a href="#拉取" class="headerlink" title="拉取"></a>拉取</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">git pull <远程仓库名> <远程分支名>:<本地分支名><br></code></pre></td></tr></table></figure><h3 id="推送到远程仓库"><a href="#推送到远程仓库" class="headerlink" title="推送到远程仓库"></a>推送到远程仓库</h3><figure class="highlight bash"><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><code class="hljs bash">//提交,一般来说本地分支和远程分支名字相同,所以可以省略冒号及其后面的部分<br>git push <远程仓库名> <本地分支名>:<远程分支名><br>//强制推送<br>git push -f ...<br>//设置默认值<br>git push -u ...<br><br></code></pre></td></tr></table></figure><h3 id="撤销"><a href="#撤销" class="headerlink" title="撤销"></a>撤销</h3><figure class="highlight bash"><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><code class="hljs bash">//还原所有未提交的更改,包括工作目录和暂存区的更改<br>git restore .<br>//使用该命令会将add到缓存区的文件撤销<br>git restore --staged <file><br></code></pre></td></tr></table></figure><h3 id="删除"><a href="#删除" class="headerlink" title="删除"></a>删除</h3><figure class="highlight bash"><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><code class="hljs bash">//从暂存区和本地文件夹中删除<br>git <span class="hljs-built_in">rm</span> <file><br>//只删除暂存区文件<br>git <span class="hljs-built_in">rm</span> --cached <file><br>//遍历删除文件夹及其下的子文件夹 <br>git <span class="hljs-built_in">rm</span> -r <file><br>//强制删除<br>git <span class="hljs-built_in">rm</span> -f <file><br></code></pre></td></tr></table></figure><h3 id="回退"><a href="#回退" class="headerlink" title="回退"></a>回退</h3><figure class="highlight bash"><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><code class="hljs bash">//回退到某个版本<br>git reset <version><br>//回退到上一个版本<br>git reset HEAD^<br>//回退到上上个版本<br>git reset HEAD^^<br>//将文件夹中文件一并回退<br>git reset --hard HEAD^<br></code></pre></td></tr></table></figure><h3 id="gitignore"><a href="#gitignore" class="headerlink" title=".gitignore"></a>.gitignore</h3><p>添加<code>.gitignore</code>文件并在其下写上文件路径,就不会被传到github</p><h2 id="Issues"><a href="#Issues" class="headerlink" title="Issues"></a>Issues</h2><p>github中可以对别人的仓库添加一个issue</p><h3 id="提出Issues"><a href="#提出Issues" class="headerlink" title="提出Issues"></a>提出Issues</h3><p>点击到库中的issue里,可以添加一个New Issues去对库中某个地方提出问题,此时该issue会带有一个编号 #xxx</p><h3 id="解决Issues"><a href="#解决Issues" class="headerlink" title="解决Issues"></a>解决Issues</h3><p>点击到库中的issue里,右边可以处理你对该issue的设置,同时你下一次解决issue的时候,可以带上 #xxx 代表你解决的是该issue。</p><h2 id="Pull-Request"><a href="#Pull-Request" class="headerlink" title="Pull Request"></a>Pull Request</h2><p>PR相当于你自己去解决别人的代码问题</p><h3 id="提出PR"><a href="#提出PR" class="headerlink" title="提出PR"></a>提出PR</h3><ul><li>点击你想要PR的仓库中的fork,创建一个新仓库用于修改代码。</li><li>将项目clone到你的新仓库,并且remote到你想要PR的仓库。</li><li>修改,完成后回到你想要PR的仓库页面,点击PR,可以看到有请求可以合并你的仓库到你想要PR的仓库上。</li><li>如果还需要进行后续代码编写,本地仓库有两个分支,不能直接删除,需要先Pull才能删除。</li></ul><h3 id="解决PR"><a href="#解决PR" class="headerlink" title="解决PR"></a>解决PR</h3><ul><li>Issues和PR同用 # 代表问题。</li><li>当收到PR,没问题时,点击merge即可合并。</li><li>合并后删除刚刚新增的分支。</li><li>回到工作区(文件夹),拉取(Pull)新的文件下来到工作区。</li></ul><h2 id="Tag-amp-Release"><a href="#Tag-amp-Release" class="headerlink" title="Tag & Release"></a>Tag & Release</h2><figure class="highlight bash"><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><code class="hljs bash">//查看tag<br>git tag<br>//增加版本号<br>git tag -a v1.0.0 -m <span class="hljs-string">"消息"</span><br>//上传tag<br>git push --tags<br></code></pre></td></tr></table></figure><p>Release 可以直接选择 Tag 发行版本。</p><h2 id="Actions"><a href="#Actions" class="headerlink" title="Actions"></a>Actions</h2><p>Github Action 就是 “什么时候” + “干什么事情” ,自动化工作流。</p><h3 id="初始化-1"><a href="#初始化-1" class="headerlink" title="初始化"></a>初始化</h3><p>在根目录创建<code>.github</code>文件夹,再在此文件夹下创建<code>workflows</code>文件夹,再在此文件夹下创建<code>xxx.yml</code>就会自动开启actions。</p><h3 id="工作流-amp-项目打包部署"><a href="#工作流-amp-项目打包部署" class="headerlink" title="工作流 & 项目打包部署"></a>工作流 & 项目打包部署</h3><p>在<code>xxx.yml</code>文件中写如下自动打包示例代码:</p><figure class="highlight yml"><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><code class="hljs yml"><span class="hljs-attr">name:</span> <span class="hljs-string">打包</span><br><br><span class="hljs-attr">on:</span> <span class="hljs-string">push</span><br><br><span class="hljs-attr">jobs:</span><br><span class="hljs-attr">npm-build:</span><br><span class="hljs-attr">name:</span> <span class="hljs-string">打包</span><br><span class="hljs-attr">runs-on:</span> <span class="hljs-string">windows-latest</span><br><br><span class="hljs-attr">steps:</span><br><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">读取仓库</span><br> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span><br> <br><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">安装依赖</span><br> <span class="hljs-attr">run:</span> <span class="hljs-string">npm</span> <span class="hljs-string">install</span><br> <br><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">打包操作</span><br> <span class="hljs-attr">run:</span> <span class="hljs-string">npm</span> <span class="hljs-string">run</span> <span class="hljs-string">build</span><br></code></pre></td></tr></table></figure><p>即可运行。</p><blockquote><p> 还没学过yml,看起来和脚本差不多的感觉诶。</p></blockquote><p>上面是为了理解,一般使用 New workflow 用模板创建。</p><p>需要部署时:</p><p><code>xxx.yml</code>内容改为:</p><figure class="highlight yml"><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><code class="hljs yml"><span class="hljs-attr">name:</span> <span class="hljs-string">打包</span><br><br><span class="hljs-attr">on:</span> <span class="hljs-string">push</span><br><br><span class="hljs-attr">jobs:</span><br><span class="hljs-attr">npm-build:</span><br><span class="hljs-attr">name:</span> <span class="hljs-string">打包</span><br><span class="hljs-attr">runs-on:</span> <span class="hljs-string">windows-latest</span><br><br><span class="hljs-attr">steps:</span><br><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">读取仓库</span><br> <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span><br> <br><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">安装依赖&打包操作</span><br> <span class="hljs-attr">run:</span> <br> <span class="hljs-string">npm</span> <span class="hljs-string">install</span><br> <span class="hljs-string">npm</span> <span class="hljs-string">run</span> <span class="hljs-string">build</span><br> <br><span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">部署</span><br> <span class="hljs-attr">uses:</span> <span class="hljs-string">JamesIves/github-pages-deploy-action@v4</span><br> <span class="hljs-attr">witch:</span><br> <span class="hljs-string">//deploy是部署分支</span><br> <span class="hljs-attr">branch:</span> <span class="hljs-string">deploy</span><br> <span class="hljs-string">//dist是打包文件夹</span><br> <span class="hljs-attr">folder:</span> <span class="hljs-string">dist</span><br></code></pre></td></tr></table></figure><p>然后找到仓库设置 左侧的page Build and deployment 下Branch选择 deploy 点击 save。</p><h3 id="Docker-amp-secrets"><a href="#Docker-amp-secrets" class="headerlink" title="Docker & secrets"></a>Docker & secrets</h3><blockquote><p>还没学过Docker,但是知道Docker可以打包程序和运行环境,先标记。</p></blockquote><p>生成Docker镜像并推送到Docker仓库里。</p><ul><li>先在根目录下创建一个<code>Dockerfile</code>,写一些创建镜像的基本操作。</li><li>在仓库设置 Secrets and variables 中 Actions下可以设置Repository secrets。</li><li>可以在<code>Dockerfile</code>文件中使用 <code>${{ secrets.name }} </code>和 <code>${{ secrets.name }}</code> 放账号密码。</li></ul>]]></content>
<categories>
<category>工具使用</category>
</categories>
<tags>
<tag>工具</tag>
<tag>迁移</tag>
</tags>
</entry>
<entry>
<title>Hexo</title>
<link href="/2023/06/06/Hexo/"/>
<url>/2023/06/06/Hexo/</url>
<content type="html"><![CDATA[<h1 id="Hexo"><a href="#Hexo" class="headerlink" title="Hexo"></a><a href="https://hexo.io/zh-cn/">Hexo</a></h1><p>使用hexo搭建一个属于自己的Blog非常快捷,对于有web基础的同学可以1~2h内完成搭建并熟练使用。</p><h2 id="Install"><a href="#Install" class="headerlink" title="Install"></a>Install</h2><p>建立一个存放blog的文件夹,然后使用以下指令进行全局安装。(使用cmd并定位到该目录下)</p><figure class="highlight avrasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs avrasm">$ npm install -g hexo-<span class="hljs-keyword">cli</span><br></code></pre></td></tr></table></figure><p>安装 Hexo 完成后,执行下列命令,Hexo 将会在指定文件夹中新建所需要的文件。(<folder>是文件夹的名称,用于后续工作)</p><figure class="highlight powershell"><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><code class="hljs powershell"><span class="hljs-variable">$</span> hexo init <folder><br><span class="hljs-variable">$</span> <span class="hljs-built_in">cd</span> <folder><br><span class="hljs-variable">$</span> npm install<br></code></pre></td></tr></table></figure><h2 id="Basic"><a href="#Basic" class="headerlink" title="Basic"></a>Basic</h2><p>如果有部署网站,所有操作之后需要执行</p><figure class="highlight crystal"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs crystal"><span class="hljs-variable">$ </span>hexo g<br><span class="hljs-variable">$ </span>hexo deploy<br></code></pre></td></tr></table></figure><p>上传 <strong>笔记</strong></p><h3 id="New"><a href="#New" class="headerlink" title="New"></a>New</h3><p>可以在目标文件夹执行下列命令来创造一幢新的 <strong>笔记</strong> 。</p><figure class="highlight gauss"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs gauss">$ hexo <span class="hljs-keyword">new</span> [layout] <<span class="hljs-built_in">title</span>><br></code></pre></td></tr></table></figure><p>其中 <strong>layout</strong> 是笔记的类型,有 <strong>post</strong> 、 <strong>page</strong> 、 <strong>draft</strong></p><p>一般只使用且默认是 <strong>post</strong> 。</p><p>建立后在在source/_post中修改markdown即可。</p><p><strong>笔记</strong> 创建后有以下配置项,可以参考修改。</p><table><thead><tr><th align="left">参数</th><th align="left">描述</th><th align="left">默认值</th></tr></thead><tbody><tr><td align="left"><code>layout</code></td><td align="left">布局</td><td align="left"><a href="https://hexo.io/zh-cn/docs/configuration#%E6%96%87%E7%AB%A0"><code>config.default_layout</code></a></td></tr><tr><td align="left"><code>title</code></td><td align="left">标题</td><td align="left">文章的文件名</td></tr><tr><td align="left"><code>date</code></td><td align="left">建立日期</td><td align="left">文件建立日期</td></tr><tr><td align="left"><code>updated</code></td><td align="left">更新日期</td><td align="left">文件更新日期</td></tr><tr><td align="left"><code>comments</code></td><td align="left">开启文章的评论功能</td><td align="left">true</td></tr><tr><td align="left"><code>tags</code></td><td align="left">标签(不适用于分页)</td><td align="left"></td></tr><tr><td align="left"><code>categories</code></td><td align="left">分类(不适用于分页)</td><td align="left"></td></tr><tr><td align="left"><code>permalink</code></td><td align="left">覆盖文章的永久链接,永久链接应该以 <code>/</code> 或 <code>.html</code> 结尾</td><td align="left"><code>null</code></td></tr><tr><td align="left"><code>excerpt</code></td><td align="left">纯文本的页面摘要。使用 <a href="https://hexo.io/zh-cn/docs/tag-plugins#%E6%96%87%E7%AB%A0%E6%91%98%E8%A6%81%E5%92%8C%E6%88%AA%E6%96%AD">该插件</a> 来格式化文本</td><td align="left"></td></tr><tr><td align="left"><code>disableNunjucks</code></td><td align="left">启用时禁用 Nunjucks 标签 <code>{{ }}</code>/<code>{% %}</code> 和 <a href="https://hexo.io/zh-cn/docs/tag-plugins">标签插件</a> 的渲染功能</td><td align="left">false</td></tr><tr><td align="left"><code>lang</code></td><td align="left">设置语言以覆盖 <a href="https://hexo.io/zh-cn/docs/internationalization#%E8%B7%AF%E5%BE%84">自动检测</a></td><td align="left">继承自 <code>_config.yml</code></td></tr></tbody></table><h3 id="Delete-amp-Change"><a href="#Delete-amp-Change" class="headerlink" title="Delete&Change"></a>Delete&Change</h3><p>直接在source/_post中修改/删除markdown即可</p><p>删除之后输入一次以下命令</p><figure class="highlight crystal"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs crystal"><span class="hljs-variable">$ </span>hexo clean<br></code></pre></td></tr></table></figure><h2 id="LocalHost"><a href="#LocalHost" class="headerlink" title="LocalHost"></a>LocalHost</h2><p>在搭建有关 笔记 后,需要进行展示</p><p>先生成静态文件(每次更新 <strong>笔记</strong> 时都需要此步,便于页面部署,类似于vue中的dist)</p><figure class="highlight crystal"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs crystal"><span class="hljs-variable">$ </span>hexo g<br></code></pre></td></tr></table></figure><p>在本地使用服务器展示使用如下指令即可:</p><figure class="highlight axapta"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs axapta">$ hexo <span class="hljs-keyword">server</span><br></code></pre></td></tr></table></figure><p>接着就可以在网址为 <a href="http://localhost:4000/">http://localhost:4000/</a> 访问到</p><h1 id="Config"><a href="#Config" class="headerlink" title="Config"></a>Config</h1><p>Hexo中用户可修改的配置放在 <code>_config.yml</code> 文件中,可根据官网描述修改。</p><p>其中基础使用需要修改的项目有 </p><ul><li>title、author、language (用户信息)</li><li>theme (自定义主题)</li><li>deploy (简易部署)</li></ul><h2 id="Themes"><a href="#Themes" class="headerlink" title="Themes"></a><a href="https://hexo.io/themes/">Themes</a></h2><p>在上述网站中可以寻找自己喜欢的主题,点击大图可以预览,点击蓝字可以进入该作者的仓库。</p><p>在<strong>hexo</strong>目录下的<strong>themes</strong>文件夹下打开<strong>git bash</strong>,输入以下命令,下载主题:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">git clone 复制主题的网址<br></code></pre></td></tr></table></figure><p>配置<code>_config.yml</code>文件 修改theme 改为主题的名字</p><p>在hexo目录下,打开git bash,输入以下命令,清除缓存,生成静态文件,查看效果</p><figure class="highlight text"><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><code class="hljs text">hexo clean<br>hexo g<br>hexo s<br></code></pre></td></tr></table></figure><h2 id="Deploy"><a href="#Deploy" class="headerlink" title="Deploy"></a>Deploy</h2><table><thead><tr><th align="left">参数</th><th align="left">描述</th><th align="left">默认</th></tr></thead><tbody><tr><td align="left"><code>repo</code></td><td align="left">库(Repository)地址</td><td align="left"></td></tr><tr><td align="left"><code>branch</code></td><td align="left">分支名称</td><td align="left"><code>gh-pages</code> (GitHub) <code>coding-pages</code> (Coding.net) <code>master</code> (others)</td></tr><tr><td align="left"><code>message</code></td><td align="left">自定义提交信息</td><td align="left"><code>Site updated: {{ now('YYYY-MM-DD HH:mm:ss') }}</code>)</td></tr><tr><td align="left"><code>token</code></td><td align="left">可选的令牌值,用于认证 repo。用 <code>$</code> 作为前缀从而从环境变量中读取令牌</td><td align="left"></td></tr></tbody></table><h2 id="Index-generator"><a href="#Index-generator" class="headerlink" title="Index_generator"></a>Index_generator</h2><p>需要修改每一页的笔记数量可以从<code>per_page</code>中修改。</p><p>需要修改排序顺序可以从<code>order_by</code>中修改,默认<code>-data</code>即日期的倒序,可以修改成其他配置项例如<code>-updated</code>即修改日期的倒序。</p><h1 id="Deployment"><a href="#Deployment" class="headerlink" title="Deployment"></a>Deployment</h1><h2 id="Git-Page"><a href="#Git-Page" class="headerlink" title="Git Page"></a>Git Page</h2><p>页面托管可以使用github,完美符合静态Blog的需求。</p><p>在 <strong>仓库Repositories</strong> 中新建一个 <strong>仓库</strong> ,名称为 <strong>你的githubID.github.io</strong> 点击创建。</p><p>接着在创建的文件夹的子文件夹public中使用git连接该仓库,push所有的文件。</p><p>等待几分钟页面部署,即可在 <strong>https://你的githubID.github.io</strong> 中访问到。</p><p>为了方便 <strong>笔记</strong> 搭建修改 需要在目标文件夹中运行以下命令</p><figure class="highlight ada"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ada">$ npm install hexo-deployer-git <span class="hljs-comment">--save</span><br></code></pre></td></tr></table></figure><p>在配置文件<code>_config.yml</code>中更改</p><figure class="highlight dts"><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><code class="hljs dts"><span class="hljs-symbol">deploy:</span><br><span class="hljs-symbol"> type:</span> git<br><span class="hljs-symbol"> repo:</span> <span class="hljs-params"><repository url></span> <span class="hljs-meta">#https:<span class="hljs-comment">//github.com/TaskManagerOL/TaskManagerOL.github.io</span></span><br><span class="hljs-symbol"> branch:</span> [branch]<br><span class="hljs-symbol"> message:</span> [message]<br></code></pre></td></tr></table></figure><p>完成配置后每次只需执行</p><figure class="highlight crystal"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs crystal"><span class="hljs-variable">$ </span>hexo g<br><span class="hljs-variable">$ </span>hexo d<br></code></pre></td></tr></table></figure><p>即可快速上传文件</p>]]></content>
<categories>
<category>工具使用</category>
</categories>
<tags>
<tag>工具</tag>
<tag>速通</tag>
</tags>
</entry>
</search>