This article is commonly used to work needs, and the corresponding NPM library records, convenient to meet the same requirements can be directly use after CV solution (I’m sorry I’m too lazy), because the work is the React technology stack, with the UI library is Antd, mainly for the background in the development of the common requirements, some may on the usage of vue is different, Later will also often record, if there are better suggestions welcome big guys comment pointed out!
1. Obtain different data according to the time interval
Often encountered according to select different values of the drop-down box and then refresh data similar to below this, mainly component of simple packaging and processing functions of time, when you click confirm according to the time when they choose to get the data, two drop-down box linkage is mainly according to choose the type of dependence in useEffect set the other two attribute’s value is empty, The value property in the DatePicker component is then bound to a value based on year, month, or quarter. This type is the year, quarter, or month of the first select
const DatePickerComp = (props) = > {
const { type, timeOpen, values, handleChange, handleClick, handOK } = props;
return (
<DatePicker
picker={type}
open={timeOpen}
allowClear={false}
value={values}
onChange={handleChange}
onClick={handleClick}
renderExtraFooter={()= > (
<div className={style.timeFooterBtnWrap}>
<div onClick={handOK} className={style.timeFooterBtn}>confirm</div>
</div>)} / >
);
};
const PickerWithType = ({ type, onChange }) = > {
const [timeOpen, setTimeOpen] = useState(false);
const [yearTimes, setYearTimes] = useState(moment().year(new Date().getFullYear()));
const [quarterTimes, setQuarterTimes] = useState(' ');
const [monthTimes, setMonthTimes] = useState(' ');
const handleClick = () = >{ setTimeOpen(! timeOpen); };// Depending on the type, click ok for the callback
const handOK = () = > {
setTimeOpen(false);
if (type === 'year') {
onChange(yearTimes);
} else if (type === 'month') {
onChange(monthTimes);
} else{ onChange(quarterTimes); }};// Based on the type, select the date for the callback
const handleYearChange = (date) = > {
setYearTimes(date);
};
const handleQuarterChange = (date) = > {
setQuarterTimes(date);
};
const handleMonthChange = (date) = > {
setMonthTimes(date);
};
useEffect(() = > {
if (type === 'year') {
setQuarterTimes(' ');
setMonthTimes(' ');
} else if (type === 'month') {
setYearTimes(' ');
setQuarterTimes(' ');
} else {
setMonthTimes(' ');
setYearTimes(' ');
}
}, [type]);
return (
<Fragment>
<DatePickerComp
type={type}
timeOpen={timeOpen}
handleClick={handleClick}
handOK={handOK}
handleChange={
type= = ='year'
? handleYearChange
: type= = ='month'
? handleMonthChange
: handleQuarterChange
}
values={type= = ='year' ? yearTimes : type= = ='month' ? monthTimes : quarterTimes} / >
</Fragment>
);
};
// Click OK, depending on the type of time, save time is one month, three months or a year
//new Date(year, Number(month) -1, 1) specifies the Date of the month
//new Date(year, month, 0) specifies the last day of the last month
// In useEffct, the dependency is the onChange function stored in time. When the time changes, the parameters of the request interface will change and the corresponding data will be retrieved again
const onChange = (dateString) = > {
let Times = [];
if (dateString) {
if (timeType === 'year') {
const startTime = `${moment(dateString).format('YYYY')}- 01-01 00:00:00 `;
const endTime = `${moment(dateString).format('YYYY')}- 12-31 23:59:59 `;
Times = [startTime, endTime];
} else if (timeType === 'month') {
const year = moment(dateString).format('YYYY');
const month = moment(dateString).format('MM');
const monthStartTime = `${moment(new Date(year, Number(month) - 1.1)).format(
'YYYY-MM-DD')},00:00:00 `;
const monthStartEnd = `${moment(new Date(year, month, 0)).format('YYYY-MM-DD')}23:59:59 `;
Times = [monthStartTime, monthStartEnd];
} else {
const year = moment(dateString).format('YYYY');
const month = moment(dateString).format('MM');
const monthStartTime = `${moment(new Date(year, Number(month) - 1.1)).format(
'YYYY-MM-DD')},00:00:00 `;
const monthStartEnd = `${moment(new Date(year, Number(month) + 2.0)).format(
'YYYY-MM-DD')},23:59:59 `;
Times = [monthStartTime, monthStartEnd];
}
}
setTime(Times);
};
Copy the code
2. Upload the Excel file
Aspects to be noted are:
1, either the action method, pass to the background interface, or write a manual customRequest yourself
2. Determine the type of the uploaded file using the beforeUpload method
3, onChange method: upload the operation of the file, if only one is allowed to upload, to save the processed file set
4. FileList method: Upload a file
export const isFileType = (file, ... fileTypes) = > {
consttype = (file? .name ||' ').split('. ').slice(-1)? .0] | |' ';
returnfileTypes.includes(file? .type) || fileTypes.includes(type); }// Check whether it matches the file type
beforeUpload={(file) = > {
if (
isFileType(file, 'application/vnd.ms-excel'.'xls') ||
isFileType(file, 'application/vnd.ms-excel'.'xlsx')) {return true;
}
message.error(`${file.name}Does not match the upload type);
return false;
}}
Copy the code
3. Remove the hollow data of the object
Generally used in form submission, when multiple input boxes may not be mandatory, you can get the form data to empty processing after passing to the background
const removeValue = (obj) = > {
const newObj = {}
Object.keys[obj].forEach(key= > {
if(obj[key]){
newObj[key] = obj[key]
}
})
return newObj
}
Copy the code
4. Click Full screen or Exit full screen
// Full screen operation
const handleFullScreen = useCallback(() = > {
function fullScreen() {
const el = document.documentElement;
const rfs =
el.requestFullScreen ||
el.webkitRequestFullScreen ||
el.mozRequestFullScreen ||
el.msRequestFullScreen;
// typeof rfs ! = "undefined" && rfs
if (rfs) {
rfs.call(el);
} else if (typeof window.ActiveXObject ! = ='undefined') { // Check whether there is an ActiveXObject control
// For IE, this is actually a simulation of F11 pressing the keyboard to make the browser full screen
const wscript = new window.ActiveXObject('WScript.Shell');
if(wscript ! =null) {
wscript.SendKeys('{F11}'); }}}function exitScreen() {
const el = document;
const cfs =
el.cancelFullScreen ||
el.webkitCancelFullScreen ||
el.mozCancelFullScreen ||
el.exitFullScreen;
// typeof cfs ! = "undefined" && cfs
if (cfs) {
cfs.call(el);
} else if (typeof window.ActiveXObject ! = ='undefined') {
// For IE, this is the same as fullScreen. Press F11 to exit fullScreen
const wscript = new window.ActiveXObject('WScript.Shell');
if(wscript ! =null) {
wscript.SendKeys('{F11}'); }}}if (isFullScreen) {
setIsFullScreen(false);
exitScreen();
} else {
setIsFullScreen(true); fullScreen(); } resetTranslate(! isFullScreen); }, [isFullScreen]);Copy the code
Be sure to style the outer container!! Otherwise, there will be extra area after full screen
// Add the external containerposition: relative
&.fullscreen {
position: fixed ! important;
top: 0;
left: 0;
z-index: 10000;
margin: 0 ! important;
padding: 10px ! important;
width: 100% ! important;
height: 100% ! important;
background-color: #fff;
}
Copy the code
5. Click Print PDF
// The useReactToPrint hook is the 'react-to-print' library
const handleToPrint = useReactToPrint({
content: () = > treeRef.current,
pageStyle: ' '});Copy the code
const handlePrint = () = > {
if (treeRef.current) {
const contianer = document.getElementsByClassName('rd3t-tree-container')? .0];
const[svg] = contianer? .childNodes || [];const[gEle] = svg? .childNodes || [];if (gEle) {
// Reduce the G element in SVG to the viewport size before downloading.
// console.log(gEle.getBBox());
const { width: svgW } = gEle.getBBox();
const { clientWidth } = contianer;
let scale = 0.5;
if (svgW < clientWidth) {
scale = 0.5;
} else {
scale = (isFullScreen ? 0.7 : 1) / (svgW / clientWidth);
}
gEle.setAttribute(
'transform'.`translate(${isFullScreen ? window.innerWidth / 2.5 : 460}, 200) scale(${scale}) `,); } handleToPrint(); }Copy the code
6. Highlight the search section
So if you have subStr, you sort out what you want to highlight, and if you have children, you recurse, which I’m using here in the tree
const loop = (treeData, val) = > {
treeData.map(item= > {
const index = item.indexOf(val)
let { title } = index
if(index >= 0) {const beforeStr = item.subStr(0, val)
const afterStr = item.subStr(index + val.length || 0)
title =
index > -1 ? (
<span>{beforeStr}</span>
<span style={{color: '#E4996'}} >{val}</span>
<span>{afterStr}</span>) : (<span>{title}</span>)}if (item.children) {
return { ...item, title, key:item.key, children: {... loop(item.children, val)} } }return {
...item, title, key: item.key
}
})
}
Copy the code
7. IsNaN is supposed to convert an argument to a Number using the Number method. If the conversion succeeds, it returns false, and if the conversion fails, it returns true.
8. Handle the serial numbers 1-10 of the table
const renderTableIndex = (pageNum, pageSize = 10) {return (text, record, index){
const genNumber = Number.parseInt(index,10) + 1 + ( pageNum - 1 ) * pageSize
const newNumber = Number.isNaN(genNumber) ? Nzh.decodeS(genNumber) : genNumber
return newNumber.toString()
}
}
//TODO:Pagenum and pageSize are passed directly to column in the component
render: renderTableIndex(pageNum, pageSize),
Copy the code
9. Conversion of various stream files
Generally, when downloading files or captcha images, a stream of image address data will be sent to the back end. In this case, RES is a stream and printed out as a bunch of gibberish
The first step is to declare responseType: ‘blob’ when requesting the interface function.
export async function downloadFile(params) {
const { path, proxyPort = 'api', ids, reqParams, ... rest } = params;return request(` /${proxyPort}/${params.path}?${stringify(rest)}`, {
method: 'POST'.data: ids, ... reqParams,// reqParams here is a bit more encapsulated, more standardized and extensible
});
}
Copy the code
// A function to download files
const downFiles = useCallback(payload, callback = () = > {}) => {
dispatch({
type: 'common/downFile'.payload: {
path: `aaa/abc`.// The path of its own interfaceproxyPort, ... payload,reqParams: {
responseType: 'blob',},}})}Copy the code
Multiple downloaded files
const downloadFile = () = > {
const idArgs = propertyRightsMaterialsList.map((el) = > el.id); // Get all ids to download multiple files
downloadFiles(
{
ids: idArgs,
isExport: false,},(res) = > {
const link = document.createElement('a');
const blob = new Blob([res], { type: 'application/zip' });
const url = URL.createObjectURL(blob);
link.download = `${projectName}.zip`; link.href = url; link.click(); }); };Captcha requirements may be encountered when the image address stream is sent from the back end
.then(res= > {
let blob = new Blob([res], { type: 'img/jpeg' });
let url = (URL || webkitURL).createObjectURL(blob);
let imgDiv = document.getElementById('secret');
imgDiv.src = url; // This will do
Imgdiv. setAttribute(' SRC ',url
imgDiv.onload = function(e) {
URL.revokeObjectURL(url);
};
});
// Download the Excel stream
.then((res) = > {
const link = document.createElement('a');
const blob = new Blob([res], { type: 'application/vnd.ms-excel; utf-8' });
const url = URL.createObjectURL(blob);
link.download = ` file${moment().format('YYYY-MM-DD-HH-mm-ss')}.xls`;
link.href = url;
link.click();
});
Copy the code
At present, only a part of the common requirements encountered summary, will be updated later, the first time to write this also do not know the use of…… Just work two months have a feeling, must deal with the backend relationship !!!! Or he returned data doesn’t demand that requires you to deal with, may the back-end process is very simple, but let’s front difficult to handle, and some back end he write good interface local debugging he throw you gave him no matter, I the back-end fine with the elder brothers, has been to help me, so be sure to set and the back-end relations, also is the product, Don’t foolishly give you a thing you pick up, oneself want to evaluate once!! Many of their products and UIs are not technical, learn to say no!
If there is a boss and a better way to deal with the above requirements, welcome to leave a message! I am too vegetables want to learn a little more, feel write bad can spray me, but not brainless spray! I hope I can stick to it, come on