前端相关知识点,都是在开发的过程中遇到了才记录一下。

ant design 页面,加载时会自动调用 button 的 onclick 事件

以下写法,相当于直接调用了 js 方法:this.jsTest(),所以页面加载时会就调用一次。

1
2
3
4
5
<Button
onClick={this.jsTest()}
style={{ marginTop: 16, marginRight: 16 }}
htmlType="button"
>

这是在一个 form 表单里的 button,当输入数据时,也会触发该方法的调用,这可能与 antd 表单某种机制有关,比如对表单数据的有效性进行校验(未验证)。

改为下面的方式,正常了,也就是不要写括号:

1
2
3
4
5
6
7
<Button
style={{ marginLeft: 16 }}
htmlType="button"
onClick={this.jsTest}
>
js test
</Button>

如果要传参数,需要这样:

1
2
3
4
5
6
<Button
style={{ marginLeft: 16 }}
htmlType="button"
//onClick={this.jsTest}
onClick={() => {this.jsTest(false)}}
>

参考:https://blog.csdn.net/qq_25252769/article/details/81412224

页面点击事件的正确写法

1
2
3
4
<Divider type="vertical" />
<a title="提交学生信息,提交之后基本信息将不可再修改" onClick={() => this.handleModify(item)}>
提交
</a>

ant design pro 登录页

  • 现象:配置登录按钮的 htmlType="submit" 时,ant design 数据有效性校验未通过也刷新页面了。
  • 解决:将 form 的 onsubmit 去掉,把提交方法放到 button 的 onclick 即可。

ant design 表单数据校验

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
isSubmitCheckPass = e => {
const { form } = this.props;
//e.preventDefault();

form.validateFieldsAndScroll((err, values) => {
if (values.stuName.trim().length === 0) {
//message.warning('请输入学生姓名');
return false;
}

if (values.idNumber.trim().length === 0) {
return false;
}

if (values.phone.trim().length === 0) {
return false;
}

if (values.majorCombination.length === 0) {
return false;
}

return true;
});
};

以上方法,在调用时,会执行两次,第一次会校验数据,第二次,直接跳过,所以,实际调用的结果其实是直接跳过的最后一次,达不到校验的目的。

其实 antd 已经帮我们实现了数据校验了,只需要这样即可达到提交之前先校验数据,校验通过之后再提示本次提交的确认信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
handleEnrollConfirm = e => {
const { form } = this.props;

form.validateFieldsAndScroll((err, values) => {
if (!err) {
Modal.confirm({
title: '提交报到',
content: '提交之后,学生信息将不能再修改。确认要提交吗?',
okText: '确认',
cancelText: '取消',
onOk: () => this.handleEnroll(e),
});
}
});
};

网页表单重置

1
2
3
4
5
6
7
<Button
type="primary"
style={{ marginTop: 16 }}
htmlType="reset"
>
重置所有信息
</Button>

点击之后没生效,添加处理事件,直接调用 this.props.form.resetFields(),

修改 state

1
2
3
4
5
6
handleRecord = e => {
this.setState({
registerType: bizTypeEnum.record,
...this.state,
});
};

这样写,没有意义,不会修改 state 的任何值,应该是:

1
2
3
4
5
6
handleRecord = e => {
this.setState({
...this.state,
registerType: bizTypeEnum.record,
});
};

