首页
统计
墙纸
留言
Search
1
PVE8优化
13 阅读
2
Debian 12 / Ubuntu 22.04 使用源安装 LAMP 教程
12 阅读
3
内核版本 4.9 以上的 Linux 系统开启/关闭 BBR 的方法
10 阅读
4
CSS动画
10 阅读
5
jenkins根据分支、文件夹打包
9 阅读
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
登录
/
注册
Search
标签搜索
vue+elementui
Cicada
累计撰写
161
篇文章
累计收到
57
条评论
首页
栏目
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
页面
统计
墙纸
留言
搜索到
152
篇与
的结果
2020-03-27
flutter布局容器
Row | ColumnRow | Column( mainAxisAlignment: MainAxisAlignment.center, //主轴对齐方式 crossAxisAlignment: CrossAxisAlignment.center, //交叉轴对齐方式 children: <Widget>[] //子部件 }StackStack( //使子部件重叠(必须要有父容器) alignment: Alignment(0,0), //子部件为对齐的对齐方式 children: <Widget>[] //子部件 )PositionedPositioned( top //上偏移 right //右偏移 bottom //下偏移 left //左偏移 child //子部件AspectRatioAspectRatio( //子部件纵横比 aspectRatio: 1 / 1,//宽高比 child: Container( decoration: BoxDecoration(color: Color(0xFFff0000)), ), )ConstrainedBoxConstrainedBox( //约束子部件大小 constraints: BoxConstraints( maxHeight: 200, minWidth: 10, ), child: Container( decoration: BoxDecoration(color: Color(0xFFff0000)), ), )
2020年03月27日
1 阅读
0 评论
0 点赞
2020-03-19
CSS常用片段
清除浮动.clearfix:after { content: "\00A0"; display: block; visibility: hidden; width: 0; height: 0; clear: both; font-size: 0; line-height: 0; overflow: hidden; } .clearfix { zoom: 1; }垂直水平居中绝对定位方式且已知宽高position: absolute; top: 50%; left: 50%; margin-top: -3em; margin-left: -7em; width: 14em; height: 6em;绝对定位 + 未知宽高 + translateposition: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); //需要补充浏览器前缀flex 轻松搞定水平垂直居中(未知宽高)display: flex; align-items: center; justify-content: center;利用绝对定位宽高拉升原理,中心居中元素 position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto;利用相对定位于 CSS3 使元素垂直居中 position: relative; top: 50%; -webkit-transform: -webkit-translateY(-50%); -moz-transform: -moz-translateY(-50%); -o-transform: -o-translateY(-50%); transform: translateY(-50%);文本末尾添加省略号宽度固定,适合单行显示...overflow: hidden; text-overflow: ellipsis; white-space: nowrap;宽度不固定,适合多行以及移动端显示overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;简洁 loading 效果.loading:after { display: inline-block; overflow: hidden; vertical-align: bottom; content: "\2026"; -webkit-animation: ellipsis 2s infinite; } // 动画部分 @-webkit-keyframes ellipsis { from { width: 2px; } to { width: 15px; } }自定义文本选中样式// 注意只能修改这两个属性 字体颜色 选中背景颜色 element::selection { color: green; background-color: pink; }顶角贴纸效果<div class="wrap"> <div class="ribbon"> <a href="#">Fork me on GitHub</a> </div> </div> /* 外层容器几本设置 */ .wrap { width: 160px; height: 160px; overflow: hidden; position: relative; background-color: #f3f3f3; } .ribbon { background-color: #a00; overflow: hidden; white-space: nowrap; position: absolute; /* shadom */ -webkit-box-shadow: 0 0 10px #888; -moz-box-shadow: 0 0 10px #888; box-shadow: 0 0 10px #888; /* rotate */ -webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); /* position */ left: -50px; top: 40px; } .ribbon a { border: 1px solid #faa; color: #fff; display: block; font: bold 81.25% "Helvetica Neue", Helvetica, Arial, sans-serif; margin: 1px 0; padding: 10px 50px; text-align: center; text-decoration: none; /* shadow */ text-shadow: 0 0 5px #444; }input 占位符input::-webkit-input-placeholder { color: green; background-color: #f9f7f7; font-size: 14px; } input::-moz-input-placeholder { color: green; background-color: #f9f7f7; font-size: 14px; } input::-ms-input-placeholder { color: green; background-color: #f9f7f7; font-size: 14px; }移动端可点击元素去处默认边框-webkit-tap-highlight-color: rgba(255, 255, 255, 0);首字下沉element:first-letter { float: left; color: green; font-size: 30px; }鼠标手型a[href], input[type="submit"], input[type="image"], input[type="button"], label[for], select, button { cursor: pointer; }屏蔽 Webkit 移动浏览器中元素高亮效果在访问移动网站时,你会发现,在选中的元素周围会出现一些灰色的框框,使用以下代码屏蔽这种样式-webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;去默认样式//移除常用标签的浏览器默认的 margin 和 padding body, p, h1, h2, h3, h4, h5, h6, dl, dd, ul, ol, th, td, button, figure, input, textarea, form { margin: 0; padding: 0; } //统一 input、select、textarea 宽度 input, select, textarea { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; } table { /*table 相邻单元格的边框间的距离设置为 0*/ border-spacing: 0; /*默认情况下给 tr 设置 border 没有效果,如果 table 设置了边框为合并模式:「border-collapse: collapse;」就可以了*/ border-collapse: collapse; } //移除浏览器部分元素的默认边框 img, input, button, textarea { border: none; -webkit-appearance: none; } input { /*由于 input 默认不继承父元素的居中样式,所以设置:「text-align: inherit」*/ text-align: inherit; } textarea { /*textarea 默认不可以放缩*/ resize: none; } //取消元素 outline 样式 a, h1, h2, h3, h4, h5, h6, input, select, button, option, textarea, optgroup { font-family: inherit; font-size: inherit; font-weight: inherit; font-style: inherit; line-height: inherit; color: inherit; outline: none; } //取消超链接元素的默认文字装 a { text-decoration: none; } ol, ul { /*开发中 UI 设计的列表都是和原生的样式差太多,所以直接给取消 ol,ul 默认列表样式*/ list-style: none; } button, input[type="submit"], input[type="button"] { /*鼠标经过是「小手」形状表示可点击*/ cursor: pointer; } input::-moz-focus-inner { /*取消火狐浏览器部分版本 input 聚焦时默认的「padding、border」*/ padding: 0; border: 0; } //取消部分浏览器数字输入控件的操作按钮 input[type="number"] { -moz-appearance: textfield; } input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { margin: 0; -webkit-appearance: none; }chrome 内核 浏览器 position: fixed 防止抖动position: fixed; -webkit-transform: translateZ(0);强制换行/自动换行/强制不换行/* 强制不换行 */ white-space: nowrap; /* 自动换行 */ word-wrap: break-word; word-break: normal; /* 强制英文单词断行 */ word-break: break-all;
2020年03月19日
2 阅读
0 评论
0 点赞
2020-03-10
flutter容器组件
容器组件(Container)可以理解为在Android中的RelativeLayout或LinearLayout等,在其中你可以放置你想布局的元素控件,从而形成最终你想要的页面布局。当然Flutter中的容器组件作为一个"容器",肯定会有一些给我们提供一些属性来约束我们容器内的组件,下面介绍一下容器组件(Container)的一些常用属性及描述:
2020年03月10日
1 阅读
0 评论
0 点赞
2020-03-10
Flutter MaterialApp - Scaffold - DefaultTabController - AppBar
class App extends StatelessWidget { @override //重写父类 Widget build(BuildContext context) { return MaterialApp( //Material风格app debugShowCheckedModeBanner: false, //关闭状态栏debug home: Home(), theme: ThemeData( //主题 primaryColor: color(0x0075b8), //主题颜色 highlightColor: color(0xffffff, a: 0.4), //高亮颜色 splashColor: color(0xffffff, a: 0.6), //水波颜色 ), ); } } class Home extends StatelessWidget { @override Widget build(BuildContext context) { return DefaultTabController( //TabBar和TabBarView的控制器,它是关联这两个组件的桥梁 length: 3, child: Scaffold( //脚手架组件 appBar: AppBar( //显示在界面顶部的一个AppBar title: Center( child: Text( "首页", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w900, color: color(0xffffff), ), ), ), leading: IconButton( //标题前面显示的一个组件 icon: Icon(Icons.menu), tooltip: "Navigration", onPressed: () => debugPrint("Navigration"), ), actions: <Widget>[ //一个Widget列表一般放按钮 IconButton( icon: Icon(Icons.search), tooltip: "search", onPressed: () => debugPrint("search"), ) ], elevation: 4, //bar阴影默认4 bottom: TabBar( //ab页的选项组件,默认为水平排列。 unselectedLabelColor: color(0xffffff, a: 0.5), indicatorColor: color(0xffffff), indicatorSize: TabBarIndicatorSize.label, indicatorWeight: 2, tabs: <Widget>[ //Tab选项列表 Tab(icon: Icon(Icons.local_florist)), Tab(icon: Icon(Icons.change_history)), Tab(icon: Icon(Icons.directions_bike)), ], ), ), body: TabBarView( //ab页的内容容器,Tab页内容一般处理为随选项卡的改变而改变 children: <Widget>[ Icon(Icons.local_florist, size: 100, color: color(0x0075b8)), Icon(Icons.change_history, size: 100, color: color(0x0075b8)), Icon(Icons.directions_bike, size: 100, color: color(0x0075b8)), ], ), bottomNavigationBar: BottomBar()), ), ); } } class _BottomBar extends State<BottomBar> { int _currentIndex = 0; void _bottomTap(int index) { setState(() { _currentIndex = index; }); } @override Widget build(BuildContext context) { return BottomNavigationBar( type: BottomNavigationBarType.fixed, selectedItemColor: color(0x00000), unselectedItemColor: color(0x999999), currentIndex: _currentIndex, onTap: _bottomTap, items: [ BottomNavigationBarItem( icon: Icon(Icons.home), title: Text("home"), ), BottomNavigationBarItem( icon: Icon(Icons.domain), title: Text("domain"), ), BottomNavigationBarItem( icon: Icon(Icons.people_outline), title: Text("people_outline"), ), ], ); } } Color color(int rgb, {double a = 1}) { if (a < 0) { a = 0; } else if (a > 1) { a = 1; } return Color.fromRGBO( (rgb & 0xFF0000) >> 16, (rgb & 0x00FF00) >> 8, (rgb & 0x0000FF) >> 0, a, ); }
2020年03月10日
2 阅读
0 评论
0 点赞
2020-03-10
Flutter基础二State
StatelessWidgetFlutter中的StatelessWidget是一个不需要状态更改的widget - 它没有要管理的内部状态。当您描述的用户界面部分不依赖于对象本身中的配置信息以及widget的BuildContext 时,无状态widget非常有用。AboutDialog, CircleAvatar和 Text 都是StatelessWidget的子类。无状态widget的build方法通常只会在以下三种情况调用:将widget插入树中时当widget的父级更改其配置时当它依赖的InheritedWidget发生变化时StatefulWidgetStatefulWidget 是可变状态的widget。 使用setState方法管理StatefulWidget的状态的改变。调用setState告诉Flutter框架,某个状态发生了变化,Flutter会重新运行build方法,以便应用程序可以应用最新状态。状态是在构建widget时可以同步读取的信息可能会在widget的生命周期中发生变化。确保在状态改变时及时通知状态 变化是widget实现者的责任。当widget可以动态更改时,需要使用StatefulWidget。 例如, 通过键入表单或移动滑块来更改widget的状态. 或者, 它可以随时间变化 - 或者数据推送更新UICheckbox, Radio, Slider, InkWell, Form, 和 TextField 都是有状态的widget,也是StatefulWidget的子类。如果用户交互或数据改变导致widget改变,那么它就是有状态的。如果一个widget是最终的或不可变的,那么它就是无状态。
2020年03月10日
0 阅读
0 评论
0 点赞
2020-03-02
linux笔记 - vim
剪切和粘贴定位鼠标到剪切的开始位置输入v键开始选择剪切的字符,或者V键是为了选择 整行移动方向键到结束的地方d键是剪切,y键是复制移动鼠标到粘贴的位置输入P是在鼠标位置前粘贴,输入p键是在鼠标的位置后粘贴命令模式使用数字0可以跳到行首使用符号$可以跳到行尾连续按两次小写字母g,光标就能移动到当前文件的开始位置使用大写字母G,光标就能移动到当前文件末尾使用数字+G就可以跳到指定的行了。但是vi本身不显示行数,vim才显示行数。使用小写字母x删除光标所在的字符使用大写字母X删除光标前面的字符连续按两次小写字母d,光标所在行就能被整行删除。使用大写字母D可以删除光标所在行后面的内容使用d+0可以删除光标所在行前面的内容使用小写字母u撤销上一步操作,注意这个操作是撤销上一步操作,当你连按两次的时候,相当于恢复到按u之前。vi的删除其实是剪切,当你删除某个内容以后,立即在某一行,按下小写字母p就能看到,你刚才删除的内容被粘贴在了这里。使用小写字母p把内容粘贴到光标所在行的下一行使用大写字母P把内容粘贴的光标所在行连续按两次小写字母y,即可复制当前行的内容。如果想复制多行,可以使用数字+两次y。在命令模式下,按下小写字母v进入可视模式,然后使用方向键或者h,j,k,l键来移动光标,选中你想选中的内容,然后进行相应的操作。在可视模式下,复制是y,删除是d。查找文本内容,在命令模式下输入反斜杠“/”。然后输入需要查找的内容,按下回车,查找就开始了。如果找不到,他会有一个提示。如果找到了,可以使用小写字母n向下依次查找,使用大写字母N向上依次查找。查找文本内容,把光标移动到某个单词之上,然后按下#键,就能找到文本中所有的该单词。
2020年03月02日
0 阅读
2 评论
0 点赞
2019-12-01
移动硬盘安装系统
点击磁盘管理,右击移动硬盘盘符,选择删除卷,先删除移动硬盘上的所有分区,创建一个10G大小的NTFS格式分区,便于引导windows系统。然后再右键该分区,选择“将该分区标记为活动分区”。然后使用解压缩工具开始解压镜像文件,将解压好的Wwindows的iso镜像文件复制到创建好的移动硬盘活动分区中接着将活动分区激活为引导分区。键盘上按下win+R,打开运行对话框,输入“cmd”,点击确定打开管理里命名窗口,如果你的移动硬盘为G盘,输入下方命令即可激活。输入一段点击一次回车。如果是其他盘符名称就需要将全部的g改为自己的移动硬盘盘符哦g: cd boot bootsect.exe /nt60 g: bootsect.exe /nt60 g: /mbr bootsect.exe /nt60 g: /force
2019年12月01日
0 阅读
0 评论
0 点赞
2019-11-21
Caddy - 方便够用的 HTTPS server
1 安装用过 golang 的应该都知道,golang 程序基本上不会有各种依赖,都是光秃秃一个可执行程序,cp 到 /usr/local/bin 就算安装完成了,所以说安装 caddy 是很简单的,我给出三种方法。1.1 脚本安装curl -s https://getcaddy.com | bashcaddy 官方给出了一个安装脚本,执行上面的命令就可以一键安装 caddy,等执行结束后,使用 which caddy,可以看到 caddy 已经被安装到了 /usr/local/bin/caddy1.2 手动安装https://caddyserver.com/download 点这个链接进入到 caddy 官网的下载界面,网页左侧可以选择平台和插件,如果在 Linux 服务器上使用的话,platform 选择 Linux 64-bit 就可以了,plugins 如果暂时不需要的话,可以不选。然后点击下面的 DOWNLOAD 按钮,就下载到 caddy 了。同理,解压之后用 cp 命令放到 /usr/local/bin/caddy 就完成了安装。image_1bn3mbk8jov2es3vu41l842ac9.png-177.7kB1.3 源码安装go get github.com/mholt/caddy/caddy对于安装了 golang 编译器的同学,只需要执行 go get 就能到 $GOPATH/bin 里,是否 cp 到 /usr/local/bin 里就看心情了。使用源码安装可以安装到最新版本的 caddy,功能上一般是最新的,而且因为是本地编译,性能可能会稍微高一些,但是可能会存在不稳定的现象。2 配置2.1 临时文件服务器Caddy 的配置文件叫做 Caddyfile,Caddy 不强制你把配置文件放到哪个特定文件夹,默认情况下,把 Caddyfile 放到当前目录就可以跑起来了,如下:echo 'localhost:8888' >> Caddyfile echo 'gzip' >> Caddyfile echo 'browse' >> Caddyfile caddy在随便一个目录里执行上面代码,然后在浏览器里打开 http://localhost:8888 发现 caddy 已经启动了一个文件服务器。当临时需要一个 fileserver 的时候(比如共享文件),使用 caddy 会很方便。2.2 生产环境使用当然了,在生产环境使用的时候就不能这么草率的把配置文件放到当前目录了,一般情况下会放到 /etc/caddy 里。sudo mkdir /etc/caddy sudo touch /etc/caddy/Caddyfile sudo chown -R root:www-data /etc/caddy除了配置文件,caddy 会自动生成 ssl 证书,需要一个文件夹放置 ssl 证书。sudo mkdir /etc/ssl/caddy sudo chown -R www-data:root /etc/ssl/caddy sudo chmod 0770 /etc/ssl/caddy因为 ssl 文件夹里会放置私钥,所以权限设置成 770 禁止其他用户访问。最后,创建一下放置网站文件的目录,如果已经有了,就不需要创建了。sudo mkdir /var/www sudo chown www-data:www-data /var/www创建好这些文件和目录了之后,我们需要把 caddy 配置成一个服务,这样就可以开机自动运行,并且管理起来也方便。因为目前大多数发行版都使用 systemd 了,所以这里只讲一下如何配置 systemd,不过 caddy 也支持配置成原始的 sysvinit 服务,具体方法看这里。sudo curl -s https://raw.githubusercontent.com/mholt/caddy/master/dist/init/linux-systemd/caddy.service -o /etc/systemd/system/caddy.service # 从 github 下载 systemd 配置文件 sudo systemctl daemon-reload # 重新加载 systemd 配置 sudo systemctl enable caddy.service # 设置 caddy 服务自启动 sudo systemctl status caddy.service # 查看 caddy 状态3 Caddyfile基本的安装配置搞定之后,最重要的就是如何写 Caddyfile了。可以直接 vim /etc/caddy/Caddyfile 来修改 Caddyfile,也可以再自己电脑上改好然后 rsync 到服务器上。如果修改了 Caddyfile 发现没有生效,是需要执行一下 sudo systemctl restart caddy.service 来重启 caddy 的。3.1 Caddyfile 的格式Caddfile的格式还是比较简单的,首先第一行必须是网站的地址,例如:localhost:8080或lengzzz.com地址可以带一个端口号,那么 caddy 只会在这个端口上开启 http 服务,而不会开启 https,如果不写端口号的话,caddy 会默认绑定 80 和 443 端口,同时启动 http 和 https 服务。地址后面可以再跟一大堆指令(directive)。Caddyfile 的基本格式就是这样,由一个网站地址和指令组成,是不是很简单。3.2 指令指令的作用是为网站开启某些功能。指令的格式有三种,先说一下最简单的不带参数的指令比如:railgun.moe # 没错,moe后缀的域名也可以哦gzip第二行的 gzip 就是一个指令,它表示打开 gzip 压缩功能,这样网站在传输网页是可以降低流量。第二种指令的格式是带简单参数的指令:railgun.moe gzip log /var/log/caddy/access.log tls lengz@lengzzz.com root /var/www/第三行,log 指令会为网站开启 log 功能,log 指令后的参数告诉 caddy log 文件存放的位置。第四行的 tls 指令告诉 caddy 为网站开启 https 并自动申请证书,后面的 email 参数是告知 CA 申请人的邮箱。(caddy 会默认使用 let's encrypt 申请证书并续约,很方便吧)另外,简单参数也可能不只一个,比如 redir 指令:railgun.moe gzip log /var/log/caddy/access.log tls /etc/ssl/cert.pem /etc/ssl/key.pem root /var/www/ redir / https://lengzzz.com/archive/{uri} 301上面的 redir 指令带了三个参数,意思是把所有的请求使用 301 重定向到 https://lengzzz.com/archive/xxx,这个指令在给网站换域名的时候很有用。另外 tls 指令变了,不单单传 email一个参数, 而是分别传了证书和私钥的路径,这样的话 caddy 就不会去自动申请证书,而是使用路径给出的证书了。在这个例子里还使用了 {uri} 这样的占位符(placeholder),详细的列表可以在这里查询到:https://caddyserver.com/docs/placeholders。最后一种指令是带复杂参数的,这种指令包含可能很多参数,所以需要用一对花括号包起来,比如 header 指令:railgun.moe gzip log /var/log/caddy/access.log tls lengz@lengzzz.com root /var/www/ header /api { Access-Control-Allow-Origin * Access-Control-Allow-Methods "GET, POST, OPTIONS" -Server } fastcgi / 127.0.0.1:9000 php { index index.php } rewrite { to {path} {path}/ /index.php?{query} }6-10 行的 header 指令代表为所有的 /api/xxx 的请求加上 Access-Control-Allow-Origin 和 Access-Control-Allow-Methods 这两个 header,从而能支持 javascript 跨域访问 ,第 9 行代表删除 Server header,防止别人看到服务器类型。11-13 行使用了 fastcgi 指令,代表把请求通过 fastcgi 传给 php,ruby 等后端程序。14-15 行,使用了 rewrite 指令,这个指令的作用是 服务器内部重定向 在下面的参数 to 后面,又跟了三个参数,这个功能上有点类似 nginx 的 try_files 。告诉 caddy 需要先查看网址根目录 /var/www 里有没有 {path} 对应的文件,如果没有再查看有没有 {path} 对应的目录,如果都没有,则转发给 index.php 入口文件。这个功能一般会用在 PHP 的 MVC 框架上使用。随着一步步完善这个 Caddyfile,目前这个版本的 Caddyfaile 已经可以直接在网站中使用了。3.3 多 HOST 网站刚才说的一直都是单个域名的网址,那么如果在同一个服务器上部署多个域名的网站呢?很简单,只需要在域名后面跟一个花括号扩起来就可以了,如下:railgun.moe { gzip log /var/log/caddy/railgun_moe.log tls lengz@lengzzz.com root /var/www/ header /api { Access-Control-Allow-Origin * Access-Control-Allow-Methods "GET, POST, OPTIONS" -Server } fastcgi / 127.0.0.1:9000 php { index index.php } rewrite { to {path} {path}/ /index.php?{query} } } lengzzz.com { tls lengz@lengzzz.com log /var/log/caddy/lengzzz_com.log redir / https://railgun.moe/{uri} 301 }
2019年11月21日
0 阅读
0 评论
0 点赞
2019-11-20
PM2
pm2常用命令记录$ pm2 start app.js # 启动app.js应用程序$ pm2 start app.js -i 4 # cluster mode 模式启动4个app.js的应用实例 4个应用程序会自动进行负载均衡$ pm2 start app.js --name="api" # 启动应用程序并命名为 "api"$ pm2 start app.js --watch # 当文件变化时自动重启应用$ pm2 start script.sh # 启动 bash 脚本$ pm2 list # 列表 PM2 启动的所有的应用程序$ pm2 monit # 显示每个应用程序的CPU和内存占用情况$ pm2 show [app-name] # 显示应用程序的所有信息$ pm2 logs # 显示所有应用程序的日志$ pm2 logs [app-name] # 显示指定应用程序的日志$ pm2 flush # 清空所有日志文件$ pm2 stop all # 停止所有的应用程序$ pm2 stop 0 # 停止 id为 0的指定应用程序$ pm2 restart all # 重启所有应用$ pm2 reload all # 重启 cluster mode下的所有应用$ pm2 gracefulReload all # Graceful reload all apps in cluster mode$ pm2 delete all # 关闭并删除所有应用$ pm2 delete 0 # 删除指定应用 id 0$ pm2 scale api 10 # 把名字叫api的应用扩展到10个实例$ pm2 reset [app-name] # 重置重启数量$ pm2 startup # 创建开机自启动命令$ pm2 save # 保存当前应用列表$ pm2 resurrect # 重新加载保存的应用列表$ pm2 update # Save processes, kill PM2 and restore processes$ pm2 generate # Generate a sample json configuration filepm2文档地址:http://pm2.keymetrics.io/docs/usage/quick-start/
2019年11月20日
0 阅读
0 评论
0 点赞
2019-08-21
history实现SPA
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>SPA</title> </head> <body> <div id="rotes"> <a href="index">index</a> <a href="login">login</a> </div> <div id="routerContent"></div> </body> <script type="text/javascript"> class Roter{ constructor(){ this.router={}; this.nowUrl=null; } renter(path,callback){ this.router[path] = (type)=>{ if(type==1){ history.replaceState({path},null,path); }else if(type==2){ history.pushState({path},null,path); } callback(); } } refresh(type){ this.router[this.nowUrl] && this.router[this.nowUrl](type); } init(){ window.addEventListener("load",(e)=>{ this.nowUrl = location.href.slice(location.href.indexOf("/",9)) }) window.addEventListener('popstate', (e) => { this.nowUrl = history.state.path; this.refresh(1) }); document.querySelectorAll('#rotes a').forEach((el)=>{ el.addEventListener('click',(e)=>{ e.preventDefault(); let href = e.target.href.slice(e.target.href.indexOf("/",9)); this.nowUrl = href; this.refresh(2); }) }) } } let router = new Roter(); router.init() router.renter('/index',()=>[ routerContent.innerHTML="index" ]) router.renter('/login',()=>[ routerContent.innerHTML="login" ]) </script> </html>往返缓存默认情况下,浏览器会缓存当前会话页面,这样当下一个页面点击后退按钮,或前一个页面点击前进按钮,浏览器便会从缓存中提取并加载此页面,这个特性被称为“往返缓存”。此缓存会保留页面数据、DOM和js状态,实际上是将整个页面完好无缺地保留往历史记录栈中添加记录:pushState(state, title, url)浏览器支持度: IE10+state: 一个 JS 对象(不大于640kB),主要用于在 popstate 事件中作为参数被获取。如果不需要这个对象,此处可以填nulltitle: 新页面的标题,部分浏览器(比如 Firefox )忽略此参数,因此一般为 nullurl: 新历史记录的地址,可为页面地址,也可为一个锚点值,新 url 必须与当前 url处于同一个域,否则将抛出异常,此参数若没有特别标注,会被设为当前文档 urlreplaceState(state, title, url)改变当前的历史记录history.state返回当前历史记录的 statepopstate定义:每当同一个文档的浏览历史(即 history 对象)出现变化时,就会触发 popstate 事件。注意:若仅仅调用 pushState 方法或 replaceState 方法,并不会触发该事件,只有用户点击浏览器倒退按钮和前进按钮,或者使用 JavaScript 调用 back 、 forward 、 go方法时才会触发。另外,该事件只针对同一个文档,如果浏览历史的切换,导致加载不同的文档,该事件也不会触发。总结一般场景下,hash 和 history 都可以,除非你更在意颜值,# 符号夹杂在 URL 里看起来确实有些不太美丽。另外,根据 Mozilla Develop Network 的介绍,调用 history.pushState() 相比于直接修改 hash,存在以下优势:pushState() 设置的新 URL 可以是与当前 URL 同源的任意 URL;而 hash 只可修改 #后面的部分,因此只能设置与当前 URL 同文档的 URLpushState() 设置的新 URL 可以与当前 URL 一模一样,这样也会把记录添加到栈中;而 hash设置的新值必须与原来不一样才会触发动作将记录添加到栈中pushState() 通过 stateObject 参数可以添加任意类型的数据到记录中;而 hash 只可添加短字符串;pushState() 可额外设置 title 属性供后续使用。这么一看 history 模式充满了 happy,感觉完全可以替代 hash 模式,但其实 history 也不是样样都好,虽然在浏览器里游刃有余,但真要通过 URL 向后端发起 HTTP 请求时,两者的差异就来了。尤其在用户手动输入 URL 后回车,或者刷新(重启)浏览器的时候。hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如http://www.qq.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如http://www.qq.com/book/id。如果后端缺少对 /book/id 的路由处理,将返回 404错误。Vue-Router官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。”需在后端(Apache 或 Nginx)进行简单的路由配置,同时搭配前端路由的 404 页面支持。
2019年08月21日
2 阅读
1 评论
0 点赞
1
...
4
5
6
...
16