custom-input

基于Vant-NumberKeyboard的自定义数字输入框

问题产生背景

  1. 移动端项目中需要用到数字输入框,html 自带的 input 标签设置[type=number]会默认调用系统输入法的数字键盘,可这样的话,minlength、maxlength 等属性就失效了,还无法禁止部分特殊字符的输入
  2. 利用 input 自带的 change 或者 input 事件在 js 进行判断,会导致 input 内造成闪动效果,光标会默认跑到尾部(可控制光标,兼容性不是很好)
  3. IOS 可利用 keypress 进行输入前的判断,Android 却不支持该事件,迫于无奈只能手动实现数字输入框 input

效果预览

image

模拟光标实现原理

image

.cursor {
  position: relative;
  height: 35px;
  &::after {
    content: "";
    animation: blink 1s infinite steps(1, start);
    position: absolute;
    width: 2px;
    height: 30px;
    right: 0;
    top: 2.5px;
    background: rgb(0, 53, 237);
    border-radius: 2px;
  }
}
@keyframes blink {
  0%,
  100% {
    background: transparent;
  }
  50% {
    background: rgb(0, 53, 237);
  }
}

use 使用

在 main.js 中引入组件

import customInput from "./components/customInput";
Vue.use(customInput);

接下来,你就可以在页面中使用 custom-input 了

<template>
  <custom-input
    v-model="inputMoney"
    placeholder="最大值888.88,保留三位小数"
    max="888.88"
    :toFixed="3"
  ></custom-input>
</template>
<script>
  export default {
    data() {
      return {
        inputMoney: ""
      };
    }
  };
</script>
属性 说明 类型 默认值
value 当前输入的值 String -
placeholder 自定义 input 框占位符 String placeholder
transform 是否判断自定义 input 位置被自定义键盘覆盖 Boolean true
max 自定义 input 最大值设置 String, Number 9999999999.99
toFixed 小数点后保留位数 Number 2
事件 说明 返回值
onKeyboardOpen 自定义键盘展开事件 data
close 自定义键盘关闭事件 data
input 当前输入值改变时间 data

文件目录

.
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
└── src
    ├── App.vue // demo
    ├── components
    │   └── customInput // 自定义数字输入框组件
    │       ├── index.js
    │       ├── input.vue
    │       └── keyboard.vue
    └── main.js

相关代码:

阅读全文

有时候会碰到需要修改手机hosts的情况,可是IOS没越狱实在是不好办。之前的解决方法是,修改电脑hosts,然后手机设置代理到电脑,间接实现了hosts的修改,然而这也是件很麻烦的事,所以决定利用docker环境手动搭建一个DNS服务器。

1.配置容器

docker search dnsmasq

QQ20190103142416.png

这里选择andyshinn/dnsmasq的docker镜像

# 下载andyshinn/dnsmasq镜像
docker pull andyshinn/dnsmasq
# 运行镜像
docker run -d --restart=always --name dns-server -p 53:53/tcp -p 53:53/udp --cap-add=NET_ADMIN -v /usr/share/dnsmasq:/etc/dnsmasq  andyshinn/dnsmasq
# 查看容器启用情况
docker ps -a

查看,容器启动成功。

QQ20190103142727.png

2.配置DNS服务

  1. 为 dnsmasq 配置一个真正的dns服务器地址:
vim /usr/share/dnsmasq/resolv.conf

# 这里我使用的是阿里云的DNS
nameserver 223.5.5.5
nameserver 223.6.6.6
  1. 配置本地解析规则:
vim /usr/share/dnsmasq/dnsmasqhosts

# 这里配置自定义解析
127.0.0.1 master
  1. 修改dnsmasq配置文件,指定使用上述两个我们自定义的配置文件:

因为我们在启动docker的时候设置了挂载卷-v /usr/share/dnsmasq:/etc/dnsmasq,所以我们只需要进入dns-server的命令行,就会看到dns-server内部对应路径文件夹内出现了刚刚配置的两个文件

docker exec -it dns-server /bin/sh

QQ20190103144521.png

vi /etc/dnsmasq.conf

# 修改下述两个配置
resolv-file=/etc/dnsmasq/resolv.conf
addn-hosts=/etc/dnsmasq/dnsmasqhosts
  1. 回到宿主,重启dns-server容器服务。
docker restart dns-server
  1. 记得开放服务器的53/tcp53/udp