js 正则表达式

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
/* 合法uri */
export function validateURL(textval) {
const urlregex = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\*\+,;=.]+$/
return urlregex.test(textval)
}
/* 小写字母 */
export function validateLowerCase(str) {
const reg = /^[a-z]+$/
return reg.test(str)
}
/* 大写字母 */
export function validateUpperCase(str) {
const reg = /^[A-Z]+$/
return reg.test(str)
}
/* 大小写字母 */
export function validateAlphabets(str) {
const reg = /^[A-Za-z]+$/
return reg.test(str)
}
/* 市场售价 */
export function validatePrice(str) {
const reg = /(^[1-9]\d*(\.\d{1,2})?$)|(^0(\.\d{1,2})?$)/
return reg.test(str)
}
/* 库存预警值 匹配非负整数(正整数 + 0) */
export function validatestockWarn(str) {
const reg = /^(0|[1-9][0-9]*)$/
return reg.test(str)
}
/* 比价网站 只验证京东和苏宁网站 */
export function validateCompareWebsite(str) {
const reg = /^((https\:\/\/[0-9a-zA-Z\_]+\.|http\:\/\/[0-9a-zA-Z\_]+\.|https\:\/\/|http\:\/\/)|([0-9a-zA-Z\_]+\.){0,1})(jd|suning)\.(com$|com\/[\S]*)/i
return reg.test(str)
}
/* 固定电话 */
export function validateTelephone(str) {
const reg = /^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/
return reg.test(str)
}
/* 手机号码 */
export function validatePhoneNumber(str) {
const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/
return reg.test(str)
}
/* 手机号码和固定电话 */
export function validatePhTelNumber(str) {
const reg = /^((0\d{2,3}-\d{7,8})|(1[3456789]\d{9}))$/
return reg.test(str)
}
/* 电子邮箱 */
export function validateEmail(str) {
const reg = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
return reg.test(str)
}
/* 邮编 */
export function validateZipCode(str) {
const reg = /^[1-9][0-9]{5}$/
return reg.test(str)
}
/* 身份证 */
export function validateIDCard(str) {
const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
return reg.test(str)
}
/* 银行卡号 15位或者16位或者19位 */
export function validateBank(str) {
const reg = /^([1-9]{1})(\d{14}|\d{18}|\d{15})$/
return reg.test(str)
}
/* 纳税人识别码 */
export function validateTaxpayer(str) {
const reg = /^([1-9]{1})(\d{14}|\d{18}|\d{15})$/
return reg.test(str)
}
/* 匹配全空格 */
export function validateAllBlank(str) {
const reg = /^\s+$/gi
return reg.test(str)
}

js 同名函数

写 Java 久了,会不小心把语法应用到 js,比如在 js 里写了多个同名函数,结果,没有按照参数个数调用“正确”的版本。
js 里同名函数,后面的会覆盖掉前面的,所以,只会调用最后面那个,这一点容易忘掉。

彻底解决 WebStorm 中加载 node_modules 卡死问题

彻底解决webstorm中加载node_modules卡死问题
彻底解决webstorm中加载node_modules卡死问题

要查看 ajax 错误

在F12下,选 Console->All

jquery 获取表单全部数据

只设置 id 不行,只设置 name 可以,说明仅依赖 name 属性。多个 form 下可以有同名 name 的 input 存在。

1
2
var form = $("#formIndex" + cDetailID);
var formData = form.serializeArray();

js 有改动,访问过的电脑还是缓存的旧版本,在后面添加一个版本号

1
<script src="../static/js/apg.common.js" th:src="@{/js/apg.common.js} + '?v=201802100714'"></script>

HttpClient get和post请求的示例代码以及防乱码处理

reference

1
2
3
4
5
HttpGet httpget = new HttpGet(uri);
//设置请求的报文头部的编码
httpget.setHeader(new BasicHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"));
//设置期望服务端返回的编码
httpget.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8"));

HTTP请求中的form data和request payload的区别

参考:https://www.cnblogs.com/xuzhudong/p/8487119.html

typeScript 页面,文件名后缀

新建 Page 文件时,WebStorm 的菜单如下:


这时默认创建的是 ts 文件,应该选下面那个。

我没注意到,输入文件名后直接回车,添加的是 ts 文件,结果 WebStorm 报了很多错,而且代码也不能正常格式化,由于前端项目只是个人爱好断断续续的玩过,所以,一时间竟丈二和尚摸不着头脑,云里雾里的各种尝试,最后与正常的文件仔细比较才发现最大的不同是文件名后缀,慨叹:如果能有一个经验丰富的人在旁边指导一二,是一件多么幸福的事情呀~~

  • 后缀名为 ts 时报错情况:
  • 后缀改为 tsx,并格式化代码后:

ESLint: Prefer default export. (import/prefer-default-export)

在一个文件里只定义了一个变量,这样写:export default cont TAB_LIST = ['a', 'b'],会有这个提示,改成这样:

1
2
cont TAB_LIST = ['a', 'b']
export default TAB_LIST

才是正解