-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.json
1 lines (1 loc) · 75.3 KB
/
search.json
1
[{"title":"宏观任务与微观任务","url":"http://yoursite.com/2020/06/17/evevt-loop/","content":"<blockquote>\n<p>一段javascript代码放在javascript引擎中如何去运行,为什么有段代码明明写在前面执行顺序却到了后面,这可能就要稍微需要理解到javascript的执行。</p>\n</blockquote>\n<h2 id=\"微观任务与宏观任务\"><a href=\"#微观任务与宏观任务\" class=\"headerlink\" title=\"微观任务与宏观任务\"></a>微观任务与宏观任务</h2><p>简单来说,我们将宿主环境(一般是指浏览器)发起的的任务称为宏观任务,将JavaScript引擎发起的任务称为微观任务。</p>\n<p>在宏观任务中,Promise还会产生异步代码,JavaScript必须保证这些异步代码在一个宏观任务中完成,所以,每个宏观任务还会包含若干个微观任务。</p>\n<figure class=\"highlight javascript\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> a = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">\"a\"</span>)</span><br><span class=\"line\"> resolve()</span><br><span class=\"line\">})</span><br><span class=\"line\">a.then(<span class=\"function\"><span class=\"params\">()</span> =></span> <span class=\"built_in\">console</span>.log(<span class=\"string\">\"c\"</span>))</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">\"b\"</span>)</span><br></pre></td></tr></table></figure>\n\n<p>上面那段代码,由于promise的resolve是一个异步机制,所以c会在b之后打印出来。</p>\n<p>接下来试试使用setTimeout</p>\n<figure class=\"highlight javascript\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> a = <span class=\"keyword\">new</span> <span class=\"built_in\">Promise</span>(<span class=\"function\">(<span class=\"params\">resolve, reject</span>) =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">console</span>.log(<span class=\"string\">\"a\"</span>)</span><br><span class=\"line\"> resolve()</span><br><span class=\"line\">})</span><br><span class=\"line\">setTimeout(<span class=\"function\"><span class=\"params\">()</span> =></span> <span class=\"built_in\">console</span>.log(<span class=\"string\">\"d\"</span>), <span class=\"number\">0</span>)</span><br><span class=\"line\">a.then(<span class=\"function\"><span class=\"params\">()</span> =></span> <span class=\"built_in\">console</span>.log(<span class=\"string\">\"c\"</span>))</span><br><span class=\"line\"><span class=\"built_in\">console</span>.log(<span class=\"string\">\"b\"</span>)</span><br></pre></td></tr></table></figure>\n\n<p>无论代码顺序如何,d都会在最后被打印出,这是因为setTimeout属于浏览器的API,属于宏观任务,<code>而微观任务一直优先于宏观任务</code>。</p>\n","categories":["技术"],"tags":["前端","javascript"]},{"title":"grid布局","url":"http://yoursite.com/2020/05/05/grid/","content":"<blockquote>\n<p>很久没想起来写博客了,最近因为某款游戏在写这个游戏的攻略小程序,前端表格就是用grid布局做的,趁热记录一下grid布局。</p>\n</blockquote>\n<h2 id=\"1-display\"><a href=\"#1-display\" class=\"headerlink\" title=\"1.display\"></a>1.display</h2><p>grid据说是css最强大的布局,但是个人在项目中挺少运用到,基本上flex能解决大部分。</p>\n<p>使一个容器变成grid布局</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid | inline-grid;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<ul>\n<li>grid 容器元素为块级元素</li>\n<li>inline-grid 容器元素为行内元素</li>\n</ul>\n<p>注:<br>float,display: inline-block,display: table-cell,vertical-align和column-* 属性在设置grid后会失效。</p>\n<h2 id=\"2-grid-template-columns-grid-template-rows-grid-template-area\"><a href=\"#2-grid-template-columns-grid-template-rows-grid-template-area\" class=\"headerlink\" title=\"2.grid-template-columns/grid-template-rows/grid-template-area\"></a>2.grid-template-columns/grid-template-rows/grid-template-area</h2><p>grid是由行和列组成的栅格,columns定义行,row定义列</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">40px</span> <span class=\"number\">50px</span> auto <span class=\"number\">50px</span> <span class=\"number\">40px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"number\">25%</span> <span class=\"number\">100px</span> auto;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>效果如下</p>\n<p><img src=\"http://static.cangyuanyuan.com/grid-1.png\" alt=\"效果图1\"></p>\n<p>同时也能命名行或列(网格线)</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: [first] <span class=\"number\">40px</span> [line2] <span class=\"number\">50px</span> [line3] auto [col4-start] <span class=\"number\">50px</span> [five] <span class=\"number\">40px</span> [end];</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: [row1-start] <span class=\"number\">25%</span> [row1-end] <span class=\"number\">100px</span> [third-line] auto [last-line];</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p><img src=\"http://static.cangyuanyuan.com/grid-2.png\" alt=\"效果图2\"></p>\n<p>每行或每列允许有多个名称,比如下列代码第二行就设定了两个名称</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: [row1-start] <span class=\"number\">25%</span> [row1-end row2-start] <span class=\"number\">25%</span> [row2-end];</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>如果定义中出现重复的部分,可以用repeat()简化代码,repeat接受的第一个参数是重复次数,第二个是重复内容,下面代码中两个css效果是相同的</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"built_in\">repeat</span>(3, 20px [col-start]);</span><br><span class=\"line\">}</span><br><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">20px</span> [col-start] <span class=\"number\">20px</span> [col-start] <span class=\"number\">20px</span> [col-start];</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>fr可以划分行列之间的比例,比如将一个容器平均分成3分,可以这样写</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">1</span>fr <span class=\"number\">1</span>fr <span class=\"number\">1</span>fr;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>fr搭配像素值,就意味着所有fr比例不得超过像素值,比如下面代码fr的比例是以50px为总量划分</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">1</span>fr <span class=\"number\">50px</span> <span class=\"number\">1</span>fr <span class=\"number\">1</span>fr;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>minmax()会接受两个参数,第一个为单元格最小值,第二个为最大值,这些值还可以为auto。</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"built_in\">minmax</span>(100px, auto);</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>grid-template-area可以划分区域</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: grid;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-areas</span>: <span class=\"string\">\"header header\"</span></span><br><span class=\"line\"> <span class=\"string\">\"content sidebar\"</span></span><br><span class=\"line\"> <span class=\"string\">\"footer footer\"</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-rows</span>: <span class=\"number\">150px</span> <span class=\"number\">1</span>fr <span class=\"number\">100px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-template-columns</span>: <span class=\"number\">1</span>fr <span class=\"number\">200px</span>;</span><br></pre></td></tr></table></figure>\n\n<p>上述代码就是一个布局实例,生成一个3行2列的网格,顶部header,页脚footer,中间左边内容右边侧边栏,如果某些区域不会用到,则可以用<code>.</code>来表示。</p>\n<p><img src=\"http://static.cangyuanyuan.com/grid-6.png\" alt=\"效果图3\"></p>\n<h1 id=\"3-column-gap-row-gap\"><a href=\"#3-column-gap-row-gap\" class=\"headerlink\" title=\"3.column-gap/row-gap\"></a>3.column-gap/row-gap</h1><p>使用column-gap和row-gap属性来创建列和行之间的间距,间距大小任意非负</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">row-gap</span>: <span class=\"number\">20px</span>;</span><br><span class=\"line\"> <span class=\"attribute\">column-gap</span>: <span class=\"number\">5rem</span>;</span><br></pre></td></tr></table></figure>\n\n<p>上面样式还可以用<code>gap</code>来简写,如果指定两个值则第一个表示row-gap,第二个表示column-gap,如果忽略第二个值,则第一个值同时表示行间距与列间距</p>\n<h2 id=\"4-项目属性\"><a href=\"#4-项目属性\" class=\"headerlink\" title=\"4.项目属性\"></a>4.项目属性</h2><figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item1</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-row-start</span>: <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-row-end</span>: <span class=\"number\">3</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-start</span>: <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-end</span>: <span class=\"number\">3</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>以上四个属性分别意味着网格从第二行到第三行、第二列到第三列所定位的项目1</p>\n<p><img src=\"http://static.cangyuanyuan.com/grid-3.png\" alt=\"项目属性1\"></p>\n<p>当然可以简写,使用/来表示从第几行(列)到第几行(列),如果省略了/,则默认跨越1个网格单位</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item1</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-row</span>: <span class=\"number\">2</span>;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column</span>: <span class=\"number\">3</span> / <span class=\"number\">4</span>;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p><img src=\"http://static.cangyuanyuan.com/grid-4.png\" alt=\"项目属性2\"></p>\n<p>更简单的可以使用grid-area,指定四个值分别对应<code>grid-row-start</code>,<code>grid-column-start</code>,<code>grid-row-end</code>,<code>grid-column-end</code></p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item1</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-area</span>: <span class=\"number\">2</span> / <span class=\"number\">2</span> / <span class=\"number\">3</span> / <span class=\"number\">3</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>如果你在定义表格的样式里就给网格线取名,则还能用网格线的名称来定位到项目,例如</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item1</span> {</span><br><span class=\"line\"> <span class=\"attribute\">grid-row-start</span>: row-<span class=\"number\">2</span>-start;</span><br><span class=\"line\"> <span class=\"attribute\">grid-row-end</span>: row-end;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-start</span>: col-<span class=\"number\">2</span>-start;</span><br><span class=\"line\"> <span class=\"attribute\">grid-column-end</span>: col-end;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p><img src=\"http://static.cangyuanyuan.com/grid-5.png\" alt=\"项目属性3\"></p>\n<h2 id=\"5-justify-content-align-content\"><a href=\"#5-justify-content-align-content\" class=\"headerlink\" title=\"5.justify-content/align-content\"></a>5.justify-content/align-content</h2><p>与flex相似<br>justify-content:内容区域在容器中的水平位置<br>align-content:内容区域在容器中的垂直位置</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">justify-content</span>: start | end | center | stretch | space-around | space-between | space-evenly;</span><br><span class=\"line\"> <span class=\"attribute\">align-content</span>: start | end | center | stretch | space-around | space-between | space-evenly; </span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p><code>start: 居前</code></p>\n<p><img src=\"http://static.cangyuanyuan.com/grid-start.png\" alt=\"start\"></p>\n<p><code>end: 居后</code></p>\n<p><img src=\"http://static.cangyuanyuan.com/grid-end.png\" alt=\"end\"></p>\n<p><code>center: 居中</code><br><img src=\"http://static.cangyuanyuan.com/grid-center.png\" alt=\"center\"></p>\n<p><code>stretch: 项目大小未指定则拉伸整个容器</code></p>\n<p><img src=\"http://static.cangyuanyuan.com/grid-stretch.png\" alt=\"stretch\"></p>\n<p><code>space-around: 每个项目两侧的间隔相同,则项目之间的间隔会比邻侧多一倍</code></p>\n<p><img src=\"http://static.cangyuanyuan.com/grid-space-around.png\" alt=\"space-around\"></p>\n<p><code>space-between: 项目之间间隔相同,但与邻边无间隔</code><br><img src=\"http://static.cangyuanyuan.com/grid-space-between.png\" alt=\"space-between\"></p>\n<p><code>space-evenly: 项目与项目之间间隔相同,与邻边之间间隔也相同</code><br><img src=\"http://static.cangyuanyuan.com/grid-space-evenly.png\" alt=\"space-evenly\"></p>\n<h2 id=\"6-justify-self-align-self\"><a href=\"#6-justify-self-align-self\" class=\"headerlink\" title=\"6.justify-self/align-self\"></a>6.justify-self/align-self</h2><p>justify-self与align-self是项目中的内容的位置方向,与justify-content和align-self使用方法一致。</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">justify-self</span>: start | end | center | stretch;</span><br><span class=\"line\"> <span class=\"attribute\">align-self</span>: start | end | center | stretch;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<h2 id=\"7-后记\"><a href=\"#7-后记\" class=\"headerlink\" title=\"7.后记\"></a>7.后记</h2><p>本文参考来源<a href=\"http://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html\" target=\"_blank\" rel=\"noopener\">阮一峰的博客</a>和<a href=\"https://learncssgrid.com/\" target=\"_blank\" rel=\"noopener\">Learn CSS Grid</a>这篇文章。</p>\n<p>关于css的博客可能就告一段落,作为一个前端,还有很长的路要走。</p>\n","categories":["技术"],"tags":["前端","css"]},{"title":"2019-2020","url":"http://yoursite.com/2020/01/01/happy-new-year/","content":"<blockquote>\n<p>最近在读三体,宇宙观变得宏大的同时感觉到自己作为渺小的人类中渺小的一员是多么的微不足道,一年看似很长,但在宇宙单位的角度稍瞬即逝,一个人的人生也是宇宙中的匆匆过客,又跳又闹也折腾不出多大动静,最后就像一滴水滴进大海化作时代的洪流。</p>\n</blockquote>\n<h1 id=\"2019总结\"><a href=\"#2019总结\" class=\"headerlink\" title=\"2019总结\"></a>2019总结</h1><p>说起总结,也就是现在坐在电脑前能回忆起来的重要的事情吧。</p>\n<ol>\n<li>年初旅行</li>\n</ol>\n<p>第一次去日本,对这个动漫游戏产业发达的国度充满了期待,去了之后发现自己这么多年看日剧动漫学的日语实际用起来还是渣,语速一快还是听不懂,但是还是能大部分无障碍的体验到秋叶原,圣地巡礼,美食,海贼王主题乐园等日本特色。由于是过年放假时去的,来回机票就要5000,挺心疼的,感觉自己再也不会在机票不打折的情况下出去玩儿了。</p>\n<ol start=\"2\">\n<li>游戏</li>\n</ol>\n<p>玩的令人印象深刻的单机游戏是pc端的<code>只狼</code>和ns上面的<code>异度之刃2</code>,手游是火焰纹章英雄(国区没有,借的朋友的日区apple store账号下载的)和明日方舟,网游的话虽然不怎么玩但是因为魔兽世界怀旧服开了,也跟着玩了挺久的,虽然最后也没有到满级吧。<br>手游和网游都是非常耗时间的,以后不打算沾了,19年也在这类游戏上花费了大量的时间,挺后悔的。相比之下单机游戏都挺精良的,只狼还获得的tga今年最佳。</p>\n<ol start=\"3\">\n<li>书</li>\n</ol>\n<p>本来个人非常喜欢纸质书的,但是自从接触了微信读书这个软件,读书就变得停不下来的。不过最重要的是移动端读书能合理消耗掉大部分碎片化时间,比如上下班的地铁、公交车中,这样一年攒下来的时间是不可估量的,但是用手机读技术书还是算了吧。</p>\n<ol start=\"4\">\n<li>技术</li>\n</ol>\n<p>19年最大的变化就是从后端到前端的转变,工作内容由以前的web、爬虫转变到小程序,h5,技术栈也增加了taro、react等,如果没有变化的话还是会继续走前端的道路。</p>\n<ol start=\"5\">\n<li>消费</li>\n</ol>\n<p>旅行总花费1w1,19年分期买了台mac pro花了1w6,种了颗牙花了1w3,年末的时候去皮肤科检查了脱发的症状(程序员的痛苦),估计也要走上植发的道路,预计至少2w。除了这些和衣食住行,想不起来别的大额消费了。</p>\n<ol start=\"6\">\n<li>其他</li>\n</ol>\n<p>换了工作也搬了家,厌食症感觉没了,胃口挺好,体重也增到了83kg,但是鼻子遇热就流血的问题还没看,以前检查过一次是鼻窦膜破裂,打算20年在北京深度检查一下,毕竟身体是最要紧的。</p>\n<h1 id=\"2020计划\"><a href=\"#2020计划\" class=\"headerlink\" title=\"2020计划\"></a>2020计划</h1><p>尽可能的把目标定的低一点,然后多一些,慢慢的不着急的一点点完成。</p>\n<ul>\n<li>体重上来后就要健身,健身环(ns上游戏)游戏时长达到200小时</li>\n<li>买台pad作为学习和娱乐工具(等mac分期还完</li>\n<li>读完20本书(目前微信读书已读完5本,阅读时间44小时</li>\n<li>读完一本技术书</li>\n<li>可能的话出去旅游一次(不做硬性要求</li>\n<li>b站投一份稿(找找以前当up的感觉</li>\n<li>开发一款小程序</li>\n<li>学习日语过了n2</li>\n</ul>\n<p>上面目标难度最大的估计就是学日语过考试这个了,但这也是表明自己要下定决心的第一步。</p>\n<p>2020我来了</p>\n","categories":["随笔"],"tags":["人生规划","年终总结"]},{"title":"简洁的可选链","url":"http://yoursite.com/2019/12/22/optional-chaining/","content":"<h1 id=\"1-起因\"><a href=\"#1-起因\" class=\"headerlink\" title=\"1.起因\"></a>1.起因</h1><p>以前经常遇到这种场景:反馈说小程序页面打不开,调试时发现抛出<code>TypeError: Cannot read property 'xxx' of undefined。</code>这样的错,再看接口原来是后端少返回了一层属性,于是无奈之下在原有的代码加上<code>project&&project.author&&project.author.name</code>诸如此类的判断。</p>\n<p>直到发现了可选链。</p>\n<h1 id=\"2-可选链的使用\"><a href=\"#2-可选链的使用\" class=\"headerlink\" title=\"2.可选链的使用\"></a>2.可选链的使用</h1><p>可选链使代码更加简介,上述判断代码替换成可选链为<code>project?.author?.name</code>,很好的预防抛出错误导致页面打不开的问题。</p>\n<p>不但可以运用在对象属性中,数组也可以运用,<code>project?.author?.[0]?.name</code>,这样可以很好的预防没有author以及author数组中第一个不存在的错误,可以代替<code>author.length > 0</code>这样的判断来保证下标0不会抛出错误。</p>\n<h1 id=\"3-双问号\"><a href=\"#3-双问号\" class=\"headerlink\" title=\"3.双问号\"></a>3.双问号</h1><p>双问号可以将为undefined或者null的变量设置默认值,例如<code>author ?? 'Harry'</code>,如果author为undefined或者null,则author为’Harry’,有种<code>||</code>的逻辑运算符感觉,但不支持false和0,和可选链搭配比较合适,例如<code>author?.name ?? 'Harry'</code>,如果前者为undefined或者null则返回Harry。</p>\n<h1 id=\"4-属性\"><a href=\"#4-属性\" class=\"headerlink\" title=\"4.属性\"></a>4.属性</h1><p>可选链有一些属性,比如</p>\n<p><strong>短路</strong>: 即可选链提前返回时,后面则不会执行</p>\n<figure class=\"highlight javascript\"><table><tr><td class=\"code\"><pre><span class=\"line\">project?.author?.add(++age)</span><br></pre></td></tr></table></figure>\n\n<p>如果作者不存在,则年龄不会增加</p>\n<p><strong>堆叠</strong>: 一条语句可以使用多个可选链</p>\n<figure class=\"highlight javascript\"><table><tr><td class=\"code\"><pre><span class=\"line\">project?.author?.name?.[<span class=\"number\">0</span>]?.first_name</span><br></pre></td></tr></table></figure>\n\n<p>可选链不鼓励多项堆叠,如果一个属性确保存在的话就不应该使用可选链</p>\n<p><strong>可选删除</strong>: 可以和delete一起用来删除属性,如果属性存在</p>\n<figure class=\"highlight javascript\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">delete</span> project?.author</span><br></pre></td></tr></table></figure>\n\n<h1 id=\"5-感想\"><a href=\"#5-感想\" class=\"headerlink\" title=\"5.感想\"></a>5.感想</h1><p>有了可选链之后,再也不怕后端返回空数据了,哇哈哈。</p>\n","categories":["技术"],"tags":["前端","javascript"]},{"title":"感觉已经脱离中二的年纪了-观新海诚新作天气之子有感","url":"http://yoursite.com/2019/11/03/weathering-with-you/","content":"<p>新海诚的天气之子11.1在国内上映,自打这部作品在日本上映就有种冲动想要漂洋过海去日本看这场电影,再加上作为新海诚的一代老粉,自然不容错过,于是赶着首映日一下班就和同事一起去看了。</p>\n<p>通篇电影看下来,首先画面是一如既往的新海诚风格,那天、那水、那光,画面美的只能惊叹,词匮的我无法用言语来形容,真是随便截一帧都能当桌面,作画方面真是无可挑剔。</p>\n<p><img src=\"http://static.cangyuanyuan.com/weather1.jpg\" alt=\"weather\"></p>\n<p>作画团队使用的是你的名字的原班人马,不仅作品,配乐也是延续了前作与RADWIMPS乐队合作。</p>\n<p><img src=\"http://static.cangyuanyuan.com/Screen%20Shot%202019-11-03%20at%201.32.57%20AM.png\" alt=\"weather2\"></p>\n<p>不得不提,电影院这一幕时的背景音乐燃出了我的鸡皮疙瘩,很会煽动带起人的情绪,所以在配乐方面我也非常满意。</p>\n<p>但是,这作的故事,我看下来觉得非常的不舒服,不是那种意犹未尽结束时还沉浸在剧情中的感觉,而是满大街的槽点我该先吐哪个的感觉。</p>\n<p>故事大概讲述的是男主离家出走到东京邂逅能改变天气的女主,但是想要结束掉东京阴雨不断的代价就是要牺牲掉作为天气之子的女主,最后男主拯救女主导致东京再也没见过太阳。</p>\n<p>这个故事从大纲上来看是没什么问题的,哪怕饱受争议的结局,男主为了爱情而不去拯救东京我都能理解,是情有可原的,毕竟雨也不是他们造成的,如果让我来选当然也会选择女主啦,毕竟那么可爱。这个世界本来就是疯狂的,结局不停隐喻为了减轻男主的负罪感,但我真是觉得这种负罪感没必要,男主为什么要拯救这个对待自己如此冷酷而又现实的东京社会,仅仅是为了跟随所谓的正确的价值观导向?我至少觉得救女主这个结局没毛病,甚至很棒!</p>\n<p><img src=\"http://static.cangyuanyuan.com/weather3.jpg\" alt=\"weather3\"></p>\n<p>大纲是不错,但是诚哥讲故事的功底太差还是暴露出来了,故事线混乱,逻辑漏洞多,还充斥着中二气息,看的我十分尴尬。</p>\n<p>故事上设定相关的我就不提了,关于天气之子的设定、东京连续不断大雨的设定,这些诚哥究竟要告诉我们什么,又要表达什么,我不是专业的影评人,也没有过强对此方面的理解。我能感觉到的是,片子进入后半段,就开始扯起来了,从警察找上女主的门问男主开始,到逃跑打雷炸汽车,到警察局能让一个小孩子跑掉,到男主在铁轨上奔跑着不停喊着女主,到楼里的持枪大乱斗,这一连串的场景我带着满脸的问号看下去的,然后发出一声感慨,真够中二的啊。</p>\n<p>显然我已经过了这个中二的年纪了,看这些情节会头皮发麻,浑身膈应。后来我问了自己一个问题,如果这些情节出现在国漫里,我的态度是怎样的,想想大鱼海棠那个天神的爱,我就知道我不能双标的看待这个剧情,不能因为放在新海诚的电影中就理所当然的接受了它,既然你把故事讲成这样,我就会不留余力的吐槽吐个痛快。</p>\n<p>看了眼豆瓣评分已经跌到了7.1,但是查了下日本的票房成绩还不错,票房这么高也表示日本观众更能理解这片子的过人之处吧。</p>\n<p>相比这种对抗全世界来相爱的充满中二的爱情,我还是喜欢<code>隐约雷鸣,阴霾天空,即使天无雨,我亦留此地</code>这种唯美的爱情。</p>\n","categories":["随笔"],"tags":["新海诚,电影,观后感"]},{"title":"记录一些设计网站","url":"http://yoursite.com/2019/10/22/design-website/","content":"<blockquote>\n<p>好久都没更新博客了,罪魁祸首都是8月底开的wow怀旧服和前阵子s赛的到来,可恶。<br>最近在构思产品的时候,本着ui差就不能看,前端也要有着一颗设计的心,所以浏览了许多设计相关的网站,希望经常看其他人优秀的设计,自己的审美水平也能提高吧!(笑)</p>\n</blockquote>\n<hr>\n<h2 id=\"设计产品网站\"><a href=\"#设计产品网站\" class=\"headerlink\" title=\"设计产品网站\"></a>设计产品网站</h2><ol>\n<li><a href=\"https://sketchrepo.com/\" target=\"_blank\" rel=\"noopener\">https://sketchrepo.com/</a></li>\n</ol>\n<hr>\n<p><img src=\"http://static.cangyuanyuan.com/sketchrepo.png\" alt=\"sketchrepo\"></p>\n<ol start=\"2\">\n<li><a href=\"https://dribbble.com/\" target=\"_blank\" rel=\"noopener\">https://dribbble.com/</a></li>\n</ol>\n<hr>\n<p><img src=\"http://static.cangyuanyuan.com/dribbble.png\" alt=\"dribbble\"></p>\n<ol start=\"3\">\n<li><a href=\"https://www.uplabs.com/\" target=\"_blank\" rel=\"noopener\">https://www.uplabs.com/</a></li>\n</ol>\n<hr>\n<p><img src=\"http://static.cangyuanyuan.com/uplabs.png\" alt=\"uplabs\"></p>\n<ol start=\"4\">\n<li><a href=\"https://www.uipixels.com/\" target=\"_blank\" rel=\"noopener\">https://www.uipixels.com/</a></li>\n</ol>\n<hr>\n<p><img src=\"http://static.cangyuanyuan.com/uipixels.png\" alt=\"uipixels\"></p>\n<ol start=\"5\">\n<li><a href=\"https://www.sketchappsources.com/\" target=\"_blank\" rel=\"noopener\">https://www.sketchappsources.com/</a></li>\n</ol>\n<hr>\n<p><img src=\"http://static.cangyuanyuan.com/sketchappsources.png\" alt=\"sketchappsources\"></p>\n<h2 id=\"设计素材网站\"><a href=\"#设计素材网站\" class=\"headerlink\" title=\"设计素材网站\"></a>设计素材网站</h2><ol>\n<li><a href=\"https://unsplash.com/\" target=\"_blank\" rel=\"noopener\">https://unsplash.com/</a></li>\n</ol>\n<hr>\n<p><img src=\"http://static.cangyuanyuan.com/unsplash.png\" alt=\"unsplash\"></p>\n<ol start=\"2\">\n<li><a href=\"https://huaban.com/\" target=\"_blank\" rel=\"noopener\">花瓣网</a></li>\n</ol>\n<hr>\n<p><img src=\"http://static.cangyuanyuan.com/huaban.png\" alt=\"huaban\"></p>\n<ol start=\"3\">\n<li><a href=\"https://www.iconfont.cn/\" target=\"_blank\" rel=\"noopener\">阿里巴巴icon图标库</a></li>\n</ol>\n<hr>\n<p><img src=\"http://static.cangyuanyuan.com/iconfont.png\" alt=\"iconfont\"></p>\n<h2 id=\"调色网站\"><a href=\"#调色网站\" class=\"headerlink\" title=\"调色网站\"></a>调色网站</h2><ol>\n<li><a href=\"https://colorhunt.co/\" target=\"_blank\" rel=\"noopener\">https://colorhunt.co/</a></li>\n</ol>\n<hr>\n<p><img src=\"http://static.cangyuanyuan.com/colorhunt.png\" alt=\"colorhunt\"></p>\n<h2 id=\"设计工具\"><a href=\"#设计工具\" class=\"headerlink\" title=\"设计工具\"></a>设计工具</h2><ol>\n<li><a href=\"https://www.sketch.com/\" target=\"_blank\" rel=\"noopener\">Sketch</a></li>\n</ol>\n<ol start=\"2\">\n<li><a href=\"https://www.figma.com/\" target=\"_blank\" rel=\"noopener\">Figma</a></li>\n</ol>\n<h2 id=\"设计网站导航\"><a href=\"#设计网站导航\" class=\"headerlink\" title=\"设计网站导航\"></a>设计网站导航</h2><ol>\n<li><a href=\"http://chuangzaoshi.com/\" target=\"_blank\" rel=\"noopener\">创意师</a></li>\n</ol>\n<hr>\n<p>以上部分网站需要科学上网</p>\n","categories":["设计"],"tags":["ui设计"]},{"title":"最近买了两台云服务器","url":"http://yoursite.com/2019/08/20/create-server/","content":"<blockquote>\n<p>这两天花了近1K大洋买了两台云服务器。。。没控制住自己的手</p>\n</blockquote>\n<h2 id=\"第一台-搬瓦工\"><a href=\"#第一台-搬瓦工\" class=\"headerlink\" title=\"第一台: 搬瓦工\"></a>第一台: 搬瓦工</h2><ul>\n<li>原价49.99刀一年,折扣6%,大概46刀左右,折合330人民币</li>\n<li>用途是为了搭建ss,再具体的用途就不用我多说了吧</li>\n<li>先前vultr的实在是受够了,感觉最快的荷兰阿姆斯特丹机房的都连不上去,而且不能用ip太多了,现在账号还有8刀左右</li>\n<li>被折腾够了,买个50刀的省省心,搬瓦工的服务也是逐渐高质量+高收费化,以前19.99刀一年的日子一去不复返了</li>\n<li>搭建过程,ssh上服务器依次输下面三个命令即可,然后安装提示输入密码、端口和选择加密方式序号</li>\n</ul>\n<figure class=\"highlight plain\"><table><tr><td class=\"code\"><pre><span class=\"line\">wget — no-check-certificate -O shadowsocks.sh https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks.sh</span><br><span class=\"line\">chmod +x shadowsocks.sh</span><br><span class=\"line\">./shadowsocks.sh 2>&1 | tee shadowsocks.log</span><br></pre></td></tr></table></figure>\n\n<ul>\n<li>bbr是谷歌出品的一套tcp拥塞控制算法,能提升网速渲染速度,安装过程如下</li>\n</ul>\n<figure class=\"highlight plain\"><table><tr><td class=\"code\"><pre><span class=\"line\">wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh</span><br><span class=\"line\">chmod +x bbr.sh</span><br><span class=\"line\">./bbr.sh</span><br></pre></td></tr></table></figure>\n\n<ul>\n<li>安装好要重启服务器</li>\n<li>之后配置shadowsocks一下就可以</li>\n</ul>\n<h2 id=\"第二台-腾讯云\"><a href=\"#第二台-腾讯云\" class=\"headerlink\" title=\"第二台: 腾讯云\"></a>第二台: 腾讯云</h2><ul>\n<li>国外的机房国内访问感觉不太稳定,虽然搬瓦工的服务器也能跑些小玩意儿</li>\n<li>看到国内腾讯云新用户折扣有点大,记得比我当时买阿里云的还实惠,见下图(这不是广告。。。</li>\n</ul>\n<!-- ![](http://static.cangyuanyuan.com/tencent_cloud.png) -->\n<img src=\"http://static.cangyuanyuan.com/tencent_cloud.png\" width=\"50%\" height=\"50%\">\n\n<ul>\n<li>3年2G2M,嗯,只要680,买!</li>\n<li>不愧是国内的机房,ssh连接就是快!</li>\n<li>但是总输入密码和记服务器ip很不爽,果断换成密钥登录</li>\n<li>每个云都会有帮你生成SSH密钥的功能,然后存好下载的与服务器关联的私钥,配置home目录下.ssh文件夹中config文件即可</li>\n</ul>\n<figure class=\"highlight plain\"><table><tr><td class=\"code\"><pre><span class=\"line\">Host xxx </span><br><span class=\"line\"> HostName # 主机地址</span><br><span class=\"line\"> User # 用户名</span><br><span class=\"line\"> IdentityFile # 私钥存放的绝对路径</span><br><span class=\"line\"> # port 指定端口</span><br></pre></td></tr></table></figure>\n\n<ul>\n<li>配置好通过 ssh xxx直接登录服务器,省去一大波操作</li>\n<li>chmod 400 <私钥绝对路径>,记得更改一下私钥文件的权限</li>\n</ul>\n<h2 id=\"接下来打算\"><a href=\"#接下来打算\" class=\"headerlink\" title=\"接下来打算\"></a>接下来打算</h2><p>腾讯云服务器是ubuntu系统,也是我学的第一个linux操作系统,用的可能会比较习惯。</p>\n<p>今后可能写的小程序的接口、网站的部署、博客的迁移都会在这上面进行,不过这是后话了。</p>\n<p>近期可以折腾折腾爬虫,爬一些妹子图存储资源(咳咳。</p>\n<pre><code></code></pre>","categories":["随笔"],"tags":["服务器","Linux"]},{"title":"flex布局","url":"http://yoursite.com/2019/08/11/flex/","content":"<blockquote>\n<p>最近由于某些机缘巧合的原因在写css,感觉真是从零开始写,记得上次写css还是刚开始学编程的时候,然后2年没接触过css了,工作虽然有写过js方面但是css的知识还局限在盒子模型那块,只会写写border,margin等等;自己的项目也是拿别人封装好的ui就用,比如bootstrap和antd。说实话,我还是挺讨厌写css的。当然讨厌归讨厌,这次讲的是比较流行而且简单的flex布局。</p>\n</blockquote>\n<h1 id=\"1-Flex布局\"><a href=\"#1-Flex布局\" class=\"headerlink\" title=\"1.Flex布局\"></a>1.Flex布局</h1><p>flex布局是09年提出的一种弹性布局,使得布局变的异常方便,比如我就用的乐不释手。</p>\n<p>声明一个flex布局也很简单</p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">display</span>: flex; <span class=\"comment\">/* or inline-flex */</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>flex使弹性容器成为块级元素,inline-flex使弹性容器成为单个不可分的行内级元素。</p>\n<p>在使用flex布局后,float、clear和vertical-align属性会失效。</p>\n<h1 id=\"2-容器属性\"><a href=\"#2-容器属性\" class=\"headerlink\" title=\"2.容器属性\"></a>2.容器属性</h1><p>一共有以下6种。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"code\"><pre><span class=\"line\">flex-direction</span><br><span class=\"line\">flex-wrap</span><br><span class=\"line\">flex-flow</span><br><span class=\"line\">justify-content</span><br><span class=\"line\">align-itmes</span><br><span class=\"line\">align-content</span><br></pre></td></tr></table></figure>\n\n<hr>\n<h3 id=\"2-1-flex-direction\"><a href=\"#2-1-flex-direction\" class=\"headerlink\" title=\"2.1 flex-direction\"></a>2.1 flex-direction</h3><p><img src=\"http://static.cangyuanyuan.com/flex-direction.png\" alt=\"direction\"></p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex-direction</span>: row | row-reverse | column | column-reverse;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p><code>row</code>: 默认值,沿着横轴从左到右。<br><code>row-reverse</code>: 沿着横轴从右到左。<br><code>column</code>: 沿着纵轴从上到下。<br><code>column-reverse</code>: 沿着纵轴从下到上。</p>\n<hr>\n<h3 id=\"2-2-flex-wrap\"><a href=\"#2-2-flex-wrap\" class=\"headerlink\" title=\"2.2 flex-wrap\"></a>2.2 flex-wrap</h3><p><img src=\"http://static.cangyuanyuan.com/flex-wrap.png\" alt=\"wrap\"></p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex-wrap</span>: nowrap | wrap | wrap-reverse;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p><code>nowrap</code>: 默认值,不换行。<br><code>wrap</code>: 换行,值从上到下。<br><code>wrap-reverse</code>: 换行,值从下到上。</p>\n<hr>\n<h3 id=\"2-3-flex-flow\"><a href=\"#2-3-flex-flow\" class=\"headerlink\" title=\"2.3 flex-flow\"></a>2.3 flex-flow</h3><p>是<code>flex-direction</code>和<code>flex-wrap</code>的简写形式。</p>\n<hr>\n<h3 id=\"2-4-justify-content\"><a href=\"#2-4-justify-content\" class=\"headerlink\" title=\"2.4 justify-content\"></a>2.4 justify-content</h3><p><img src=\"http://static.cangyuanyuan.com/justify-countent.png\" alt=\"justify-content\"></p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">justify-content</span>: flex-start | flex-end | center | space-between | space-around | space-evenly;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p><code>flex-start</code>: 默认值, 左对齐。<br><code>flex-end</code>: 右对齐。<br><code>center</code>: 居中。<br><code>space-between</code>: 均匀分布。<br><code>space-around</code>: 每个项目的两侧空间相等。<br><code>space-evenly</code>: 两个项目之间的空间相等。</p>\n<hr>\n<h3 id=\"2-5-align-items\"><a href=\"#2-5-align-items\" class=\"headerlink\" title=\"2.5 align-items\"></a>2.5 align-items</h3><p><img src=\"http://static.cangyuanyuan.com/align-items.png\" alt=\"align-items\"></p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">align-items</span>: stretch | flex-start | flex-end | center | baseline;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p><code>stretch</code>: 默认值,纵轴高度充满容器。<br><code>flex-start</code>: 在交叉轴的起点对齐。<br><code>flex-end</code>: 在交叉轴的终点对齐。<br><code>center</code>: 在交叉轴居中。<br><code>baseline</code>: 项目的基准线对齐。</p>\n<hr>\n<h3 id=\"2-6-align-content\"><a href=\"#2-6-align-content\" class=\"headerlink\" title=\"2.6 align-content\"></a>2.6 align-content</h3><p> <img src=\"http://static.cangyuanyuan.com/align-content.png\" alt=\"align-content\"></p>\n <figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"> <span class=\"selector-class\">.container</span> {</span><br><span class=\"line\"> <span class=\"attribute\">align-content</span>: flex-start | flex-end | center | space-between | space-around | stretch;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>注意: 只有一个轴线则不会起作用。</p>\n<p><code>flex-start</code>: 交叉轴起点对齐。<br><code>flex-end</code>: 交叉轴终点对齐。<br><code>center</code>: 在交叉中居中。<br><code>space-between</code>: 在纵轴、横轴间隔均匀分布。<br><code>space-around</code>: 每个项目的两侧空间相等。<br><code>stretch</code>: 默认值,充满剩余空间。</p>\n<h1 id=\"3-项目属性\"><a href=\"#3-项目属性\" class=\"headerlink\" title=\"3.项目属性\"></a>3.项目属性</h1><p>一共也有6种。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"code\"><pre><span class=\"line\">order</span><br><span class=\"line\">flex-grow</span><br><span class=\"line\">flex-shrink</span><br><span class=\"line\">flex-basis</span><br><span class=\"line\">flex</span><br><span class=\"line\">align-self</span><br></pre></td></tr></table></figure>\n\n<hr>\n<h3 id=\"3-1-order\"><a href=\"#3-1-order\" class=\"headerlink\" title=\"3.1 order\"></a>3.1 order</h3><p> <img src=\"http://static.cangyuanyuan.com/flex-order.png\" alt=\"order\"></p>\n<figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">order</span>: <integer>; <span class=\"comment\">/* 默认为 0 */</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>order可以定义项目排列顺序,数字越小越靠前。</p>\n<hr>\n<h3 id=\"3-2-flex-grow\"><a href=\"#3-2-flex-grow\" class=\"headerlink\" title=\"3.2 flex-grow\"></a>3.2 flex-grow</h3><p> <img src=\"http://static.cangyuanyuan.com/flex-grow.png\" alt=\"flex-grow\"></p>\n <figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex-grow</span>: <integer>; <span class=\"comment\">/* 默认为 0 */</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>如果所有<code>flex-grow</code>元素设置为1,那么平分空间,如果有一共设置为2,则占据两倍空间。</p>\n<hr>\n<h3 id=\"3-3-flex-shrink\"><a href=\"#3-3-flex-shrink\" class=\"headerlink\" title=\"3.3 flex-shrink\"></a>3.3 flex-shrink</h3><figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex-shrink</span>: <number>; <span class=\"comment\">/* 默认为 1 */</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>如果空间不足的话则会缩小。</p>\n<hr>\n<h3 id=\"3-4-flex-basis\"><a href=\"#3-4-flex-basis\" class=\"headerlink\" title=\"3.4 flex-basis\"></a>3.4 flex-basis</h3><figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex-basis</span>: <length> | auto; <span class=\"comment\">/* 默认为 auto */</span></span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>指定项目在主轴方向上的大小。</p>\n<hr>\n<h3 id=\"3-5-flex\"><a href=\"#3-5-flex\" class=\"headerlink\" title=\"3.5 flex\"></a>3.5 flex</h3><figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">flex</span>: none | [ <<span class=\"string\">'flex-grow'</span>> <<span class=\"string\">'flex-shrink'</span>>? || <<span class=\"string\">'flex-basis'</span>> ]</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>是<code>flex-grow</code>, <code>flex-shrink</code> 和 <code>flex-basis</code>的简写,<code>flex-shrink</code> 和 <code>flex-basis</code>是可选项。默认值为0, 1, auto。</p>\n<p>注意: 推荐使用这种简写的方式来代替使用单个属性的方式。</p>\n<hr>\n<h3 id=\"3-6-align-self\"><a href=\"#3-6-align-self\" class=\"headerlink\" title=\"3.6 align-self\"></a>3.6 align-self</h3><p> <img src=\"http://static.cangyuanyuan.com/align-self.png\" alt=\"align-self\"></p>\n <figure class=\"highlight css\"><table><tr><td class=\"code\"><pre><span class=\"line\"> <span class=\"selector-class\">.item</span> {</span><br><span class=\"line\"> <span class=\"attribute\">align-self</span>: auto | flex-start | flex-end | center | baseline | stretch;</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p> 此属性允许单个项目的对齐方式与他人不一致(同样是start对齐你咋这么优秀呢)。这种方式会覆盖align-items父元素属性。</p>\n<h1 id=\"4-后记\"><a href=\"#4-后记\" class=\"headerlink\" title=\"4.后记\"></a>4.后记</h1><p> 此笔记和所用图片参考与源自<a href=\"http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html\" target=\"_blank\" rel=\"noopener\">阮一峰的博客</a>,和<a href=\"https://css-tricks.com/snippets/css/a-guide-to-flexbox/\" target=\"_blank\" rel=\"noopener\">A Complete Guide to Flexbox </a>这篇文章。</p>\n<p>flex的用法很简单易懂,下次会学习并分享grid用法更加复杂的一种网格式布局。</p>\n","categories":["技术"],"tags":["前端","css"]},{"title":"React新特性Hooks","url":"http://yoursite.com/2019/08/04/hooks-1/","content":"<blockquote>\n<p>最近由于某些机缘巧合的原因在写前端,由于项目被React重构,而且用的还是最新的React技术Hooks,由于之前只简单了解过React,趁着这次机会系统的学习一下Hooks,强化一下前端的知识。</p>\n</blockquote>\n<h2 id=\"1-Hooks是什么\"><a href=\"#1-Hooks是什么\" class=\"headerlink\" title=\"1.Hooks是什么\"></a>1.Hooks是什么</h2><p>hooks是React16.8的新特性,是去年React团队推出的新特性,今年年初已经被稳定支持,可谓是非常时髦的一个知识点。hooks可以用函数组件来替换类组件,并且在函数组件中使用新方法来代替一系列的生命周期方法。</p>\n<h4 id=\"hooks优点\"><a href=\"#hooks优点\" class=\"headerlink\" title=\"hooks优点\"></a>hooks优点</h4><ul>\n<li>hooks完全可选,即想用就可以在自己项目中使用,不想用也不必须去学习,react没有废除class组件的想法,也就是说hooks并不是一门必学的课程。</li>\n<li>向后兼容,你可以在项目中一处使用,并不会导致你的项目整体不能使用,以前的语法和hooks并不冲突,你可以一点一点迁移到hooks上来。</li>\n</ul>\n<h4 id=\"hooks缺点\"><a href=\"#hooks缺点\" class=\"headerlink\" title=\"hooks缺点\"></a>hooks缺点</h4><ul>\n<li>并不能完全复现生命周期,hooks只不过将最常见的生命周期复现,但是还有一部分需要使用类组件来应用。</li>\n</ul>\n<h4 id=\"如何使用\"><a href=\"#如何使用\" class=\"headerlink\" title=\"如何使用\"></a>如何使用</h4><p>在react版本16.8及以上便可</p>\n<figure class=\"highlight js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">import</span> { useState, useEffect } <span class=\"keyword\">from</span> <span class=\"string\">'react'</span>;</span><br></pre></td></tr></table></figure>\n\n<h2 id=\"2-useState\"><a href=\"#2-useState\" class=\"headerlink\" title=\"2.useState\"></a>2.useState</h2><p>简单的例子</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"code\"><pre><span class=\"line\">const [count, setCount] = useState(10);</span><br><span class=\"line\">onClick = {() => setCount(count + 1)}</span><br></pre></td></tr></table></figure>\n\n<ol>\n<li>count是state</li>\n<li>setCount来更新state</li>\n<li>useState(10), 设置count默认值为10</li>\n</ol>\n<h2 id=\"3-useEffect\"><a href=\"#3-useEffect\" class=\"headerlink\" title=\"3.useEffect\"></a>3.useEffect</h2><p><code>useEffect</code>实现了<code>componentDidMount</code>,<code>componentDidUpdate</code>和<code>componentWillUnmount</code>三种副作用。</p>\n<p>当组件被更新时,<code>useEffect</code>会在render之后被调用,如果想要当变量值变化就更新组件,只需在第二个参数传入一个数组即可。</p>\n<figure class=\"highlight js\"><table><tr><td class=\"code\"><pre><span class=\"line\">useEffect(<span class=\"function\"><span class=\"params\">()</span> =></span> {</span><br><span class=\"line\"> <span class=\"built_in\">document</span>.title = <span class=\"string\">`You clicked <span class=\"subst\">${count}</span> times`</span></span><br><span class=\"line\">}, [count])</span><br></pre></td></tr></table></figure>\n\n<ul>\n<li>第二个参数不传,每次渲染后都执行。</li>\n<li>传一个空数组的话,只会执行一次。</li>\n</ul>\n<p>如果想要在组件被销毁前触发,需要加上回调函数</p>\n<figure class=\"highlight js\"><table><tr><td class=\"code\"><pre><span class=\"line\">useEffect(<span class=\"function\"><span class=\"params\">()</span> =></span> {</span><br><span class=\"line\"> <span class=\"keyword\">return</span> <span class=\"function\"><span class=\"params\">()</span> =></span> {</span><br><span class=\"line\"> <span class=\"comment\">// 此处相当于componentWillUnmount,来进行一些组件销毁时的操作</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure>\n\n<h2 id=\"4-useContext\"><a href=\"#4-useContext\" class=\"headerlink\" title=\"4.useContext\"></a>4.useContext</h2><p>Context在类组件中可以跨组件传递,避免一层一层传递,如果在hooks中使用context,用<code>useContext</code>即可,非常简单。</p>\n<figure class=\"highlight js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> count = useContext(xxxContext)</span><br></pre></td></tr></table></figure>\n\n<p>相比较类组件中的ContextType,函数组件可以使用多个<code>useContext</code>。</p>\n<h2 id=\"5-useMemo、useCallback\"><a href=\"#5-useMemo、useCallback\" class=\"headerlink\" title=\"5.useMemo、useCallback\"></a>5.useMemo、useCallback</h2><p>类组件中对指定组件渲染是用PureComponent,这样可以避免组件重复渲染,通过判断传入的属性值是否相等。</p>\n<p>在函数组件中,使用memo,见下例</p>\n<figure class=\"highlight js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> Count = memo(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Count</span>(<span class=\"params\"></span>) => </span>{</span><br><span class=\"line\"> <span class=\"keyword\">return</span> ...</span><br><span class=\"line\">})</span><br></pre></td></tr></table></figure>\n\n<p><code>useMemo</code>和memo相比,可以判断一段函数逻辑是否重复执行。<br>使用方法和memo相似</p>\n<figure class=\"highlight js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">const</span> count = useMemo(<span class=\"function\"><span class=\"params\">()</span> =></span> {</span><br><span class=\"line\"> <span class=\"comment\">// ...</span></span><br><span class=\"line\">}, [])</span><br></pre></td></tr></table></figure>\n\n<p>其中第二个参数和<code>useEffect</code>使用逻辑一样,而与<code>useEffect</code>不同,<code>useEffect</code>在渲染之后运行,而<code>useMemo</code>在渲染期间完成。</p>\n<p>当<code>useMemo</code>返回的是函数,可以直接用<code>useCallback</code></p>\n<figure class=\"highlight js\"><table><tr><td class=\"code\"><pre><span class=\"line\">useCallback(<span class=\"function\"><span class=\"params\">()</span> =></span> {</span><br><span class=\"line\"> <span class=\"comment\">// ...</span></span><br><span class=\"line\">}, [])</span><br></pre></td></tr></table></figure>\n\n<p><code>useMemo(() => fn)</code> 等价于 <code>useCallback(fn)</code></p>\n<h2 id=\"6-useRef\"><a href=\"#6-useRef\" class=\"headerlink\" title=\"6.useRef\"></a>6.useRef</h2><p><code>useRef</code>使用有两种场景:</p>\n<ol>\n<li>获取字组件、DOM元素</li>\n<li>同步不同渲染周期需要共享的数据</li>\n</ol>\n<p>例如</p>\n<figure class=\"highlight js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"comment\">// 1.</span></span><br><span class=\"line\"><span class=\"keyword\">const</span> countRef = useRef();</span><br><span class=\"line\"><Counter ref = {countRef} /></span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"comment\">// 2.</span></span><br><span class=\"line\">count it = useRef();</span><br><span class=\"line\"><span class=\"comment\">// 赋值</span></span><br><span class=\"line\">it.current = <span class=\"number\">123</span></span><br><span class=\"line\"><span class=\"comment\">// 使用</span></span><br><span class=\"line\">it.current</span><br></pre></td></tr></table></figure>\n\n<h2 id=\"7-Hooks的规则\"><a href=\"#7-Hooks的规则\" class=\"headerlink\" title=\"7.Hooks的规则\"></a>7.Hooks的规则</h2><p>hooks有使用规则,我们必须按照规则严格使用,不然程序会出现各种各样的问题,还好这些规则十分简单。</p>\n<ol>\n<li>需要函数组件最顶层使用</li>\n</ol>\n<figure class=\"highlight js\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">functionName</span>(<span class=\"params\"></span>) </span>{</span><br><span class=\"line\"> <span class=\"comment\">// top-level顶层</span></span><br><span class=\"line\"> <span class=\"keyword\">const</span> [count, setCount] = useCount(<span class=\"number\">0</span>);</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<ol start=\"2\">\n<li><p>不允许在循环或者判断语句中使用</p>\n<p>很容易出现state值错乱的问题,就不要作死去尝试啦。</p>\n</li>\n<li><p>不能在类组件中使用</p>\n</li>\n<li><p>use是hooks关键所在</p>\n<p>当你定义一个函数开头使用use,那么就是一个hooks</p>\n</li>\n</ol>\n<h2 id=\"8-总结\"><a href=\"#8-总结\" class=\"headerlink\" title=\"8.总结\"></a>8.总结</h2><p>在学go中过程中,go就摒弃了类的实现,一开始也很不习惯,后来发现用的还舒心。react中的类组件因为逻辑状态复杂,难以理解,生命周期逻辑混乱,所以才诞生出hooks。</p>\n<p>虽然hooks还无法完全取代class,但hooks的诞生能应用在日常项目中的绝大多数环境下,取代使用最频繁的生命周期场景,使代码的可读性更强,用法更简便,已经足够了。</p>\n","categories":["技术"],"tags":["前端","React"]},{"title":"3种方法实现一个基于Go语言的Web服务器","url":"http://yoursite.com/2019/07/15/go-http/","content":"<blockquote>\n<p>go语言中的http库是一个非常简单、实用的底层封装库,几行代码就可以实现一个Web服务器。(本文基于Go版本1.12.4)</p>\n</blockquote>\n<h2 id=\"第一种实现\"><a href=\"#第一种实现\" class=\"headerlink\" title=\"第一种实现\"></a>第一种实现</h2><p>首先上代码</p>\n<figure class=\"highlight go\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">package</span> main</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">import</span> (</span><br><span class=\"line\"> <span class=\"string\">\"fmt\"</span></span><br><span class=\"line\"> <span class=\"string\">\"log\"</span></span><br><span class=\"line\"> <span class=\"string\">\"net/http\"</span></span><br><span class=\"line\">)</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">func</span> <span class=\"title\">main</span><span class=\"params\">()</span></span> {</span><br><span class=\"line\"> http.HandleFunc(<span class=\"string\">\"/\"</span>, handler)</span><br><span class=\"line\"> log.Fatal(http.ListenAndServe(<span class=\"string\">\"localhost:8000\"</span>, <span class=\"literal\">nil</span>))</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">func</span> <span class=\"title\">handler</span><span class=\"params\">(w http.ResponseWriter, r *http.Request)</span></span> {</span><br><span class=\"line\"> fmt.Fprintf(w, <span class=\"string\">\"URL.Path = %q\\n\"</span>, r.URL.Path)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>很简单的十来行代码,我们来看看发生了什么吧。首先是HandlerFunc方法的参数要求。</p>\n<figure class=\"highlight go\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">func</span> <span class=\"title\">HandleFunc</span><span class=\"params\">(pattern <span class=\"keyword\">string</span>, handler <span class=\"keyword\">func</span>(ResponseWriter, *Request)</span>)</span> {</span><br><span class=\"line\">\tDefaultServeMux.HandleFunc(pattern, handler)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>从源码中可以看出,是注册了一个handle函数给pattern路由路径,handler函数接受两个参数,1是ResponseWriter的值传递,2是Request的指针传递,再跳转Request中发现Request是一个结构体,实例化之后默认是值传递,所以为了节省内存将它设置为指针传递,而ResponseWriter是个接口,并不存在指针传递。</p>\n<p>知道handler的参数那么接下来实现的handler就很简单了。注册好路由需要通过ListenAndServe来启动服务,它接受两个参数,1是服务器的地址,2是接口的实例,上面例子由于我们使用的是默认的serve mux,所以传递一个nil就可以了。</p>\n<p>流程是“/”路由路径和处理函数绑定在一起 –> 启动服务器监听服务器地址 –> 访问“/”路径时,请求到达转交给处理函数 –> 处理函数从请求的URL提取Path,然后用fmt格式化并作为响应发送出去。</p>\n<p>可能这还不够底层,接下来看第二版本。</p>\n<h2 id=\"第二种实现\"><a href=\"#第二种实现\" class=\"headerlink\" title=\"第二种实现\"></a>第二种实现</h2><p>第一个例子中并没有完全控制处理函数handler,而是使用了程序中init()初始化中的默认serve mux。接下来自己实现一个mux。</p>\n<figure class=\"highlight go\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">package</span> main</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">import</span> (</span><br><span class=\"line\"> <span class=\"string\">\"fmt\"</span></span><br><span class=\"line\"> <span class=\"string\">\"log\"</span></span><br><span class=\"line\"> <span class=\"string\">\"net/http\"</span></span><br><span class=\"line\">)</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">func</span> <span class=\"title\">main</span><span class=\"params\">()</span></span> {</span><br><span class=\"line\"> mux := http.NewServeMux()</span><br><span class=\"line\"></span><br><span class=\"line\"> mux.Handle(<span class=\"string\">\"/\"</span>, &myHandler{})</span><br><span class=\"line\"> mux.HandleFunc(<span class=\"string\">\"/hello\"</span>, handler)</span><br><span class=\"line\"></span><br><span class=\"line\"> log.Fatal(http.ListenAndServe(<span class=\"string\">\"localhost:8000\"</span>, mux))</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">type</span> myHandler <span class=\"keyword\">struct</span>{}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">func</span> <span class=\"params\">(*myHandler)</span> <span class=\"title\">ServeHTTP</span><span class=\"params\">(w http.ResponseWriter, r *http.Request)</span></span> {</span><br><span class=\"line\"> fmt.Fprintf(w, <span class=\"string\">\"URL:\"</span> + r.URL.Path)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">func</span> <span class=\"title\">handler</span><span class=\"params\">(w http.ResponseWriter, r *http.Request)</span></span> {</span><br><span class=\"line\"> fmt.Fprintf(w, <span class=\"string\">\"hello, world!\"</span>)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>自定义的mux,而不是使用系统自带的DefaultServeMux,这样的好处是可以在服务中完全控制handler。而handler也可以自定义,前提是需要实现一个ServeHTTP方法。</p>\n<h2 id=\"第三种实现\"><a href=\"#第三种实现\" class=\"headerlink\" title=\"第三种实现\"></a>第三种实现</h2><p>接下来看ListenAndServe的源码</p>\n<figure class=\"highlight go\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"function\"><span class=\"keyword\">func</span> <span class=\"title\">ListenAndServe</span><span class=\"params\">(addr <span class=\"keyword\">string</span>, handler Handler)</span> <span class=\"title\">error</span></span> {</span><br><span class=\"line\">\t server := &Server{Addr: addr, Handler: handler}</span><br><span class=\"line\">\t <span class=\"keyword\">return</span> server.ListenAndServe()</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>里面封装了一个Server的结构,然后进行监听,那么由我们自己来实现这个Server</p>\n<figure class=\"highlight go\"><table><tr><td class=\"code\"><pre><span class=\"line\"><span class=\"keyword\">package</span> main</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">import</span> (</span><br><span class=\"line\"> <span class=\"string\">\"fmt\"</span></span><br><span class=\"line\"> <span class=\"string\">\"log\"</span></span><br><span class=\"line\"> <span class=\"string\">\"net/http\"</span></span><br><span class=\"line\"> <span class=\"string\">\"time\"</span></span><br><span class=\"line\">)</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"keyword\">var</span> mux <span class=\"keyword\">map</span>[<span class=\"keyword\">string</span>]<span class=\"function\"><span class=\"keyword\">func</span><span class=\"params\">(http.ResponseWriter, *http.Request)</span></span></span><br><span class=\"line\"><span class=\"function\"></span></span><br><span class=\"line\"><span class=\"function\"><span class=\"title\">func</span> <span class=\"title\">main</span><span class=\"params\">()</span></span> {</span><br><span class=\"line\"> server := http.Server{</span><br><span class=\"line\"> Addr: <span class=\"string\">\"localhost:8000\"</span>,</span><br><span class=\"line\"> Handler: &myHandler{},</span><br><span class=\"line\"> ReadTimeout: <span class=\"number\">5</span>*time.Second,</span><br><span class=\"line\"> }</span><br><span class=\"line\"></span><br><span class=\"line\"> mux = <span class=\"built_in\">make</span>(<span class=\"keyword\">map</span>[<span class=\"keyword\">string</span>]<span class=\"function\"><span class=\"keyword\">func</span><span class=\"params\">(http.ResponseWriter, *http.Request)</span>)</span></span><br><span class=\"line\"><span class=\"function\"> <span class=\"title\">mux</span>[\"/<span class=\"title\">hello</span>\"] = <span class=\"title\">hello</span></span></span><br><span class=\"line\"><span class=\"function\"> <span class=\"title\">mux</span>[\"/<span class=\"title\">bye</span>\"] = <span class=\"title\">bye</span></span></span><br><span class=\"line\"><span class=\"function\"></span></span><br><span class=\"line\"><span class=\"function\"> <span class=\"title\">log</span>.<span class=\"title\">Fatal</span><span class=\"params\">(server.ListenAndServe()</span>)</span></span><br><span class=\"line\"><span class=\"function\">}</span></span><br><span class=\"line\"><span class=\"function\"></span></span><br><span class=\"line\"><span class=\"function\"><span class=\"title\">type</span> <span class=\"title\">myHandler</span> <span class=\"title\">struct</span></span>{}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">func</span> <span class=\"params\">(*myHandler)</span> <span class=\"title\">ServeHTTP</span><span class=\"params\">(w http.ResponseWriter, r *http.Request)</span></span> {</span><br><span class=\"line\"> <span class=\"keyword\">if</span> h, ok := mux[r.URL.Path]; ok {</span><br><span class=\"line\"> h(w, r)</span><br><span class=\"line\"> <span class=\"keyword\">return</span></span><br><span class=\"line\"> }</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">func</span> <span class=\"title\">hello</span><span class=\"params\">(w http.ResponseWriter, r *http.Request)</span></span> {</span><br><span class=\"line\"> fmt.Fprintf(w, <span class=\"string\">\"hello, world!\"</span>)</span><br><span class=\"line\">}</span><br><span class=\"line\"></span><br><span class=\"line\"><span class=\"function\"><span class=\"keyword\">func</span> <span class=\"title\">bye</span><span class=\"params\">(w http.ResponseWriter, r *http.Request)</span></span> {</span><br><span class=\"line\"> fmt.Fprintf(w, <span class=\"string\">\"bye!\"</span>)</span><br><span class=\"line\">}</span><br></pre></td></tr></table></figure>\n\n<p>由于Server结构体中并没有和路径相关的成员,那么我们如何实现路径绑定呢,此时可以利用go中的数据结构map,由路径字符串作为key,handler函数作为值形成一个映射关系,而我们在handler中的唯一一个ServeHTTP方法中来进行路由转发,从map中判断路径是否存在,即可实现绑定相应的handler。</p>\n<h2 id=\"总结\"><a href=\"#总结\" class=\"headerlink\" title=\"总结\"></a>总结</h2><ol>\n<li><p>ServeHTTP方法是可以基于URL路径来决定执行哪部分逻辑,但是现实中的应用往往会有一大堆逻辑,我们需要分离到独立的函数及方法中。</p>\n</li>\n<li><p>为了简化URL和处理函数之间的关联,net/http包中提供一个<em>多工转发器</em>ServeMux,将多个Handle组合成单个Handle。</p>\n</li>\n<li><p>更复杂的应用中,ServeMux会组合起来。</p>\n</li>\n<li><p>注册处理程序的方法太常见来,所以ServeMux引用了一个HandleFunc的便捷方法来处理。</p>\n</li>\n<li><p>对于绝大多数服务来说,一个Web服务远远足够,这个服务可能会在很多文件中定义处理程序,但是每次都要注册到ServeMux中,太麻烦了,所以net/http包提供了一个全局的ServeMux实例DefaultServeMux,使DefaultServeMux作为服务器的主处理程序,这样就无须将它传给ListenAndServe,直接传nil即可。</p>\n</li>\n</ol>\n","categories":["技术"],"tags":["服务器","Goland","Web"]},{"title":"第一次使用hexo","url":"http://yoursite.com/2019/06/27/start-hexo/","content":"<blockquote>\n<p>花了一天时间开了个hexo的静态博客,比起自己从零搭建一个博客好处就是太方便了。主题使用的是<a href=\"https://github.com/forsigner/fexo\" target=\"_blank\" rel=\"noopener\">fexo</a>,是个极简风格的,第一眼看到就中意上了。博客头像是今年寒假在日本旅行遇到的2019年的第一场雪,当时深夜在街道上站了好久拍的一张图,冻的瑟瑟发抖,没想到这一冻就是一年。</p>\n</blockquote>\n<h2 id=\"搭建过程\"><a href=\"#搭建过程\" class=\"headerlink\" title=\"搭建过程\"></a>搭建过程</h2><p>整个搭建下来还是蛮容易的,fexo提供的文档非常清晰。</p>\n<p>先把<a href=\"https://github.com/forsigner/fexo\" target=\"_blank\" rel=\"noopener\">fexo</a>克隆到themes文件夹中,在_config.yml配置文件中修改主题为fexo。</p>\n<p>接下来的配置在themes/fexo/_config.yml中进行,文档都有说明。</p>\n<h3 id=\"1-hexo命令\"><a href=\"#1-hexo命令\" class=\"headerlink\" title=\"1. hexo命令\"></a>1. hexo命令</h3><figure class=\"highlight plain\"><table><tr><td class=\"code\"><pre><span class=\"line\">hexo g // 执行生成静态文件</span><br><span class=\"line\">hexo d // 部署</span><br><span class=\"line\">hexo s --debug // 本地debug</span><br><span class=\"line\">hexo clean // 清除缓存</span><br><span class=\"line\"></span><br><span class=\"line\">hexo new [layout] <title> // layout默认为post,创建一篇文章</span><br></pre></td></tr></table></figure>\n\n<p>经常用到的也就是上面一些命令,更多的也都能在hexo文档里面找到。</p>\n<h2 id=\"使用到的配置\"><a href=\"#使用到的配置\" class=\"headerlink\" title=\"使用到的配置\"></a>使用到的配置</h2><p>fexo本身自带了很多有用的配置,只需要在themes/fexo/_config.yml中填写相应的参数即可。</p>\n<h3 id=\"1-打赏二维码\"><a href=\"#1-打赏二维码\" class=\"headerlink\" title=\"1. 打赏二维码\"></a>1. 打赏二维码</h3><p>随着知识付费的理念越来越普及,很多博主都会在博文下方添加一个收钱二维码,大致意思是创作不易,请杯咖啡。</p>\n<p>笔者也厚着脸皮跟风添加了一个,将图片放置themes/fexo/source/images中,然后在配置文件中填入相应的路径即可。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"code\"><pre><span class=\"line\">- type: 微信</span><br><span class=\"line\">text: 微信扫一扫</span><br><span class=\"line\">imgUrl: /images/xxx.png // 二维码图片名</span><br></pre></td></tr></table></figure>\n\n<h3 id=\"2-谷歌、百度分析\"><a href=\"#2-谷歌、百度分析\" class=\"headerlink\" title=\"2. 谷歌、百度分析\"></a>2. 谷歌、百度分析</h3><p>两款用来分析网站流量的工具。</p>\n<p><a href=\"https://analytics.google.com/analytics/web/\" target=\"_blank\" rel=\"noopener\">谷歌分析</a>需要翻墙</p>\n<p><a href=\"https://tongji.baidu.com/web/welcome/login\" target=\"_blank\" rel=\"noopener\">百度分析</a>需要注册,ps:百度账号不能使用。</p>\n<p>两者随便选择一种即可,然后将获取到的key值添加到配置文件中即可。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"code\"><pre><span class=\"line\">google_analytics: xxxxxxxxx</span><br><span class=\"line\">baidu_analytics: xxxxxxxxx</span><br></pre></td></tr></table></figure>\n\n<h3 id=\"3-评论\"><a href=\"#3-评论\" class=\"headerlink\" title=\"3. 评论\"></a>3. 评论</h3><p>使用<a href=\"https://github.com/gitalk/gitalk\" target=\"_blank\" rel=\"noopener\">gitalk</a>的评论服务,需要先在github仓库下建立一个OAuth Application。然后将获取到的Client ID和Client Secret填入配置文件中。</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"code\"><pre><span class=\"line\">gitalk:</span><br><span class=\"line\">enable: true # 如果使用 gitalk,请设置改之为true</span><br><span class=\"line\">clientID: xxx</span><br><span class=\"line\">clientSecret: xxx</span><br><span class=\"line\">repo: // 仓库名</span><br><span class=\"line\">owner: // github用户名</span><br><span class=\"line\">admin: // 同上</span><br></pre></td></tr></table></figure>\n\n<p>其中遇到了一个坑就是,配置好在文章下出现:</p>\n<figure class=\"highlight plain\"><table><tr><td class=\"code\"><pre><span class=\"line\">未找到相关的Issues进行评论</span><br><span class=\"line\">请联系@xxx 初始化创建</span><br><span class=\"line\">使用github登录</span><br></pre></td></tr></table></figure>\n\n<p>点击登录之后,就会跳转重定向到首页,原因是OAuth Apps配置中填入的Authorization callback URL和Homepage URL都带了www,和页面的连接不一样,所以导致重定向失败。</p>\n<p>遇到这种情况先打开开发者工具中network选项,然后详细看发送的网络请求,就能定位出错误的所在了。</p>\n<h2 id=\"后续\"><a href=\"#后续\" class=\"headerlink\" title=\"后续\"></a>后续</h2><p>搭建博客的原因,居然是我Python1年经验,在帝都获得不到一次面试机会!很后悔自己没有写博客的习惯,而是依赖于网易云笔记。</p>\n<p>但是为了找工作而搭建这个博客明显是非常功利的,希望自己能坚持下去把。</p>\n<p>并且早日找到满意的工作,在这寒风凛冽的冬天中。</p>\n<p>2019/6/27</p>\n","categories":["技术"],"tags":["hexo","技术博客","markdown"]},{"title":"about","url":"http://yoursite.com/about/index.html","content":"","categories":[],"tags":[]},{"title":"category","url":"http://yoursite.com/category/index.html","content":"","categories":[],"tags":[]},{"title":"link","url":"http://yoursite.com/link/index.html","content":"","categories":[],"tags":[]},{"title":"tag","url":"http://yoursite.com/tag/index.html","content":"","categories":[],"tags":[]},{"title":"search","url":"http://yoursite.com/search/index.html","content":"","categories":[],"tags":[]}]