3.通过本机验证

修改本机dns服务器地址:

QQ20190103144830.png

通过ping命令查看配置是否生效:

ping master

QQ20190103144936.png

参考地址:

阅读全文

什么是 frp

frp 是一个高性能的反向代理应用,可以帮助您轻松地进行内网穿透,对外网提供服务,支持 tcp, http, https 等协议类型,并且 web 服务支持根据域名进行路由转发。

前言:

在家里宽带有公网IP直接在路由器上进行端口映射还是很方便的,但是有时候需要在公司使用或者进行微信开发(微信小程序开发必须要求端口为443的https)这种方式就不好用了,所以会用到 frp 内网穿透工具

准备:

  1. 一台拥有外网ip的主机(我这里用的就是阿里云的服务器了)做服务端,在内网使用的主机(目前我自己的开发主力机)做客户端,域名还是要的
  2. frp releases 下载最新版本 frp 工具,请根据系统版本不同下载不同版本工具

开始配置

1. 服务器配置:

1.1 frps配置
#这里我服务器下载的是linux_amd64版本
 wget https://github.com/fatedier/frp/releases/download/v0.21.0/frp_0.21.0_linux_amd64.tar.gz

#解压文件
tar -zxvf frp_0.21.0_linux_amd64.tar.gz

#因为是服务端用,需要删除frpc开头的多余客户端文件
rm -f frpc
rm -f frpc.ini
rm -f frpc_full.ini

#修改frps配置
vim frps.ini

由于 frp工具的文档 还是很详细了,这里就只贴一下我自己的配置,不做过多的介绍

#frps.ini配置
[common]
bind_port = 8090
vhost_http_port = 3800

[common]部分是必须有的配置,其中bind_port是自己设定的frp服务端端口,vhost_http_port是自己设定的http访问端口。,因为会用到nginx做反向代理绑定域名,所以配置不是很多

1.2 linux服务器新建 frps.service 方便控制frps服务
vim /etc/systemd/system/frps.service

frps.service 内容

[Unit]
Description=frps
After=network.target

[Service]
# Modify these two values and uncomment them if you have
# repos with lots of files and get an HTTP error 500 because
# of that
###
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
ExecStart=/usr/local/sbin/frp/frps -c /usr/local/sbin/frp/frps.ini
ExecStop=/bin/kill $MAINPID
Restart=always

[Install]
WantedBy=multi-user.target

修改service文件权限使其生效并设置开机自启

chmod 644 /etc/systemd/system/frps.service
systemctl daemon-reload
# 设置frps开机自启
systemctl enable frps.service
1.3 nginx添加反向代理
server {
    server_name demo.frp.mrabit.com;
    listen 443 ssl http2;
    ssl on;
    ssl_certificate   cert/frp.mrabit.cer;
    ssl_certificate_key  cert/frp.mrabit.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;

    location / {
        # 上面frps配置的vhost_http_port端口
        proxy_pass http://localhost:3800;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        add_header X-Frame-Options SAMEORIGIN;
        proxy_set_header X-Forwarded-For 
        $proxy_add_x_forwarded_for;
    }
}

2. 客户端配置

#mac上面下载的是darwin_amd64版本
wget https://github.com/fatedier/frp/releases/download/v0.21.0/frp_0.21.0_darwin_amd64.tar.gz

#解压后当然也要删除frps开头的多余服务端文件
rm -f frps
rm -f frps.ini
rm -f frps_full.ini

#修改frpc配置
vim frpc.ini

这里贴一下客户端的配置,更多详情还是去看 frp工具的文档 可能会更清晰

[common]
server_addr = x.x.x.x
server_port = 8090

[demo]
type = http
local_port = 80
# custom_domains 值对应上方 nginx 配置的 server_name 值
custom_domains = demo.frp.mrabit.com

[common]中的server_addr填frp服务端的ip(也就是外网主机的IP),server_port填frp服务端的bind_prot

[demo]为当前模块的名字,可以自定义

[demo]中的type对应服务端配置,可在frp工具的文档查看更多选项。local_port填本地想要映射的服务的端口。custom_domains为要映射的域名,记得域名的A记录要解析到外网主机的IP。

至此,frp内网穿透工具的基本使用就足够了,现在就可以执行看效果了:

QQ20181128122149.png

扩展

