docker

docker命令

docker images: 查看镜像

docker ps: 查看容器

创建Dockerfile

1
2
3
4
5
6
7
FROM nginx
MAINTAINER username "username@example.com"
ADD build /usr/share/nginx/html
ADD nginx_server.conf /etc/nginx/conf.d/default.conf
ADD gzip.conf /etc/nginx/conf.d/gzip.conf
EXPOSE 80:80
ENTRYPOINT /bin/bash -c "nginx -g 'daemon off;'"

docker image COMMAND 查看命令

1
2
3
4
5
6
7
8
9
10
11
12
build       Build an image from a Dockerfile
history Show the history of an image
import Import the contents from a tarball to create a filesystem image
inspect Display detailed information on one or more images
load Load an image from a tar archive or STDIN
ls List images
prune Remove unused images
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rm Remove one or more images
save Save one or more images to a tar archive (streamed to STDOUT by default)
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
tar cf build.tag.gz build:压缩文件
tar xf build.tar.gz: 解压文件
scp -r build.tar.gz root@ip:/root/: 上传文件到服务器
docker build -t blog .: 构建镜像,镜像名为blog
docker run -d -p 8080:80 blog:基于镜像blog生成容器,8080为公网端口

swiper 使用体验

首先是实例化swiper

这里有一个注意点,就是实例化的时机

如果你的swiper内容是写死的,可以在componentDidMount中实例化,但是如果你的内容是通过接口异步请求过来的,就必须在componentDidUpdate里实例化,因为如果在 componentDidMount 中实例化,异步请求过来的内容可能还没有挂载完就实例化就会出现问题

1
2
3
componentDidUpdate(){
this.initialBannerSwiper()
}

这里还用到了一个知识点,就是单例模式,因为componentDidMount会多次执行,所以使用单例模式避免生成多个实例

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
initialBannerSwiper =()=>{
if(this.bannerSwiper){
return this.bannerSwiper //单例模式
}
this.bannerSwiper = new Swiper('#swiper-banner', {

slidesPerView: 1, //设置slider容器能够同时显示的slides数量(carousel模式) 默认值为1。

observer: true, //当改变swiper的样式(例如隐藏/显示)或者修改swiper的子元素时,自动初始化swiper。

observeParents: true, //将observe应用于Swiper的父元素。当Swiper的父元素变化时,例如window.resize,Swiper更新。

shortSwipes: false, // 这个属性后面会说

slideToClickedSlide: false, //设置为true则点击slide会过渡到这个slide。

loop: true, //开启循环

autoplay: true, //设置为true启动自动切换,并使用默认的切换设置。

pagination: {
clickable: true, //此参数设置为true时,点击分页器的指示点分页器会控制Swiper切换。
el: '#swiper-pagination-banner',
}

})
this.hoverStop()
}

鼠标划入停止轮播

swiper居然没有这个api来控制,好吧 只能自己来用js来控制了

bannerSwiper.$el

swiper的container的Dom7/jQuery对象

Swiper4自带有DOM7库,因此无需另外加载Jquery等库即可对Dom7对象使用以下常用的DOM操作

this.bannerSwiper.$el[0]就可以拿到 实例的container的dom节点

1
2
3
4
5
6
7
8
9
10
11
12
hoverStop = ()=>{
let that = this.bannerSwiper.$el[0] // 实例的container的dom节点

that.addEventListener("mouseenter", () => {
this.bannerSwiper.autoplay.stop()
that.addEventListener("mousemove", () => {
})
})
that.addEventListener("mouseleave",()=>{
this.bannerSwiper.autoplay.start()
})
}
你可能还会遇到一个小问题

这也是我遇到的,那就是鼠标划到轮播图的时候点击轮播图 会偶尔出现切换的情况,swiper有一个属性可以控制 shortSwipes ,官方描述是这样的

默认允许短切换。设置为false时,只能长切换,进行快速且短距离的滑动无法触发切换。

为什么会出现这种情况呢,因为swiper是专注于移动端的,划上swiper点击的时候可能鼠标方向偏了一点,swiper会以为你是手机上的滑动,设置为false时,短距离的滑动就不会发生切换了,下面是官方的说法

Swiper常用于移动端网站的内容触摸滑动

Swiper是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端。
Swiper能实现触屏焦点图、触屏Tab切换、触屏多图切换等常用效果。
Swiper开源、免费、稳定、使用简单、功能强大,是架构移动终端网站的重要选择!

最后

记得在组件卸载的时候解绑事件和销毁swiper实例~

componentWillUnmount(){
    if(this.bannerSwiper){
        this.bannerSwiper.detachEvents()
        this.bannerSwiper.destroy()
    }
}

