-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
240 lines (115 loc) · 64.4 KB
/
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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>计算机网络总结复习</title>
<link href="/2019/11/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E6%80%BB%E7%BB%93%E5%A4%8D%E4%B9%A0/"/>
<url>/2019/11/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E6%80%BB%E7%BB%93%E5%A4%8D%E4%B9%A0/</url>
<content type="html"><![CDATA[<h1 id="校园网设计实验"><a href="#校园网设计实验" class="headerlink" title="校园网设计实验"></a>校园网设计实验</h1><p><img src="/2019/11/03/计算机网络总结复习/%E6%90%9C%E7%8B%97%E6%88%AA%E5%9B%BE19%E5%B9%B411%E6%9C%8803%E6%97%A51619_2.gif" alt></p><h2 id="1-创建vlan"><a href="#1-创建vlan" class="headerlink" title="1.创建vlan"></a>1.创建vlan</h2><p>在conf t 模式下</p><p>swithch(config) vlan 2 //创建vlan</p><p>swithch(config-vlan) name v2 //为创建的vlan命名</p><h2 id="2-给端口分配vlan"><a href="#2-给端口分配vlan" class="headerlink" title="2.给端口分配vlan"></a>2.给端口分配vlan</h2><h3 id="分配接入端口。也就是分配vlan"><a href="#分配接入端口。也就是分配vlan" class="headerlink" title="分配接入端口。也就是分配vlan"></a>分配接入端口。也就是分配vlan</h3><p>swithch(config) int fa0/1 //进入对应端口</p><p>swithch(config-if) switchport mode access //设置端口协议</p><p>swithch(config-if) switchport access vlan 2 //为端口设置vlan</p><h3 id="共享端口。供不同的vlan通过交换"><a href="#共享端口。供不同的vlan通过交换" class="headerlink" title="共享端口。供不同的vlan通过交换"></a>共享端口。供不同的vlan通过交换</h3><p>swithch(config) int fa0/1 //进入对应端口</p><p><strong>swithch(config-if) switchport trunk encapsulation dot1q //对于三层交换机设置端口必须有这一步</strong></p><p>swithch(config-if) switchport mode trunk //设置端口协议</p><p>swithch(config-if) switchport trunk allowed vlan 2,3 //设置允许通过的vlan</p><h2 id="3-为对应vlan设置ip地址"><a href="#3-为对应vlan设置ip地址" class="headerlink" title="3.为对应vlan设置ip地址"></a>3.为对应vlan设置ip地址</h2><p>(config) int vlan 2</p><p>(config-if) ip addr 192.1.2.254 255.255.255.0</p><h2 id="4-启动三层交换机路由功能"><a href="#4-启动三层交换机路由功能" class="headerlink" title="4.启动三层交换机路由功能"></a>4.启动三层交换机路由功能</h2><p>(config) ip routing</p><p>总结:该实验中,二层交换机进行创建vlan,给端口分配vlan。而三层交换机则要创建vlan,给端口分配vlan,同时为对应vlan设置ip地址,最后启动交换机路由功能</p><h1 id="三层交换机动态路由配置实验"><a href="#三层交换机动态路由配置实验" class="headerlink" title="三层交换机动态路由配置实验"></a>三层交换机动态路由配置实验</h1><img src="/2019/11/03/计算机网络总结复习/clip_image002.jpg" alt="img" style="zoom: 80%;"><p>需要将两条两路聚合成一条</p><h2 id="1-创建端口通道"><a href="#1-创建端口通道" class="headerlink" title="1.创建端口通道"></a>1.创建端口通道</h2><p>switch(config) # int range fa0/3-fa0/5 //进入要聚合的端口</p><p>switch(config-if-range) # channel-group 1 mode active //创建编号为1的端口通道,分配给上述端口,并激活。(端口通道编号针对于本交换机而言,即不同交换机都是从1开始的)</p><p>switch(config-if-range) # channel-protocol lacp //指定聚合协议为lacp</p><p>switch(config-if-range) # exit</p><p>switch(config) # port-channel load-balance src-dst-mac 指定分发策略</p><h2 id="2-给端口通道分配vlan"><a href="#2-给端口通道分配vlan" class="headerlink" title="2.给端口通道分配vlan"></a>2.给端口通道分配vlan</h2><h3 id="接入端口"><a href="#接入端口" class="headerlink" title="接入端口"></a>接入端口</h3><p>swithch(config) int port-channel 1 //进入聚合端口 对应的编号</p><p>swithch(config-if) switchport mode access //设置端口协议</p><p>swithch(config-if) switchport access vlan 2 //为端口设置vlan</p><h3 id="共享端口"><a href="#共享端口" class="headerlink" title="共享端口"></a>共享端口</h3><p>swithch(config) int port-channel 2 //进入对应端口</p><p><strong>swithch(config-if) switchport trunk encapsulation dot1q //对于三层交换机设置端口必须有这一步</strong></p><p>swithch(config-if) switchport mode trunk //设置端口协议</p><p>swithch(config-if) switchport trunk allowed vlan 2,3 //设置允许通过的vlan</p><h2 id="3-配置ospf"><a href="#3-配置ospf" class="headerlink" title="3.配置ospf"></a>3.配置ospf</h2><p>swithch(config) #router ospf 07 //07 为标识符 ,一个线路中,每个都要不一样</p><p>network 192.1.2.0 0. 0. 0.255 area 1 // 相连的网络号 子网掩码的反码</p><p>。。。</p><h2 id="三层交换机"><a href="#三层交换机" class="headerlink" title="三层交换机"></a>三层交换机</h2><ol><li><p>链路聚合,创建端口通道</p></li><li><p>创建vlan,端口配置vlan,为vlan配置ip地址</p></li><li><p>ospf路由协议</p></li></ol><h2 id="二层交换机"><a href="#二层交换机" class="headerlink" title="二层交换机"></a>二层交换机</h2><p>二层交换机进行创建vlan,给端口分配vlan。</p><h1 id="企业网路由项和NAT配置"><a href="#企业网路由项和NAT配置" class="headerlink" title="企业网路由项和NAT配置"></a>企业网路由项和NAT配置</h1><p><img src="/2019/11/03/计算机网络总结复习/clip_image003.jpg" alt></p><h2 id="打开路由器端口,为端口分配IP地址"><a href="#打开路由器端口,为端口分配IP地址" class="headerlink" title="打开路由器端口,为端口分配IP地址"></a>打开路由器端口,为端口分配IP地址</h2><p>int fa0/0</p><p>no shut </p><p>ip addr 192.168.1.254 255.255.255.0 </p><h2 id="ospf路由"><a href="#ospf路由" class="headerlink" title="ospf路由"></a>ospf路由</h2><p>router ospf 01</p><p>network 193.1.1.0 0.0.0.3 area 1</p><p>Router8,Router9,Router10</p><ol><li><p>打开路由器端口,为端口分配IP地址</p></li><li><p>ospf路由</p></li></ol><p>此时左边因为是内部网络所以访问外部网络无法得到响应</p><p>所以需要net地址转换</p><h2 id="1-建立全球ip地址池和私有地址的关联"><a href="#1-建立全球ip地址池和私有地址的关联" class="headerlink" title="1.建立全球ip地址池和私有地址的关联"></a>1.建立全球ip地址池和私有地址的关联</h2><p>Router(config) # access-list 1 permit 192.168.1.0 0.0.0.255 //创建一个编号为1的标准分组过滤器允许转发192.168.1.0的ip分组。 这里规定了nat的私有地址范围</p><p>Router(config) # ip nat pool a1 193.1.4.1 193.1.4.13 netmask 255.255.255.240// 定义全球ip地址池</p><p>Router(config) # ip nat inside source list 1 pool a1 //私有地址和全球ip地址池绑定 </p><h2 id="2-创建静态地址转换项"><a href="#2-创建静态地址转换项" class="headerlink" title="2.创建静态地址转换项"></a>2.创建静态地址转换项</h2><p>Router(config) # ip nat inside source static 192.168.2.3 193.1.4.14 //内部地址和全球地址绑定</p><h2 id="3-配置内部网络连接外部网络接口"><a href="#3-配置内部网络连接外部网络接口" class="headerlink" title="3.配置内部网络连接外部网络接口"></a>3.配置内部网络连接外部网络接口</h2><p>Router(config) # int fa0/0</p><p>Router(config-if) # ip nat inside //将该接口配置为内部网络接口</p><p>Router(config) # int fa1/0</p><p>Router(config-if) # ip nat outside //将该接口配置为外部网络接口</p><h2 id="4-静态路由项配置"><a href="#4-静态路由项配置" class="headerlink" title="4.静态路由项配置"></a>4.静态路由项配置</h2><p>ip route 193.1.4.0 255.255.255.240 193.1.1.1 //193.1.4.0 255.255.255.240为目标网络。193.1.1.1为下一跳的地址。</p><p>Router1</p><p>1.建立全球ip地址池和私有地址的关联</p><p>2.配置内部网络连接外部网络接口</p><p>3.创建静态地址转换项。配置内部网络连接外部网络接口。</p><p>router2,router3</p><p>静态路由项配置(因为外部网络不知道内部网络193.1.4.0的位置,所以需要通过配置静态路由来指引)</p><h1 id="分组过滤器配置实验"><a href="#分组过滤器配置实验" class="headerlink" title="分组过滤器配置实验"></a>分组过滤器配置实验</h1><h2 id="分组过滤器"><a href="#分组过滤器" class="headerlink" title="分组过滤器"></a>分组过滤器</h2><p>Router(config) # access-list 101 permit tcp 193.1.4.0 0.0.0.15 host 193.1.5.3 eq www //建立编号为101的过滤规则,允许193.1.4.0对193.1.5.3转发端口号为www的报文</p><p>Router(config) # access-list 101 permit ospf host 193.1.1.1 any</p><p>Router(config) # access-list 101 deny ip any any</p><h2 id="定义检测机制"><a href="#定义检测机制" class="headerlink" title="定义检测机制"></a>定义检测机制</h2><p>Router(config) # ip inspect name in1 http</p><p>Router(config) # ip inspect name in1 tcp</p><h2 id="作用接口"><a href="#作用接口" class="headerlink" title="作用接口"></a>作用接口</h2><p>Router(config) # int fa0/0</p><p>Router(config) # ip access-group 101 in </p><p>Router(config) # ip access-group 102 out</p><p>Router(config) # ip inspect in1 in</p><h1 id="两个内部网络互连实验"><a href="#两个内部网络互连实验" class="headerlink" title="两个内部网络互连实验"></a>两个内部网络互连实验</h1><p><img src="/2019/11/03/计算机网络总结复习/1572867363366.png" alt></p><h2 id="router0配置"><a href="#router0配置" class="headerlink" title="router0配置"></a>router0配置</h2><h3 id="1-打开两个fa端口,分配ip地址"><a href="#1-打开两个fa端口,分配ip地址" class="headerlink" title="1.打开两个fa端口,分配ip地址"></a>1.打开两个fa端口,分配ip地址</h3><p>int fa0/0</p><p>no shut</p><p>ip addr 192.168.1.254 255.255.255.0</p><p>int fa0/1</p><p>…</p><h3 id="2-内部ip地址和全球ip地址绑定"><a href="#2-内部ip地址和全球ip地址绑定" class="headerlink" title="2.内部ip地址和全球ip地址绑定"></a>2.内部ip地址和全球ip地址绑定</h3><p>access-list 1 permit 192.168.1.0 0.0.0.255</p><p>ip nat pool a1 192.1.1.1 192.1.1.13 netmask 255.255.255.240</p><p>ip nat inside source list 1 pool a1</p><p>ip nat inside source static 192.168.1.3 192.1.1.14</p><h3 id="3-内部网络和外部网络接口配置"><a href="#3-内部网络和外部网络接口配置" class="headerlink" title="3.内部网络和外部网络接口配置"></a>3.内部网络和外部网络接口配置</h3><p>int fa0/0</p><p>ip nat inside</p><p>int fa0/1</p><p>ip nat outside</p><h3 id="4-配置静态路由,到另一个内部网络的路由"><a href="#4-配置静态路由,到另一个内部网络的路由" class="headerlink" title="4.配置静态路由,到另一个内部网络的路由"></a>4.配置静态路由,到另一个内部网络的路由</h3><p>ip route 192.1.2.0 255.255.255.240 192.1.3.2</p><h1 id="isp-网络设计"><a href="#isp-网络设计" class="headerlink" title="isp 网络设计"></a>isp 网络设计</h1><p><img src="/2019/11/03/计算机网络总结复习/1572869270843.png" alt></p><h2 id="1-配置串行接口"><a href="#1-配置串行接口" class="headerlink" title="1.配置串行接口"></a>1.配置串行接口</h2><p>在2811路由器中添加serial接口wic-2T。</p><p>int Serial0/3/0</p><p>clock rate 4000000 //dce一侧需要设置定时器</p><p>no shut</p><p>ip addr 192.1.3.1 255.255.255.252 </p><p>encapsulation ppp //配置协议</p><p>ppp authtication chap //建立连接需要验证身份</p><h2 id="2-配置鉴别信息"><a href="#2-配置鉴别信息" class="headerlink" title="2.配置鉴别信息"></a>2.配置鉴别信息</h2><p>hostname Router1 //设置本机的身份</p><p>username Router2 password 1234 //指定对方路由器的身份为router2,共享密码要相同都为1234</p><h2 id="3-配置RIP"><a href="#3-配置RIP" class="headerlink" title="3.配置RIP"></a>3.配置RIP</h2><p>router rip</p><p>version 2</p><p>no auto-summary</p><p>network 192.1.1.0</p><p>network 192.1.3.0</p>]]></content>
<categories>
<category> 其他 </category>
</categories>
<tags>
<tag> 计算机网络 </tag>
</tags>
</entry>
<entry>
<title>nodejs和前端js模块导出和引入</title>
<link href="/2019/11/02/nodejs%E5%92%8C%E5%89%8D%E7%AB%AFjs%E6%A8%A1%E5%9D%97%E5%AF%BC%E5%87%BA%E5%92%8C%E5%BC%95%E5%85%A5/"/>
<url>/2019/11/02/nodejs%E5%92%8C%E5%89%8D%E7%AB%AFjs%E6%A8%A1%E5%9D%97%E5%AF%BC%E5%87%BA%E5%92%8C%E5%BC%95%E5%85%A5/</url>
<content type="html"><![CDATA[<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>经常容易忘记node的模块导入和导出的细节,还有就是上次作业node和前端js导入导出分不清,所以特意进行测试记录</p><h1 id="node中模块导入和导出"><a href="#node中模块导入和导出" class="headerlink" title="node中模块导入和导出"></a>node中模块导入和导出</h1><p><a href="https://segmentfault.com/a/1190000014305806#articleHeader10" target="_blank" rel="noopener">学习网址</a></p><h2 id="module"><a href="#module" class="headerlink" title="module"></a>module</h2><p>node中的module对象,通过console.log(),可以看到以下结果</p><pre><code class="js">Module { id: '.', exports: {}, parent: null, filename: 'D:\\vscode_work\\houduanwork\\test\\test.js', loaded: false, children: [], paths: [ 'D:\\vscode_work\\houduanwork\\test\\node_modules', 'D:\\vscode_work\\houduanwork\\node_modules', 'D:\\vscode_work\\node_modules', 'D:\\node_modules' ] }</code></pre><blockquote><p>module.filename 模块的文件名,带有绝对路径。<br>module.loaded 返回一个布尔值,表示模块是否已经完成加载。<br>module.parent 返回一个对象,表示调用该模块的模块对象。<br>module.children 返回一个数组,表示该模块要用到的其他模块对象。<br>module.exports 表示模块对外输出的值。</p></blockquote><h2 id="module-exports和exports"><a href="#module-exports和exports" class="headerlink" title="module.exports和exports"></a>module.exports和exports</h2><p>module.exports={a:”1”,b:”2”}</p><p>exports.a:”1”</p><p>exports.b:”2”</p><p>module.exports和exports两者结果相同.</p><p>本质上两者等同于如下关系。公用同一个对象。</p><pre><code class="js">let exports = module.exports;</code></pre><p>在新版的node中不支持export和export default。<strong>所以在node中文件导出基本就是对module.exports进行操作.</strong></p><h2 id="require"><a href="#require" class="headerlink" title="require"></a>require</h2><p>//foo.js</p><pre><code class="js">var firstName = 'Michael';var lastName = 'Jackson';exports.ahh = firstName;exports.lastName = lastName;</code></pre><p>//test.js</p><pre><code class="js">const hh = require('./foo');console.log(hh);//{ ahh: 'Michael', lastName: 'Jackson' }</code></pre><p>require接受的是对应的module.exports中的数据,一般为对象.所以经常用解构赋值获取其中的值.</p><pre><code class="js">const {ahh,lastName} = require('./foo');console.log(ahh,lastName);//Michael Jackson</code></pre><p>require同一个文件多次只有最后一次有效.</p><p>导入模块在node中只有require.</p><h1 id="在前端js中的模块导入和导出"><a href="#在前端js中的模块导入和导出" class="headerlink" title="在前端js中的模块导入和导出"></a>在前端js中的模块导入和导出</h1><p><a href="http://es6.ruanyifeng.com/#docs/module" target="_blank" rel="noopener">学习网址</a></p><p>在非webpack中,在html引入需要引用其他模块的js,需要将 type=”module” 否则</p><p>出现Cannot use import statement outside a module</p><pre><code class="html"><script src="./test.js" type="module"></script></code></pre><h2 id="export"><a href="#export" class="headerlink" title="export"></a>export</h2><p>export导出模块要注意写法,因为export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系,也就是说必须要提供一个key一个value值。下面的错误写法,本质上都是只提供了一个值。</p><p>错误写法:</p><pre><code class="javascript">// 报错export 1;// 报错var m = 1;export m;</code></pre><p>正确写法:</p><pre><code class="javascript">// 写法一export var m = 1;// 写法二var m = 1;export {m};</code></pre><p>同理 function和class的输出,也遵循这种写法</p><pre><code class="javascript">// 报错function f() {}export f;// 正确export function f() {};// 正确function f() {}export {f};</code></pre><p>export可以任意位置,任意多个,但是不能放在块级作用域比如说函数中</p><h2 id="import"><a href="#import" class="headerlink" title="import"></a>import</h2><p>通过import…from加载模块,变量名必须和接口名一致,可以通过as进行重命名</p><pre><code>import {a,b} from "./foo.js"import {a,b as ahh} from "./foo.js"</code></pre><p>import 可以直接去执行被import的模块</p><p>test.js</p><pre><code class="js">import "./foo.js"</code></pre><p>foo.js</p><pre><code class="js">console.log("233")//浏览器中可以看到输出</code></pre><h2 id="export-default"><a href="#export-default" class="headerlink" title="export default"></a>export default</h2><p>相比较与export,export default不需要知道所要加载的变量名称。使用import时可以任意命名。</p><p>test.js</p><pre><code class="js">import ahh from "./foo.js"ahh()//foo</code></pre><p>foo.js</p><pre><code class="js">export default function () { console.log('foo');}</code></pre><p>export default中函数名在模块外部无效。</p><pre><code class="js">// export-default.jsexport default function foo() { console.log('foo');}// 或者写成 在export中这种写法无效function foo() { console.log('foo');}export default foo;</code></pre><p>export default 本质上就是输出一个default的变量或者方法</p><pre><code class="javascript">// modules.jsfunction add(x, y) { return x * y;}export {add as default};// 等同于// export default add;// app.jsimport { default as foo } from 'modules';// 等同于// import foo from 'modules';</code></pre><p>因此</p><pre><code class="js">// 正确export var a = 1;// 正确var a = 1;export default a;// 错误export default var a = 1;// 正确export default 42;// 报错export 42;</code></pre>]]></content>
<categories>
<category> 前端 </category>
<category> 后端 </category>
</categories>
<tags>
<tag> javascript </tag>
<tag> nodejs </tag>
</tags>
</entry>
<entry>
<title>nodejs随笔记录</title>
<link href="/2019/10/31/nodejs%E9%9A%8F%E7%AC%94%E8%AE%B0%E5%BD%95/"/>
<url>/2019/10/31/nodejs%E9%9A%8F%E7%AC%94%E8%AE%B0%E5%BD%95/</url>
<content type="html"><![CDATA[<h2 id="关于中间件"><a href="#关于中间件" class="headerlink" title="关于中间件"></a>关于中间件</h2><p>中间件在nodejs中功能是访问请求对象req,响应对象res,修改或者解析这两者对象,将新的对象属性插入其中。</p><h3 id="body-parser"><a href="#body-parser" class="headerlink" title="body-parser"></a>body-parser</h3><p>主要用于解析请求体,并将解析完成的请求体添加到req中,通过req.body可以获取得到</p><pre><code class="js">var bodyParser = require('body-parser');//To parse URL encoded dataapp.use(bodyParser.urlencoded({ extended: false }))//To parse json dataapp.use(bodyParser.json())...//在post请求中,通过req.body得到数据app.post('/', function(req, res){ let params = JSON.stringify(req.body) console.log(params) res.send(params)});</code></pre><h3 id="cookie-parser-cookie解析器"><a href="#cookie-parser-cookie解析器" class="headerlink" title="cookie-parser cookie解析器"></a>cookie-parser cookie解析器</h3><p>同理。将cookie添加到req.cookies中。</p><pre><code class="js">var cookieParser = require('cookie-parser');app.use(cookieParser())</code></pre><h2 id="静态文件"><a href="#静态文件" class="headerlink" title="静态文件"></a>静态文件</h2><pre><code class="js">//创建静态目录,在src下的图片可以通过以下方式进行访问静态资源//http://localhost:3000/1.jpegapp.use(express.static(path.join(__dirname, '/src')));</code></pre><p>虚拟路径前缀</p><pre><code class="js">//增加一个虚拟前缀//http://localhost:3000/static/1.jpegapp.use('/static', express.static('public'));</code></pre><h2 id="multer"><a href="#multer" class="headerlink" title="multer"></a>multer</h2><p>用于multipart/form-data的body,文件上传,批量上传</p><p>简单用法.将上传的文件保存到file中。高级用法详见github文档</p><pre><code class="js">var multer = require('multer')var upload = multer( {dest:'uploads'})app.post('/', upload.single('avatar'), function (req, res, next) { let file = req.file let params = req.body res.send('upload finished')})</code></pre>]]></content>
<categories>
<category> 后端 </category>
</categories>
<tags>
<tag> nodejs </tag>
</tags>
</entry>
<entry>
<title>vue-router</title>
<link href="/2019/10/18/vue-router/"/>
<url>/2019/10/18/vue-router/</url>
<content type="html"><![CDATA[<h1 id="vue-router"><a href="#vue-router" class="headerlink" title="vue-router"></a>vue-router</h1><h3 id="路由对象属性"><a href="#路由对象属性" class="headerlink" title="路由对象属性"></a>路由对象属性</h3><ul><li><p><strong>$route.path</strong></p><ul><li><p>类型: <code>string</code></p><p>字符串,对应当前路由的路径,总是解析为绝对路径,如 <code>"/foo/bar"</code>。</p></li></ul></li><li><p><strong>$route.params</strong> </p><p>params 参数,获取动态路由的参数</p><ul><li><p>类型: <code>Object</code></p><p>一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。</p></li></ul></li><li><p><strong>$route.query</strong></p><p>query 查询 ,获取url ?后的查询参数</p><ul><li><p>类型: <code>Object</code></p><p>一个 key/value 对象,表示 URL 查询参数。例如,对于路径 <code>/foo?user=1</code>,则有 <code>$route.query.user == 1</code>,如果没有查询参数,则是个空对象。</p></li></ul></li><li><p><strong>this.$router.push()</strong></p><p>描述:跳转到不同的url,但这个方法会向history栈添加一个记录,点击后退会返回到上一个页面。</p></li><li><p><strong>this.$router.replace()</strong></p><p>描述:同样是跳转到指定的url,但是这个方法不会向history里面添加新的记录,点击返回,会跳转到上上一个页面。上一个记录是不存在的。</p></li></ul>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> vue-router </tag>
</tags>
</entry>
<entry>
<title>vuex</title>
<link href="/2019/10/18/vuex/"/>
<url>/2019/10/18/vuex/</url>
<content type="html"><![CDATA[<h1 id="vuex"><a href="#vuex" class="headerlink" title="vuex"></a>vuex</h1><p>建立store.js</p><pre><code class="vue">import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({ state: { number:0, }, mutations: { ADD(state){ state.number++ }, SUB(state){ state.number-- } }, actions: { }})</code></pre><p>在main.js中,将状态从根组件“注入”到每一个子组件中</p><pre><code class="vue">new Vue({ render: h => h(App), store}).$mount('#app')</code></pre><p>在子组件中可以通过$store.state.number进行调用</p><h2 id="state属性"><a href="#state属性" class="headerlink" title="state属性"></a>state属性</h2><p>类似与vue中data属性,用于存放属性,键值对。可以通过 mutations 和 actions 来改变state的值。使用this.$store.state.属性名称 来获取相应的值。</p><h2 id="getters属性"><a href="#getters属性" class="headerlink" title="getters属性"></a>getters属性</h2><p>getters我们类比到vue中,那么它应该是 computed了 我们在使用的时候要使用 this.$store.getters.属性名 。用法也和computed类似,它实际上是调用一个方法,然后获取到的数据是经过一系列处理后并且return回来的数据。</p><h2 id="mutations"><a href="#mutations" class="headerlink" title="mutations"></a>mutations</h2><p>类似与vue的methods。可以通过调用其中的函数来修改state的值。this.$store.commit(‘ADD’)来调用mutations中的方法。</p><h2 id="actions属性"><a href="#actions属性" class="headerlink" title="actions属性"></a>actions属性</h2><p>actions属性用法和mutations类似,但是actions我们是不可以修改state的 需要在actions通过commit来调用mutations来修改数据,那么action的意义何在呢?处理异步事件就要用action来做了呀。调用方法是,this.$store.dispatch(“action的名字”,参数)</p><p>actions 方法的第一个参数是context,类似与store实例,可以调用 <code>context.commit</code> 提交一个 mutation,或者通过 <code>context.state</code> 和 <code>context.getters</code> 来获取 state 和 getters。</p><p>常用法,获取context中的commit方法,提交commit调用mutations来修改数据</p><pre><code class="js">actions: { increment ({ commit }) { commit('increment') }}</code></pre><p>综合示例</p><pre><code>// store.jsimport Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({ state: { number:0, }, mutations: { ADD(state){ state.number++ }, SUB(state){ state.number-- }, ADDPARAM(state,param){ if (typeof param !== 'number'){ param = 0 } state.number = state.number + param } }, actions: { ASYNCADD(context,param){ //这里我们传入context上下文,里面包含 commit, state ,getters 这三个属性都可以通过context来调用到并且触发内部方法 setTimeout(function(){ context.commit('ADDPARAM',param) },1000) } }, getters:{ getNumber(state){ //getter的书写方法 return state.number + 100 } }})</code></pre><pre><code><!-- children.vue --><template> <div class="children"> <h1>This is an children page</h1> <button @click="add"> + </button> {{$store.state.number}} {{$store.getters.getNumber}} <button @click="sub"> - </button> <button @click="actAdd">action</button> </div></template><script> export default{ name: 'children', methods: { add() {</code></pre><h2 id="modules"><a href="#modules" class="headerlink" title="modules"></a>modules</h2><p>Vuex 允许我们将 store 分割成<strong>模块(module)</strong>。每个模块拥有自己的 state、mutation、action、getter</p><pre><code class="js">const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... }}const moduleB = { state: { ... }, mutations: { ... }, actions: { ... }}const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB }})</code></pre><p>对于模块内部的 mutation 和 getter,接收的第一个参数是<strong>模块的局部状态对象</strong>。</p><pre><code class="js">const moduleA = { state: { count: 0 }, mutations: { increment (state) { // 这里的 `state` 对象是模块的局部状态 state.count++ } }, getters: { doubleCount (state) { return state.count * 2 } }}</code></pre><p>对于模块内部的 action,局部状态通过 <code>context.state</code> 暴露出来,根节点状态则为 <code>context.rootState</code></p><pre><code class="js">const moduleA = { // ... actions: { incrementIfOddOnRootSum ({ state, commit, rootState }) { if ((state.count + rootState.count) % 2 === 1) { commit('increment') } } }}</code></pre>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> vuex </tag>
</tags>
</entry>
<entry>
<title>vue-element-admin学习之旅</title>
<link href="/2019/10/18/vue-element-admin%E5%AD%A6%E4%B9%A0%E4%B9%8B/"/>
<url>/2019/10/18/vue-element-admin%E5%AD%A6%E4%B9%A0%E4%B9%8B/</url>
<content type="html"><![CDATA[<p><a href="https://juejin.im/post/59097cd7a22b9d0065fb61d2#heading-11" target="_blank" rel="noopener">学习网址</a></p><h1 id="axios封装"><a href="#axios封装" class="headerlink" title="axios封装"></a>axios封装</h1><p>在vue-element-admin中,已经对axios进行了封装。其中下面的requset.js主要是使用axios.create创建一个实例,为这个实例设置基础路径,对请求和响应增设拦截器,进行统一的操作。</p><pre><code class="js">import axios from 'axios'import { MessageBox, Message } from 'element-ui'import store from '@/store'import { getToken } from '@/utils/auth'//@ alias 别名指向src目录 在config.js中设置// 创建axios实例const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url // withCredentials: true, // send cookies when cross-domain requests timeout: 5000 // request timeout})// request 拦截器service.interceptors.request.use( config => { //发送请求之前操作,若存在token则向头部添加x-token if (store.getters.token) { // let each request carry token // ['X-Token'] is a custom headers key // please modify it according to the actual situation config.headers['X-Token'] = getToken() } return config }, error => { // do something with request error console.log(error) // for debug return Promise.reject(error) })// 响应拦截器service.interceptors.response.use( /** * If you want to get http information such as headers or status * Please return response => response */ /** * Determine the request status by custom code * Here is just an example * You can also judge the status by HTTP Status Code */ response => { const res = response.data //根据返回码进行相应的处理 // if the custom code is not 20000, it is judged as an error. if (res.code !== 20000) { Message({ message: res.message || 'Error', type: 'error', duration: 5 * 1000 }) // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; if (res.code === 50008 || res.code === 50012 || res.code === 50014) { // to re-login MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { confirmButtonText: 'Re-Login', cancelButtonText: 'Cancel', type: 'warning' }).then(() => { store.dispatch('user/resetToken').then(() => { location.reload() }) }) } return Promise.reject(new Error(res.message || 'Error')) } else { return res } }, error => { console.log('err' + error) // for debug Message({ message: error.message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) })export default service</code></pre><p>以这个实例为基础,在@/api 中添加配置,加入请求路径,请求方法,请求数据。</p><pre><code class="js">import request from '@/utils/request'export function fetchList(query) { return request({ url: '/article/list', method: 'get', params: query })}</code></pre><p>这样只需要在对应的页面中调用该方法发起请求,然后写处理函数。</p><p>fetchList(query).then(res=>{</p><p>})</p><h1 id="Swagger"><a href="#Swagger" class="headerlink" title="Swagger"></a>Swagger</h1><h1 id="easy-mock"><a href="#easy-mock" class="headerlink" title="easy-mock"></a>easy-mock</h1><h1 id="登录流程与权限控制"><a href="#登录流程与权限控制" class="headerlink" title="登录流程与权限控制"></a>登录流程与权限控制</h1><ol><li>触发click事件触发登录操作。执行vuex中响应的action</li></ol><pre><code class="js">this.$store.dispatch('user/login', this.loginForm) .then(() => { this.$router.push({ path: this.redirect || '/', query: this.otherQuery }) this.loading = false }) .catch(() => { this.loading = false })</code></pre><ol start="2"><li>action。action返回一个promise,供上面继续操作。在action中调用api中的login登录函数,若登录成功则将token放入vuex和cookie中。login函数则是上方axios封装过后的函数。</li></ol><pre><code class="js">login({ commit }, userInfo) { const { username, password } = userInfo //返回一个promise实例 return new Promise((resolve, reject) => { //登录请求函数 login({ username: username.trim(), password: password }).then(response => { const { data } = response //调用commit设置token commit('SET_TOKEN', data.token) //token存入cookie中 setToken(data.token) //执行成功 resolve() }).catch(error => { //执行出错,传递错误原因 reject(error) }) }) }</code></pre><ol start="3"><li>获取用户信息。获取用户信息和登录获取token分隔开。获取信息的时机在全局钩子<code>router.beforeEach</code>中拦截路由,判断是否已获得token,在获得token之后去获取用户的基本信息。也就是说每一次路由跳转的时候会进行检测,是否有token,没有则进行登录。有那么查看vuex是否有身份信息,如果有则进入指定路由。如果没有身份信息则通过token去获取身份信息。 </li></ol><pre><code class="js">// ./permission.js router.beforeEach(async(to, from, next) => { // 进度条显示 NProgress.start() // 设置页面标题 document.title = getPageTitle(to.meta.title) // 从cookie中得到token const hasToken = getToken() // token存在 if (hasToken) { if (to.path === '/login') { // 如果已经有了token,说明已经登录,那么这是前往登录路由的,重定向到初始页面 next({ path: '/' }) //进度条结束 NProgress.done() } else {//有了token进入其他路由 // determine whether the user has obtained his permission roles through getInfo // 判断当前用户是否已拉取完user_info信息 const hasRoles = store.getters.roles && store.getters.roles.length > 0 if (hasRoles) { //已经有身份信息,进入目标路由 next() } else {//没有身份信息,去获取身份信息 try { // get user info // note: roles must be a object array! such as: ['admin'] or ,['developer','editor'] //拉去成功获得其中的身份信息 const { roles } = await store.dispatch('user/getInfo') // 生成路由,返回为增加的路由 const accessRoutes = await store.dispatch('permission/generateRoutes', roles) // dynamically add accessible routes //动态添加路由规则,为原本的路由添加上上述的生成路由 router.addRoutes(accessRoutes) // hack method to ensure that addRoutes is complete // set the replace: true, so the navigation will not leave a history record //复制to的路由对象解构 next({ ...to, replace: true }) } catch (error) { // 获取失败,移除token await store.dispatch('user/resetToken') //打印消息 Message.error(error || 'Has Error') //返回登录页面 next(`/login?redirect=${to.path}`) NProgress.done() } } } } else { /* has no token */ // 目的页面是否在白名单,如果是前往,不是回到登录页面 if (whiteList.indexOf(to.path) !== -1) { // in the free login whitelist, go directly next() } else { // other pages that do not have permission to access are redirected to the login page. next(`/login?redirect=${to.path}`) NProgress.done() } }})</code></pre><p>4.权限控制。</p><ol><li>创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载登录页面或者一些不用权限的公用页面。 </li></ol><pre><code class="js">export const constantRoutes = [ { path: '/login', component: () => import('@/views/login/index'), hidden: true }, { path: '/auth-redirect', component: () => import('@/views/login/auth-redirect'), hidden: true }, { path: '/404', component: () => import('@/views/error-page/404'), hidden: true }, { path: '/401', component: () => import('@/views/error-page/401'), hidden: true }, { path: '/', component: Layout, redirect: '/dashboard', children: [ { path: 'dashboard', component: () => import('@/views/dashboard/index'), name: 'Dashboard', meta: { title: 'Dashboard', icon: 'dashboard', affix: true } } ] }, ] }]</code></pre><ol start="2"><li>当用户登录后,获取用role,将role和下面的路由表每个页面的需要的权限作比较(meta中的roles数组中存在),将该路由加入数组中,使用router.addRoutes()加入生成的路由,最终生成用户可访问的路由表。 </li></ol><pre><code class="js">export const asyncRoutes = [ { path: '/permission', component: Layout, redirect: '/permission/page', alwaysShow: true, // will always show the root menu name: 'Permission', meta: { title: 'Permission', icon: 'lock', roles: ['admin', 'editor'] // you can set roles in root nav }, //... //... ]</code></pre><pre><code class="js">generateRoutes({ commit }, roles) { return new Promise(resolve => { let accessedRoutes // 如果包含管理员身份,管理员身份可以访问所有路由 if (roles.includes('admin')) { accessedRoutes = asyncRoutes || [] } else { //不是管理员的按照路由表中meta中的roles数组如果有对应的role则全部进行返回 accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) } commit('SET_ROUTES', accessedRoutes) //返回增加的路由 resolve(accessedRoutes) }) }</code></pre><ol start="3"><li>使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件。</li></ol>]]></content>
<categories>
<category> 前端 </category>
</categories>
<tags>
<tag> vue </tag>
<tag> vue-element-admin </tag>
</tags>
</entry>
<entry>
<title>es6记录</title>
<link href="/2019/10/16/es6%E8%AE%B0%E5%BD%95/"/>
<url>/2019/10/16/es6%E8%AE%B0%E5%BD%95/</url>
<content type="html"><![CDATA[<h2 id="Object-values"><a href="#Object-values" class="headerlink" title="Object.values()"></a>Object.values()</h2><p>获取传入对象的值的数组</p><h2 id="Object-keys"><a href="#Object-keys" class="headerlink" title="Object.keys()"></a>Object.keys()</h2><p>获取传入对象的键的数组</p><h2 id="Object-entries"><a href="#Object-entries" class="headerlink" title="Object.entries()"></a>Object.entries()</h2><p>获取传入对象的数组形式的键值对</p><pre><code class="javascript">const cars = {bmw:3, tesla:2, toyota:1}const keys = Object.keys(cars)const vals = Object.values(cars)const entries = Object.entries(cars)console.log(vals,keys)console.log(entries)</code></pre><p>[ 3, 2, 1 ] [ ‘bmw’, ‘tesla’, ‘toyota’ ]<br>[ [ ‘bmw’, 3 ], [ ‘tesla’, 2 ], [ ‘toyota’, 1 ] ]</p><h2 id="函数默认参数"><a href="#函数默认参数" class="headerlink" title="函数默认参数"></a>函数默认参数</h2><p>es6开始,直接在参数行赋值默认参数</p><pre><code class="javascript">function test(a=50,b=100){ console.log(a,b)}test(5)</code></pre><p>5 100</p><h2 id="模板对象"><a href="#模板对象" class="headerlink" title="模板对象"></a>模板对象</h2><pre><code class="js">// OLDvar name = 'Your name is ' + first + ' ' + last + '.';var url = 'http://localhost:3000/api/messages/' + id;// ES6语法 `${NAME}` 不是引号哦 tab建上方var name = `Your name is ${first} ${last}. `;var url = `http://localhost:3000/api/messages/${id}`;</code></pre><h2 id="多行字符串"><a href="#多行字符串" class="headerlink" title="多行字符串"></a>多行字符串</h2><pre><code class="js">var roadPoem = `Then took the other, as just as fair, And having perhaps the better claim Though as for that the passing there Had worn them really about the same,`;</code></pre><h2 id="结构赋值"><a href="#结构赋值" class="headerlink" title="结构赋值"></a>结构赋值</h2><h4 id="对象解构"><a href="#对象解构" class="headerlink" title="对象解构"></a>对象解构</h4><p>要求接受属性名和解构对象的属性一一对应</p><pre><code class="js">let node = { type: "Identifier", name: "foo"};let { type, name } = node;console.log(type); // "Identifier"console.log(name); // "foo"</code></pre><p>一定要用一对小括号包裹解构赋值语句,JS引擎将一对开放的花括号视为一个代码块。语法规定,代码块语句不允许出现在赋值语句左侧,添加小括号后可以将块语句转化为一个表达式,从而实现整个解构赋值过程</p><pre><code class="js">let node = { type: "Identifier", name: "foo"},type = "Literal",name = 5;// 使用解构来分配不同的值({ type, name } = node);console.log(type); // "Identifier"console.log(name); // "foo"</code></pre><p>可以为变量设置默认值,如果它可能不存在node中</p><pre><code class="js">let node = { type: "Identifier", name: "foo"};let { type, name, value = true } = node;console.log(type); // "Identifier"console.log(name); // "foo"console.log(value); // true</code></pre><p>为非同名变量赋值</p><pre><code class="js">let node = { type: "Identifier", name: "foo"};let { type: localType, name: localName } = node;console.log(localType); // "Identifier"console.log(localName); // "foo"</code></pre><p>为非同名变量设初始值</p><pre><code class="js">let node = { type: "Identifier"};let { type: localType, name: localName = "bar" } = node;console.log(localType); // "Identifier"console.log(localName); // "bar"</code></pre><h4 id="数组解构"><a href="#数组解构" class="headerlink" title="数组解构"></a>数组解构</h4><p>数组解构与对象解构略有不同,数组解构按照位置进行解构,和对象不同,数组解构赋值不需要加括号</p><pre><code class="js">let colors = [ "red", "green", "blue" ],firstColor = "black",secondColor = "purple";[ firstColor, secondColor ] = colors;console.log(firstColor); // "red"console.log(secondColor); // "green"</code></pre><p>变量交换,无需第三变量</p><pre><code class="js">// 在 ES6 中互换值let a = 1, b = 2;[ a, b ] = [ b, a ];console.log(a); // 2console.log(b); // 1</code></pre><p>设置默认值,同理</p><pre><code>let colors = [ "red" ];let [ firstColor, secondColor = "green" ] = colors;console.log(firstColor); // "red"console.log(secondColor); // "green"</code></pre><p>不定元素</p><pre><code class="js">let colors = [ "red", "green", "blue" ];let [ firstColor, ...restColors ] = colors;console.log(firstColor); // "red"console.log(restColors); // [ 'green', 'blue' ]</code></pre><p>数组复制</p><pre><code class="js">// 在 ES6 中克隆数组let colors = [ "red", "green", "blue" ];let [ ...clonedColors ] = colors;console.log(clonedColors); //"[red,green,blue]"</code></pre><h4 id="字符串同样可以解构"><a href="#字符串同样可以解构" class="headerlink" title="字符串同样可以解构"></a>字符串同样可以解构</h4><pre><code class="js">const [a, b, c, d, e] = 'hello';console.log(a);//"h"console.log(b);//"e"console.log(c);//"l"console.log(d);//"l"console.log(e);//"o"</code></pre><h4 id="字符串集合函数"><a href="#字符串集合函数" class="headerlink" title="字符串集合函数"></a>字符串集合函数</h4><p>查找字符串是否包含在另一个字符串中</p><ul><li>includes():返回布尔值,表示是否找到了参数字符串。</li><li>startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。</li><li>endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。</li></ul><pre><code class="js">let s = 'Hello world!';console.log(s.startsWith('Hello')) // trueconsole.log(s.endsWith('!')) // trueconsole.log(s.includes('o')) // true// 这三个方法都支持第二个参数,表示开始搜索的位置。console.log(s.startsWith('world', 6)) // trueconsole.log(s.endsWith('d',11)) // trueconsole.log(s.includes('Hello', 6)) // false</code></pre><h4 id="repeat()"><a href="#repeat()" class="headerlink" title="repeat()"></a>repeat()</h4><p>返回一个新字符串,将一个字符串重复n次</p><pre><code class="js">console.log("abc".repeat(3)) //abcabcabc</code></pre><h4 id="空白填充"><a href="#空白填充" class="headerlink" title="空白填充"></a>空白填充</h4><p>padStart() 和 padEnd()</p><pre><code class="js">// 第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串。console.log('x'.padStart(5, 'ab')) // 'ababx'console.log('x'.padEnd(5, 'ab')) // 'xabab'// 补全字符串过长时,不全完毕多余的会去除console.log('x'.padStart(5, 'abbbbbbb')) // 'abbbx'console.log('x'.padEnd(5, 'abbbbbbbbb')) // 'xabbb'</code></pre><h4 id="promise"><a href="#promise" class="headerlink" title="promise"></a>promise</h4><p><a href="https://www.jianshu.com/p/82237a7ca6e5" target="_blank" rel="noopener">参考文章</a></p><p>“承诺将来会执行”的对象在JavaScript中称为Promise对象。</p><p>resolve() 表示成功执行,执行时表示执行成功。可以传递参数,会执行.then的回调函数,且可以接受传递的参数</p><p>reject 表示执行失败。同理与resolve()。由.catch()进行接受。</p><pre><code class="js">var promise = new Promise(function (resolve, reject) { var a = 2 if (a== 0) { resolve(a) } else { reject("233") }})promise.then(function (value) { console.log(value);}).catch(function (error) { console.log(error);})//1 //2</code></pre><p>then,catch的返回都是一个新的promise,可以做为下一个then或者catch的参数,执行没有错误后面的then会接受上一个then的参数,执行错误会由下面第一个catch方法来接受</p><pre><code class="js">var promise = new Promise(function (resolve, reject) { resolve()})promise.then(function (value) { // 抛出错误 console.log(1 / x)}).then(function () { // 此方法不会执行 console.log('This "then" method will not happend!')}).catch(function (error) { // 接受错误,并打印出错误 console.log('Have an error: ',error)}).then(function () { // 此方法会执行 console.log('This "then" method will happend!')})</code></pre><p>Promise.all() 和 Promise.race()</p><p>都接受promise对象的数组。</p><p>Promise.all()当这个数组里的所有Promise对象全部变为resolve的时候,该方法才resolve</p><p>Promise.race()只要其中一个Promise对象变为Resolved或者Rejected状态,该方法才resolve</p><h4 id="Async-Await"><a href="#Async-Await" class="headerlink" title="Async/Await"></a>Async/Await</h4><p><a href="https://www.jianshu.com/p/1e75bd387aa0" target="_blank" rel="noopener">参考文章</a></p><p>async/await是一个用同步思维解决异步问题的方案,等待awiat返回结果才会继续执行</p><p>async</p><ul><li><p>自动将常规函数转换成Promise,返回值也是一个Promise对象</p></li><li><p>只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数</p></li><li><p>异步函数内部可以使用await</p></li></ul><pre><code class="js">//async 返回promise对象可以用then去捕获async function doubleAndAdd(a,b) { return a + b}doubleAndAdd(1,2).then(res=>{console.log(res)})</code></pre><p>awiat</p><ul><li>await 后面如果是promise那么等待promise对象resolve的值做为返回结果</li><li>await后面如果不是promise那么同样会等待后面函数或者表达式执行完毕</li><li>await只能在async函数内部使用,用在普通函数里就会报错</li></ul><pre><code class="js">async function doubleAndAdd(a,b) { a = await doubleAfterSec(a) b = await doubleAfterSec(b) return a + b}function doubleAfterSec(param) { return new Promise( resolve =>{ setTimeout(()=> resolve(param*2) ,1000) })}doubleAndAdd(1,2).then(console.log)</code></pre><p>Promise.all的使用,多个await命令不存在依赖关系,即后面的await不依赖前一个await的结果。使用promise.all只有当后面的两个promise对象都完成时,才会同时处理。使用promise.all相比单独的await命令运行更快。</p><pre><code class="js">async function doubleAndAdd(a,b) { [a,b] = await Promise.all([doubleAfterSec(a), doubleAfterSec(b)]); return a + b}</code></pre><p>异常处理</p><p>async返回的是promise对象,通过catch捕获里面的reject异常</p><pre><code class="js">function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(() => { reject('error') }, ms); //reject模拟出错,返回error });}async function asyncPrint(ms) { console.log('start'); await timeout(ms) console.log('end'); //这句代码不会被执行了}asyncPrint(1000).catch(err => { console.log(err); // 从这里捕捉到错误});</code></pre><p>在async内部使用try/catch来捕获异常</p><pre><code class="js">function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(() => { reject('error') }, ms); //reject模拟出错,返回error });}async function asyncPrint(ms) { try { console.log('start'); await timeout(ms); //这里返回了错误 console.log('end'); //所以这句代码不会被执行了 } catch (err) { console.log(err); //这里捕捉到错误error }}asyncPrint(1000);</code></pre><p>提前截住错误。在await出拦截错误。</p><pre><code class="js">function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(() => { reject('error') }, ms); //reject模拟出错,返回error });}async function asyncPrint(ms) { console.log('start'); await timeout(ms).catch(err => { // 注意要用catch console.log(err) }) console.log('end'); //这句代码会被执行}asyncPrint(1000);</code></pre>]]></content>
<categories>
<category> 工具 </category>
</categories>
<tags>
<tag> javascript </tag>
<tag> es6Object </tag>
</tags>
</entry>
<entry>
<title>js小记录</title>
<link href="/2019/10/16/js%E5%B0%8F%E8%AE%B0%E5%BD%95/"/>
<url>/2019/10/16/js%E5%B0%8F%E8%AE%B0%E5%BD%95/</url>
<content type="html"><![CDATA[<h2 id="foreach方法遍历数组"><a href="#foreach方法遍历数组" class="headerlink" title="foreach方法遍历数组"></a>foreach方法遍历数组</h2><p>相对与for循环来遍历数组,更快捷的写法</p><pre><code class="javascript">let a = [1, 2, 3, 4, 5, 6, 7, 8, 9,"151" , 10]a.forEach((value, index ,self) => { console.log(value,index,self) })</code></pre><p>结果为</p><p>1 0 [ 1, 2, 3, 4, 5, 6, 7, 8, 9, ‘151’, 10 ]<br>2 1 [ 1, 2, 3, 4, 5, 10, 7, 8, 9, ‘151’, 10 ]<br>3 2 [ 1, 2, 3, 4, 5, 10, 7, 8, 9, ‘151’, 10 ]<br>4 3 [ 1, 2, 3, 4, 5, 10, 7, 8, 9, ‘151’, 10 ]<br>5 4 [ 1, 2, 3, 4, 5, 10, 7, 8, 9, ‘151’, 10 ]<br>10 5 [ 1, 2, 3, 4, 5, 10, 7, 8, 9, ‘151’, 10 ]<br>7 6 [ 1, 2, 3, 4, 5, 10, 7, 8, 9, ‘151’, 10 ]<br>8 7 [ 1, 2, 3, 4, 5, 10, 7, 8, 9, ‘151’, 10 ]<br>9 8 [ 1, 2, 3, 4, 5, 10, 7, 8, 9, ‘151’, 10 ]<br>151 9 [ 1, 2, 3, 4, 5, 10, 7, 8, 9, ‘151’, 10 ]<br>10 10 [ 1, 2, 3, 4, 5, 10, 7, 8, 9, ‘151’, 10 ]</p><p>foreach方法</p><p>传入一个回调函数,回调函数参数为 值,序号,数组本身</p><ul><li><p>foreach方法没有返回值</p></li><li><p>foreach方法会忽略数组中undefine的值</p></li></ul><h2 id="map方法"><a href="#map方法" class="headerlink" title="map方法"></a>map方法</h2><p>与foreach方法类似</p><pre><code class="javascript">let a = [1, 2, 3, 4, 5, 6, 7, 8, 9, , 10]let b = a.map((value, index ,self) => { return [value,index] })console.log(b)</code></pre><p>[ [ 1, 0 ],<br> [ 2, 1 ],<br> [ 3, 2 ],<br> [ 4, 3 ],<br> [ 5, 4 ],<br> [ 6, 5 ],<br> [ 7, 6 ],<br> [ 8, 7 ],<br> [ 9, 8 ],<br> <1 empty item>,<br> [ 10, 10 ] ]</p><p>不同的是map方法有返回值,map方法会遍历数组,return的结果最后会被组合成为一个新的数组返回。且map方法不会跳过空白值。</p><h2 id="for-in遍历数组"><a href="#for-in遍历数组" class="headerlink" title="for in遍历数组"></a>for in遍历数组</h2><p>主要用于对象,用于数组可能不是按数组内部顺序进行遍历,for in遍历数组的索引值。主要用于普通对象。</p><h2 id="for-of-遍历数组"><a href="#for-of-遍历数组" class="headerlink" title="for of 遍历数组"></a>for of 遍历数组</h2><p>相较于for in,for of遍历数组的值,相较于foreach,for of可以使用break,continue等。可应用maps,set,array等可迭代对象,以及类数组对象。但是一般对象无法使用。要想遍历所有对象,搭配object.keys()来使用。</p><pre><code class="javascript">const iterable = [1,,8,454];for(let i of iterable){ console.log(i)}</code></pre><p>1<br>undefined<br>8<br>454</p><pre><code class="javascript">const iterable = new Map([['one', 1], ['two', 2]]);for (const [key, value] of iterable) { console.log(`Key: ${key} and Value: ${value}`);}</code></pre><p>Key: one and Value: 1<br>Key: two and Value: 2</p>]]></content>
<categories>
<category> 工具 </category>
</categories>
<tags>
<tag> javascript </tag>
</tags>
</entry>
<entry>
<title>markdown</title>
<link href="/2019/10/11/markdown/"/>
<url>/2019/10/11/markdown/</url>
<content type="html"><![CDATA[<h2 id="markdown-标题"><a href="#markdown-标题" class="headerlink" title="markdown 标题"></a>markdown 标题</h2><pre><code># 一级标题## 二级标题### 三级标题#### 四级标题##### 五级标题###### 六级标题</code></pre><h1 id="一级标题"><a href="#一级标题" class="headerlink" title="一级标题"></a>一级标题</h1><h2 id="二级标题"><a href="#二级标题" class="headerlink" title="二级标题"></a>二级标题</h2><h3 id="三级标题"><a href="#三级标题" class="headerlink" title="三级标题"></a>三级标题</h3><h4 id="四级标题"><a href="#四级标题" class="headerlink" title="四级标题"></a>四级标题</h4><h5 id="五级标题"><a href="#五级标题" class="headerlink" title="五级标题"></a>五级标题</h5><h6 id="六级标题"><a href="#六级标题" class="headerlink" title="六级标题"></a>六级标题</h6><h2 id="字体"><a href="#字体" class="headerlink" title="字体"></a>字体</h2><pre><code>*斜体文本*_斜体文本_**粗体文本**__粗体文本__***粗斜体文本***___粗斜体文本___</code></pre><p><em>斜体文本</em><br><em>斜体文本</em><br><strong>粗体文本</strong><br><strong>粗体文本</strong><br><strong><em>粗斜体文本</em></strong><br><strong><em>粗斜体文本</em></strong></p><h2 id="分割线"><a href="#分割线" class="headerlink" title="分割线"></a>分割线</h2><pre><code>***---</code></pre><hr><hr><h2 id="删除线"><a href="#删除线" class="headerlink" title="删除线"></a>删除线</h2><pre><code>~~haha~~</code></pre><p><del>haha</del></p><h2 id="下划线"><a href="#下划线" class="headerlink" title="下划线"></a>下划线</h2><pre><code><u>带下划线文本</u></code></pre><p><u>带下划线文本</u></p><h2 id="脚注"><a href="#脚注" class="headerlink" title="脚注"></a>脚注</h2><pre><code>创建脚注格式类似这样 [^RUNOOB]。[^RUNOOB]: 菜鸟教程 -- 学的不仅是技术,更是梦想!!!</code></pre><p>创建脚注格式类似这样 [^RUNOOB]。</p><p>[^RUNOOB]: 菜鸟教程 – 学的不仅是技术,更是梦想!!!</p><h2 id="列表"><a href="#列表" class="headerlink" title="列表"></a>列表</h2><pre><code>无序列表 *或+或-均可* 第一项* 第二项* 第三项+ 第一项+ 第二项+ 第三项- 第一项- 第二项- 第三项</code></pre><ul><li><p>第一项</p></li><li><p>第二项</p></li><li><p>第三项</p></li></ul><pre><code>有序列表 1. 第一项2. 第二项3. 第三项</code></pre><pre><code>列表嵌套 回车 删除当前行标识 打四个空格 1. xxxx 回车 二级列表1. 第一项: - 第一项嵌套的第一个元素 - 第一项嵌套的第二个元素2. 第二项: - 第二项嵌套的第一个元素 - 第二项嵌套的第二个元素</code></pre><ol><li><p>第一项:</p><ul><li>第一项嵌套的第一个元素</li><li>第一项嵌套的第二个元素</li></ul></li><li><p>第二项: </p><ul><li><p>1</p></li><li><p>2</p><pre><code>1. xxxx 2. xxxx 3. </code></pre></li></ul></li></ol><h2 id="区块"><a href="#区块" class="headerlink" title="区块"></a>区块</h2><pre><code>> 区块引用> 菜鸟教程> 学的不仅是技术更是梦想</code></pre><blockquote><p>区块引用<br>菜鸟教程<br>学的不仅是技术更是梦想</p></blockquote><pre><code>> 最外层> > 第一层嵌套> > > 第二层嵌套</code></pre><blockquote><p>最外层</p><blockquote><p>第一层嵌套</p><blockquote><p>第二层嵌套</p></blockquote></blockquote></blockquote><pre><code>> 区块中使用列表> 1. 第一项> 2. 第二项> + 第一项> + 第二项> + 第三项</code></pre><blockquote><p>区块中使用列表</p><ol><li>第一项</li><li>第二项</li></ol><ul><li>第一项</li><li>第二项</li><li>第三项</li></ul></blockquote><pre><code>列表中用区块 区块前需要加四个空格* 第一项 > 菜鸟教程 > 学的不仅是技术更是梦想* 第二项</code></pre><ul><li>第一项<blockquote><p>菜鸟教程<br>学的不仅是技术更是梦想</p></blockquote></li><li>第二项</li></ul><h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><pre><code>`printf()` 函数</code></pre><p><code>printf()</code></p><pre><code>代码块```javascript$(document).ready(function () { alert('RUNOOB');});```</code></pre><pre><code class="javascript">$(document).ready(function () { alert('RUNOOB');});</code></pre><h2 id="链接"><a href="#链接" class="headerlink" title="链接"></a>链接</h2><pre><code>这是一个链接 [菜鸟教程](https://www.runoob.com)</code></pre><p>这是一个链接 <a href="https://www.runoob.com" target="_blank" rel="noopener">菜鸟教程</a></p><pre><code><https://www.runoob.com></code></pre><p><a href="https://www.runoob.com" target="_blank" rel="noopener">https://www.runoob.com</a></p><pre><code>链接也可以用变量来代替,文档末尾附带变量地址:这个链接用 1 作为网址变量 [Google][1]这个链接用 runoob 作为网址变量 [Runoob][runoob]然后在文档的结尾为变量赋值(网址) [1]: http://www.google.com/ [runoob]: http://www.runoob.com/</code></pre><p>链接也可以用变量来代替,文档末尾附带变量地址:<br>这个链接用 1 作为网址变量 <a href="http://www.google.com/" target="_blank" rel="noopener">Google</a><br>这个链接用 runoob 作为网址变量 <a href="http://www.runoob.com/" target="_blank" rel="noopener">Runoob</a><br>然后在文档的结尾为变量赋值(网址)</p><h2 id="图片"><a href="#图片" class="headerlink" title="图片"></a>图片</h2><pre><code>![手动](http://static.runoob.com/images/runoob-logo.png)</code></pre><p><img src="http://static.runoob.com/images/runoob-logo.png" alt="手动"></p><pre><code>markdown 无法指定图片大小<img src="http://static.runoob.com/images/runoob-logo.png" width="50%"></code></pre><img src="http://static.runoob.com/images/runoob-logo.png" width="50%"><h2 id="Markdown-表格"><a href="#Markdown-表格" class="headerlink" title="Markdown 表格"></a>Markdown 表格</h2><p>Markdown 制作表格使用 <strong>|</strong> 来分隔不同的单元格,使用 <strong>-</strong> 来分隔表头和其他行。</p><p>语法格式如下:</p><pre><code>| 表头 | 表头 || ---- | ---- || 单元格 | 单元格 || 单元格 | 单元格 |</code></pre><table><thead><tr><th>表头</th><th>表头</th></tr></thead><tbody><tr><td>单元格</td><td>单元格</td></tr><tr><td>单元格</td><td>单元格</td></tr></tbody></table><pre><code>| 左对齐 | 右对齐 | 居中对齐 || :-----| ----: | :----: || 单元格 | 单元格 | 单元格 || 单元格 | 单元格 | 单元格 |</code></pre><table><thead><tr><th align="left">左对齐</th><th align="right">右对齐</th><th align="center">居中对齐</th></tr></thead><tbody><tr><td align="left">单元格</td><td align="right">单元格</td><td align="center">单元格</td></tr><tr><td align="left">单元格</td><td align="right">单元格</td><td align="center">单元格</td></tr></tbody></table><h2 id="高级技巧"><a href="#高级技巧" class="headerlink" title="高级技巧"></a>高级技巧</h2><h3 id="一些html元素"><a href="#一些html元素" class="headerlink" title="一些html元素"></a>一些html元素</h3><p><kbd> <b> <i> <em> <sup> <sub> <br></sub></sup></em></i></b></kbd></p><pre><code>使用 <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> 重启电脑</code></pre><p><kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd> </p><h3 id="转义"><a href="#转义" class="headerlink" title="转义"></a>转义</h3><p>通过添加反斜杠进行转义</p><pre><code>**文本加粗** \*\* 正常显示星号 \*\*</code></pre><p><strong>文本加粗</strong><br>** 正常显示星号 **</p>]]></content>
<categories>
<category> 工具 </category>
</categories>
<tags>
<tag> markdown </tag>
</tags>
</entry>
</search>