✅ 作者 : 布克吉(微信公众号同名)
🍎简介 :入行两年,专注于前端开发,微信小程序,后台管理(Vue+React)
本博客主要用于分享前端技术知识,更多内容请看下方👇
✨人生态度 :☀️Eventually everything will be fine!
目录
8.react antd table未指定列宽无数据时多出一列
1.阻止页面回退
本项目作为简单的单页面应用,如果回退,会直接退出到登录页,即丢失登录信息,再次请求登录就会是已登录状态,带来不好的体验。
所以在页面生命周期中添加如下代码
componentDidUpdate() {
window.history.pushState(null, document.title, window.location.href);
window.addEventListener('popstate', function(event) {
window.history.pushState(null, document.title, window.location.href);
});
}
这时候左上方页面回退的箭头就会被禁用啦!
2.阻止表单自动填充
原本是用来阻止浏览器记住密码的功能,无奈查遍了全网,尝试了很多种方法,也没有一个完美的解决方案。
所以只能阻止自动填充,网上提到的autoComplete="new-password"和autoComplete="off"确实有用,但是一点击输入框就会弹出保存的密码提示,以下方法实现:
第一次点击输入框不会弹出账号密码提示,连续两次点击同一个输入框才会弹出;
使用readonly属性,初始值为true,onfocus事件激活时,修改值为false,获取到光标可输入;
onblur事件,修改值为true。
this.state = {
preadOnly:true,
ispwdFocus:false
}
//dom
<Form.Item>
<Input
type="password"
readOnly={this.state.preadOnly}
onFocus={this.pwdFocus}
onBlur={this.pwdBlur}
/>
</Form.Item>
//function
pwdFocus =(e)=>{
setTimeout(()=>{
this.setState({
preadOnly:false
})
},100)
}
pwdBlur =(e)=>{
this.setState({
preadOnly:true,
ispwdFocus:false
})
}
补充:为了实现在输入时,和密码框有同样的效果,且不会记住密码,以下有两种方法。(但是都存在谷歌浏览器中文输入bug,且无法修改,仅供参考)
(1)css样式控制,输入内容以符号显示
/* 用于显示密码框为不可见样式 */
.password{
-webkit-text-security: disc;
text-security: disc;
}
-webkit-text-security的可选值有:
- none:文本不进行任何处理,显示原始文本。
- disc:将文本替换为实心圆点(•)。
- circle:将文本替换为空心圆圈(○)。
- square:将文本替换为空心方块(□)。
- disclosure-closed:将文本替换为实心三角形(▶)。
- disclosure-open:将文本替换为倒三角形(▼)。
(2)js代码同步替换
//输入框内容改变事件
handlePassWDChange = (e) => {
const value = e.target.value.split("").filter(item=>item!=="'").join(""); //获取用户输入的内容
console.log(value);
if (value.length > password.length) { //判断用户输入的内容是否大于密码的长度
password += value.slice(-1); //如果是,将用户输入的最后一个字符追加到密码的末尾
} else {
password = password.slice(0, value.length); //如果不是,将密码的最后一个字符删除
}
e.target.value = '•'.repeat(value.length); //将输入框的内容替换为和用户输入的内容长度相同的星号
}
3.鼠标键盘无操作超时自动退出登录
目的:人有事离开电脑,但是当前登录的页面还在电脑上显示,为了防止第三方人员获取到重要信息,需要在一定时间内自动退出登录,以此保障数据的安全。
原理:进入页面时监听鼠标键盘事件,如果有则记录当前时间到本地,开启定时器每秒判断一次,当前时间减去上一次记录的时间有没有超过预定的时间(例如5分钟),如果超出则退出登录。
componentDidMount() {
//生命周期内开启监听鼠标键盘事件
this.ChangeUserOperation()
//定时器每秒判断一次
this.CheckOpartionTimer = setInterval(
() => {
let _lastTime = LocalStorage.getItems('lastTime') * 1;
let nowTime = new Date().getTime();
// console.log('nowTime',nowTime);
if((nowTime - _lastTime > 1000 * 60 * 5)&&_lastTime) {
console.log('当前时间:',nowTime,'最新时间',_lastTime, '间隔:', (nowTime-_lastTime), '超时了,已退出登录');
message.warning('长时间未操作,已退出登录');
// 清除计时器
clearInterval(this.timer);
clearInterval(this.CheckOpartionTimer)
// 断开连接,退出
this.Loginout();
}
},
1000
)
}
componentWillUnmount() {
//离开页面时解除监听 清除定时器
clearInterval(this.CheckOpartionTimer);
LocalStorage.removeAllItems()
homeWrapper.removeEventListener('click', function(){});
homeWrapper.removeEventListener('keydown', function(){});
homeWrapper.removeEventListener('mouseover', function(){});
homeWrapper.removeEventListener("mousewheel", function(){});
}
ChangeUserOperation = () => {
// 只要鼠标键盘有操作,就基本当前时间到本地
let callEvent = () => {
LocalStorage.SetItems('lastTime', new Date().getTime().toString())
}
homeWrapper = document.getElementById('homeWrapper')
homeWrapper.addEventListener('click', callEvent);
homeWrapper.addEventListener('keydown', callEvent);
homeWrapper.addEventListener('mouseover', callEvent);
homeWrapper.addEventListener("mousewheel", callEvent);
}
4.验证两次密码输入一致性问题
我们在注册账号和修改密码时,都会要求我们进行再次输入,防止误操作,带来不必要的麻烦。
该方法通过ref获取form表单值,rules中的validator触发验证。
// dom
<Form ref={this.formRef} onFinish={this.onFinish}>
<Form.Item label={<label className="labelstyle" >用户名</label>}
name="newUser" rules={[
{required: true, message: '请输入用户名'}
]}>
<Input placeholder="用户名" id="newname" />
</Form.Item>
<Form.Item label={<label>密码</label>}
name="password" rules={[
{required: true, message: '请输入密码'},
{validator:this.inputOnce}
]}>
<Input type="password" value={password} />
</Form.Item>
<Form.Item label={<label>确认密码</label>}
name="surePwd" rules={[
{required: true, message: '请再次输入密码'},
{validator:this.inputTwice}
]}>
<Input type="password" value={surePwd} />
</Form.Item>
</Form>
// function
// 创建表单ref 用于验证时获取表单指定字段值
formRef = React.createRef()
inputOnce = (_,value)=>{
console.log(value);
const regex = /^[a-zA-Z0-9]*$/; // 正则表达式,只允许输入数字和字母
if (!regex.test(value)&&value) {
console.log('只允许输入数字和字母');
return Promise.reject(new Error('只允许输入数字和字母')); }
return Promise.resolve();
}
inputTwice = (_,value)=>{
const { getFieldValue } = this.formRef.current;
if (getFieldValue('password')&&value && value !== getFieldValue('password')) {
return Promise.reject(new Error('两次输入的密码不一致')); }
return Promise.resolve();
}
5.修改state数据后异步执行函数
例如某个操作需要以改变指定数据为前提,可以使用如下写法
this.state({
data:newData
},()=>{
//修改数据后进行的操作
})
6.ant design设置table列宽不生效问题
scroll={{ x: 'max-content',y: 300 }}(y:300为垂直滚动距离)
7.解决react中点击事件带参数会立即执行问题
onClick={(e)=>btnAction('XXX')}//箭头函数
8.react antd table未指定列宽无数据时多出一列
在React Antd Table中,如果未指定列宽并且没有数据时出现多出一列的情况,可能是由于表格组件默认会渲染一个空的列来占位。为了解决这个问题,可以通过设置scroll={{ x: true }}
来启用横向滚动,并且给每一列设置一个固定的宽度或者使用width: 100%
来自适应父容器的宽度。
下面是一个示例代码:
import React from 'react';
import { Table } from 'antd';
const dataSource = [];
const columns = [
{
title: '列1',
dataIndex: 'col1',
key: 'col1',
width: 200, // 设置列宽度
},
{
title: '列2',
dataIndex: 'col2',
key: 'col2',
width: 300, // 设置列宽度
},
// 其他列...
];
const App = () => {
return (
<Table
dataSource={dataSource}
columns={columns}
scroll={{ x: true }} // 启用横向滚动
/>
);
};
export default App;
9.打包后部署到服务器上没有页面(报错404)
报错:Resource interpreted as Stylesheet but transferred with MIME type text/ html:
意为资源解释为样式表,但传输MIME类型文本text/html
尝试过各种修改无果,最终修改package.json中'homepage':'.'为'homepage':'./'
其实是路径的问题:本地运行npm start后,URL为真实的URL,但是npm run build打包项目,上传项目到服务器后,实际项目页面出现404错误。当页面刷新时,浏览器会向服务器请求我们在服务器设置的默认URL,服务器实际会去找根目录下的build好的html文件,发现找不到,因为实际上我们的服务器并没有这样的物理路径/文件等,或者我们没有配置处理这个路由,所以内容无法显示,只有提示404错误。