swiper真的强大,了解更多请参考 swiper 文档

如果对您有帮助记得给个 喜欢

EventBus-javascript事件总线

1. class实现

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
class EventBus {
handlers: any = {};

/**
* 发布事件
* @param type {String} 事件名
* @param params 参数
*/
emit(type: string, ...params: any) {
// 若没有注册该事件则抛出错误
if (!(type in this.handlers)) {
return new Error('未注册该事件')
}
// 便利触发
this.handlers[type].forEach((handler: Function) => {
handler(...params)
})
}

/**
* 订阅事件
* @param type {String} 事件名
* @param handler {Function} 事件方法
*/
addEventListener (type: string, handler: any) {
// 首先判断handlers内有没有type事件容器,没有则创建一个新数组容器
if (!(type in this.handlers)) {
this.handlers[type] = []
}
// 将事件存入
this.handlers[type].push(handler)
}

/**
* 取消订阅
* @param type {String} 事件名
* @param handler 删除的事件,若无该参数则删除该事件的订阅和发布
*/
removeEventListener (type: string, handler: any) {
// 无效事件抛出
if (!(type in this.handlers)) {
return new Error('无效事件')
}
if (!handler) {
// 直接移除事件
delete this.handlers[type]
} else {
const idx = this.handlers[type].findIndex((ele: any) => ele === handler)
// 抛出异常事件
if (idx === undefined) {
return new Error('无该绑定事件')
}
// 移除事件
this.handlers[type].splice(idx, 1)
if (this.handlers[type].length === 0) {
delete this.handlers[type]
}
}
}
}

export default new EventBus();

2.基于node模块实现

1
2
3
4
5
6
7
const EventEmitter = require('events');
const evtBus = new EventEmitter();
evtBus.setMaxListeners(20);
evtBus.on('error', (err) => {
console.error(err, 'error');
});
export default evtBus;

gitlab && github 同时使用

1.生成秘钥

gitlab:

1
ssh-keygen -t rsa -C "username@163.com" -f ~/.ssh/id-rsa

github:

1
ssh-keygen -t rsa -C "username@qq.com" -f ~/.ssh/github_id-rsa

注:将两个秘钥分别保存在不同文件下,如果不加-f和后面的文件地址执行ssh-keygen -t rsa -C “邮箱”的时候,不要一路回车,需指定文件名,否则第二个会覆盖第一个

2.创建config文件

在.ssh下touch config,内容如下:

gitlab

1
2
3
4
Host gitlab.com
HostName gitlab.*.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id-rsa

github

1
2
3
4
Host github.com 
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/github_id-rsa

注:IdentityFile后的文件路径及文件名需与创建好的一致

3.在github和gitlab上配置ssh

4.测试:

ssh -T git@github.com
gitlab 测试可能会被denied
但现在已经可以同时使用github和gitlab了~

如果你公司gitlab账号和个人github账号用的同一个邮箱,同一个ssh就没这么多事了~~

如果配置 ssh key 以后还是需要密码
那么执行一下

1
ssh-add ~/.ssh/id-rsa

linux远程免密登录

  • 免密登陆的原理
    • 非对称加密
  • 配置免密登陆的步骤

    1.生成密钥对

    • ssh-keygen -t rsa -C ‘yourname’ -f ‘yourname_rsa’

    2.上传配置公钥

    • 上传公钥到服务器对应账号的home路径下的.ssh/中 ( ssh-copy-id -i “公钥文件名” 用户名@服务器ip或域名 )
    • 配置公钥文件访问权限为 600

    3.配置本地私钥

    • 把第一步生成的私钥复制到你的home目录下的.ssh/ 路径下
    • 配置你的私钥文件访问权限为 600(chmod 600 你的私钥文件名)

    4.免密登录功能的本地配置文件

    • 编辑自己home目录的.ssh/ 路径下的config文件
    • 配置config文件的访问权限为 644

使用ssh-keygen 会生成一对文件(公私钥对)

yourname_rsa.pub
yourname_rsa

本地配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 别名
Host ali-cloud
# 域名或者ip
HostName 192.168.0.6
# 端口
Port 22
# 指定用户
User root
# 指定私钥文件
IdentityFile ~/.ssh/yourname_rsa
# 协议
Protocol 2
# 防止长时间不操作被踢掉
Compression yes
# 每隔60s发一次心跳
ServerAliveInterval 60
# 最大连接数 20
ServerAliveCountMax 20
# 日志等级
LogLevel INFO
You need to set client_id and slot_id to show this AD unit. Please set it in _config.yml.