由于可能开发端口会改变,虽然frpc.ini可以同时配置多个模块,但是总有不常用有时候却要用到的端口,每次遇到这种情况去改frpc.ini还是很麻烦的,为此,可以编写一个shell脚本,动态去修改frpc.ini的配置,具体操作步骤如下:

1. 新建配置模版文件 frpc.ini.bak

# 该文件放置在frpc同级目录下
[common]
server_addr = x.x.x.x
server_port = 8090

# web_name 对应上方frp.sh脚本内 web_name 做关键字替换
[web_name]
type = http
# web_port 对应上方frp.sh脚本内 web_port 做关键字替换
local_port = web_port
# web_domain 对应上方frp.sh脚本内 web_domain 做关键字替换
custom_domains = web_domain.frp.mrabit.com

2. 新建shell脚本 frp.sh

#!/bin/bash
num=$#
ok=0
if [ ${num} != 2 ]; then
    echo '请输入域名 端口号'
    exit 0
fi
# frpc文件放置路径
# $1 参数为绑定的域名
# $2 参数为绑定的本地端口
frpPath='/etc/frp'
cp $frpPath/frpc.ini.bak $frpPath/frpc.ini
# 替换关键字 web_domain 为 $1 变量
sed -i '' 's/web_domain/'$1'/g' $frpPath/frpc.ini
# 替换关键字 web_name 为 $1 变量
sed -i '' 's/web_name/'$1'/g' $frpPath/frpc.ini
# 替换关键字 web_port 为 $2 变量
sed -i '' 's/web_port/'$2'/g' $frpPath/frpc.ini
$frpPath/frpc -c $frpPath/frpc.ini

3. 设置泛域名解析*.frp到自己的服务器:

QQ20181128123331.png

4. 修改服务端配置内 nginx 配置:

server {
   server_name *.frp.mrabit.com;
   ...
}

5. 分别执行 ./frp.sh demo 80./frp.sh test 7777效果如下:

QQ20181128123836.png

都连接成功了,分别访问https://demo.frp.mrabit.comhttps://test.frp.mrabit.com可查看到均可访问到本地服务内容

至此,shell脚本也执行成功,现在就算没有公网IP进行映射也可以开开心心的调试代码了

参考地址:

阅读全文

前言:

一开始一个朋友发消息问我:

var a = ['123.JpG','123.jpg'];
var reg = /(jpg|png)$/ig;
a.forEach(v => {
    if(reg.test(v) === true){
        console.log(123)
    }
})

会输出什么。 我理所当然的说,当然是输出两个123了。

lastIndex:

QQ20181015090701.png

这时候你会发现,我们在连续使用一个正则匹配其他字符串的时候,第一次匹配是 true,而第二次匹配则是 false。

查看了一下 MDN文档 发现这样一个描述:

如果正则表达式设置了全局标志,test() 的执行会改变正则表达式 lastIndex属性。连续的执行test()方法,后续的执行将会从 lastIndex 处开始匹配字符串,(exec() 同样改变正则本身的 lastIndex属性值).

QQ20181015090907.png

解决方案:

  1. 方案1 既然文档说了是因为全局标志才会影响到lastIndex,于是可以把g去掉就可以了。
var reg = /(jpg|png)$/i;
console.log(reg.test(a[0])); //true
console.log(reg.test(a[0])); //true
  1. 方案2 有时候既然需要用到g,那就不能用到方案1的方法了。 其实,我们的lastIndex属性是可读可写的。 我们可以在下一次匹配的之前更改lastIndex的值来达到目的:
var reg = /(jpg|png)$/ig;
console.log(reg.test(a[0])); //true
console.log(reg.lastIndex); //7
reg.lastIndex = 0;
console.log(reg.test(a[0])); //true

最后:

再来回顾最开始的问题,我们只需要选择方案1或者方案2中的一个方法,即可实现输出两个123:

3.png

参考地址:

阅读全文

ONE·一个 每日阅读

复杂世界里,一个就够了。

该小程序所有数据均由 「ONE · 一个」 提供,本人采取非正常手段获取,仅作为日常学习之用。获取跟共享的行为或许有侵犯权益的嫌疑。若被告知需停止共享与使用,本人会及时删除该小程序与整个项目。

在线访问html5版:https://one.mrabit.com

小程序码:

gh_35dcdd9b6f58_258.jpg

GitHub仓库地址: https://github.com/mrabit/WeChatApp_ONE

阅读全文