项目总结
前端复制插件
import copy from 'copy-to-clipboard';
handleCopy = text => {
if (copy(text)) {
message.success({
content: '复制成功',
duration: 1
});
}
};
<span
title='复制'
className={styles.servicesUrlCopy}
onClick={this.handleCopy.bind(this, text)}
>
<CopyOutlined />
</span>
react 项目中实现一键复制
import {FC, useCallback} from 'react';
import {Toast} from 'antd-mobile';
import {CopyToClipboard} from 'react-copy-to-clipboard';
import c from './index.less';
interface Props {
style?: any;
value: string | number;
}
const Copy: FC<Props> = ({value, style}) => {
const onCopy = useCallback(
() => {
Toast.show({icon: 'success', content: '复制成功'});
},
[]
);
return (
<CopyToClipboard
text={value}
onCopy={onCopy}
>
<span style={style} className={c.copy}></span>
</CopyToClipboard>
);
};
export default Copy;
移动端 @vw
@device-width: 1242;
@vw: (100vw/@device-width);
文件暴露方法
export const getRegions = (nums: number) => {
...
..
};
export * from './getRegions';
export * from './getCode';
import {getRegions} from '@/utils';
const radioValue = Form.useWatch(FormKeys.result, form)
git reset –soft
在push代码时,如果包含多个commit,这个时候提交就会有问题,
提示不能提交多个。
那我们可以使用此命令删除commit,
不用担心会删除已有的代码,
它只会删除commit记录
mac里git项目删除.DS_Store文件
在项目的 .gitignore 文件下,
写入
*/.DS_Store
.DS_Store
git rm --cached filename
git commit -m "delete file"
git push origin
参考资料: http://t.zoukankan.com/zourong-p-5962240.html
const createFunc = useCallback(
async () => {
const nowDate = (new Date()).valueOf();
const unixSecond = nowDate.toString().substring(0, 10);
const params: CreateOrder = {
timestamp: unixSecond,
act_id: actId,
asset_id: assetId,
return_url: 'https://www.karlfranz.com',
};
const formData = new FormData();
Object.keys(params).forEach(key => {
formData.append(key, params[key as CreateOrderType]);
});
const res = await service1.getBuyUrl(formData);
location.href = (res as any)?.data?.order_url;
},
[actId, assetId]
);
直接以对象形式传入
debugger
想要确定代码的执行顺序?
不用分好几个地方打印,
在你想确定顺序的几个地方,
都写下debugger,
然后打开控制台
就能一步一步点小三角确定代码的执行顺序了。
确定代码逻辑的执行顺序,
有时能解决很多bug,
也能少走弯路,
能以更清晰简便的方式,
解决问题。
antd 单项校验
this.formModalRef.current.form.validateFields(['bus']);
if (res.code === 1110) {
this.setState({isShow: true});
}
if (res.code === 1110) {
this.setState({isShow: true});
this.formModalRef.current.form.validateFields(['bus']);
}
vue 自动刷新
Vue.prototype.autoChangeMethods = function(roterkey, fn) {
if (location.pathname.includes(roterkey)) {
setTimeout(() => {
fn()
}, 5000);
}
return;
};
autoChange () {
this.autoChangeMethods(
'apply',
() =>{
this.getTableList()
const flag = this.tableData.filter(item => {
return this.status.includes(item.state);
});
if (flag[0]) {
this.autoChange();
return;
}
this.isRunning = false;
}
)
}
watch: {
tableData: {
handel(now) {
const isHaveMiddleStatus = Array.isArray(now)
&& now.filter(item => {
return this.status.includes(item.state);
});
if (isHaveMiddleStatus[0] && !this.isRunning) {
this.autoChange();
this.isRunning = true;
return;
}
}
}
}
react renderList 事件委托
import React, {
useState,
MouseEvent,
} from "react";
interface ListType {
name: string;
key: number;
}
const list = [
{
name: "王之哈默",
key: 1,
},
{
name: "光之惩戒",
key: 2,
},
{
name: "圣灵谱尼",
key: 3,
},
{
name: "启灵元神",
key: 4,
},
];
const APP = () => {
const [saier, setSaier] = useState<ListType[]>();
const handeleClick = (
e: MouseEvent<HTMLDivElement, globalThis.MouseEvent>
) => {
const key = Object.keys(e.target)[1];
const changeObj = (e.target as any)[key];
const { style, ..._other } = changeObj;
console.log(
"other data-item",
_other["data-item"],
"index",
_other["data-index"]
);
const newList = [...(saier as any)];
const newItem = { key: _other["data-item"]["key"], name: "圣霆雷伊" };
setSaier((state) => {
(state as any)[_other["data-index"]] = newItem;
return state;
});
};
return (
<div style={{ height: 100 }} onClick={handeleClick}>
{Array.isArray(saier) &&
saier.map((ele, index) => (
<p
style={{ height: 10 }}
key={ele.key}
data-item={ele}
data-index={index}
>
{ele.name}
</p>
))}
</div>
)
};
export default App;
气泡省略组件
import {Popover} from 'antd';
import {FC, useRef, useState} from 'react';
interface PopoverProps {
text: string | React.ReactNode;
}
let currBubbleCallback = (state: boolean) => {};
const showCurrBubble = () => currBubbleCallback(true);
const hideCurrBubble = () => currBubbleCallback(false);
const EllipsisPopover: FC<PopoverProps> = ({text}) => {
const [isVisible, setIsVisible] = useState(false);
const eleRef = useRef<HTMLDivElement>(null);
const timeRef = useRef<any>(undefined);
const renderBubble = (state: boolean) => {
if (timeRef.current !== undefined) {
clearTimeout(timeRef.current);
timeRef.current = undefined;
}
setIsVisible(state);
};
const hasEllipsisFn = () => {
const ele = eleRef.current;
return ele && ele.scrollWidth > ele.offsetWidth;
};
const handleMouseEnter = () => {
currBubbleCallback(false);
currBubbleCallback = renderBubble;
if (hasEllipsisFn()) {
setIsVisible(true);
}
};
const handleMouseLeave = () => {
const popDom = document.getElementsByClassName('ant-popover-inner');
for (let i = 0; i < popDom.length; ++i) {
const dom = popDom[i];
if (dom.getAttribute('listener') !== 'true' && dom?.children?.length < 2) {
dom.addEventListener('mouseenter', showCurrBubble);
dom.addEventListener('mouseleave', hideCurrBubble);
dom.setAttribute('listener', 'true');
}
}
timeRef.current = setTimeout(() => {
renderBubble(false);
}, 500);
};
return (
<Popover
content={
<div
style={{
overflow: 'auto',
maxHeight: '132px',
maxWidth: '310px',
lineHeight: '26px'
}}
>
{text}
</div>
}
visible={isVisible}
>
<div
ref={eleRef}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
style={{
display: 'block',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
}}
>
{text}
</div>
</Popover>
);
};
export default EllipsisPopover;
import EllipsisPopover from '@/components/EllipsisPopover';
const columns = [
{
width: '20%',
ellipsis: true,
title: '审核时间',
dataIndex: 'modifiedTime',
render: (text: string) => <EllipsisPopover text={sendForamt(text)} />,
},
{
width: '10%',
ellipsis: true,
title: '审核结果',
dataIndex: 'status',
render: (text: string) => <EllipsisPopover text={text} />,
},
...
..
];
引入antd 组类型
import {FormProps} from 'rc-field-form/lib/Form';
Antd useForm 是自动监听表单值的变化的,
变化后打印的确能看到最新值,
但如果希望 用 form.getFieldValue(FormKeys.result) 的方式以这个值,
在节点中以此判断dom的显示隐藏,
会发现 form.getFieldValue(FormKeys.result) 值变化时,
发现render函数中 没有观察到这个值的变化,
也就是说表单域管控的值,在变化时,无法引起视图更新!
因此以这种方式动态控制节点的显示隐藏,并不可行!
echarts 版本和 event-source-polyfill 版本不兼容
echarts 4x 和 event-source-polyfill 配合使用,
5x 和 3x 配合使用,
项目里是 4x 配合 3x, 不兼容报错了,修改 event-source-polyfill 版本 至2x。
重新安装 event-source-polyfill 版本依然报错,
删除整个依赖重装,发现就好了。
history.svg?react 有多余title?
在我们使用 svg 图标时,图标确实可以正常显示,
但hover上去发现有不该显示的内容,
这时一审查元素发现svg图也是一个标签,
在它的内部的title正好是hover上去不该显示的内容。
这时,我们将这个svg以备忘录以typora打开,
删去哪一行title,
就发现项目上的图标hover上去不会再显示无关内容了。
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>4.图标元件/7.通用/4.电话/电话-线备份 5</title>
<g id="页面说明" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="待审核名单" transform="translate(-1329.000000, -2117.000000)">
<g id="编组-23" transform="translate(1329.000000, 2115.000000)">
<g id="4.图标元件/7.通用/4.电话/电话-线备份-5" transform="translate(0.000000, 2.000000)">
<rect id="矩形" stroke="#2468F2" fill="#2468F2" opacity="0" x="0.5" y="0.5" width="15" height="15"></rect>
<path d="M11,9 C9.34329471,9 8,10.343604 8,12 C8,13.6569792 9.34302082,15 11,15 C12.6569792,15 14,13.6569792 14,12 C14,10.343604 12.6567053,9 11,9 Z M11,10 C12.1043892,10 13,10.895817 13,12 C13,13.1046861 12.1046861,14 11,14 C9.8953139,14 9,13.1046861 9,12 C9,10.895817 9.89561076,10 11,10 Z" id="Stroke-3" fill="#2468F2" fill-rule="nonzero"></path>
<path d="M10.1,12.5 L10.1,12 L10.8,12 L10.8,11 L11.3,11 L11.3,12.5 L10.1,12.5 Z" id="形状结合" fill="#2468F2" transform="translate(10.700000, 11.750000) scale(-1, -1) rotate(-180.000000) translate(-10.700000, -11.750000) "></path>
<g id="编组" transform="translate(3.000000, 1.500000)">
<polyline id="Stroke-1" stroke="#2468F2" points="4.60462219 13.0987 0 13.0987 0 0.0987 7 0.0987 10 3.0987 10 7.0987"></polyline>
<polygon id="Fill-3" fill="#2468F2" points="6.1983 4.001 7.1983 4.001 7.1983 0 6.1983 0"></polygon>
<polygon id="Fill-4" fill="#2468F2" points="6.1983 4.001 10.1993 4.001 10.1993 3 6.1983 3"></polygon>
<polygon id="Fill-5" fill="#2468F2" points="2 6.588 8 6.588 8 5.588 2 5.588"></polygon>
<polygon id="Fill-6" fill="#2468F2" points="2 9 4.5 9 4.5 8 2 8"></polygon>
</g>
</g>
</g>
</g>
</g>
</svg>
ReactSVG 插件
import React from 'react';
import { ReactSVG } from 'react-svg';
import history from 'assets/name/history.svg';
import waitexamine from 'assets/name/waitexamine.svg';
interface SvgIconProps {
[propsName: string]: any;
}
class SvgIcon extends React.Component<SvgIconProps> {
render(): React.ReactNode {
return (
<div>
{}
{}
<ReactSVG src={history} />
<ReactSVG src={waitexamine} />
</div>
);
}
}
export default SvgIcon;
.wrapper {
width: 200px;
height: 200px;
}
.wrapper path {
fill: red;
height: 190px;
width: 190px;
}
this.state = {
formList: [
{
label: '用户名称',
name: 'username',
require: true,
rules: [
{
min: 4,
max: 16,
message: '请输入4~16个字符'
},
{
pattern: new RegExp(/^[\u4e00-\u9fa5a-zA-Z]+$/, 'g'),
message: '只允许输入中文或英文字母'
}
],
props: {
placeholder: '请输入业务方名称'
}
},
{
label: '用户账户',
name: 'account',
require: true,
rules: [
{
min: 6,
max: 20,
message: '请输入6~20个字符'
},
{
pattern: new RegExp(/^[A-Za-z]*$/, 'g'),
message: '只允许输入英文字母'
}
],
props: {
placeholder: '创建后不允许更改',
message: '请输入用户账户'
}
},
{
label: '用户密码',
name: 'password',
require: true,
formType: 'password',
rules: [
{
min: 8,
max: 32,
message: '请输入8~32个字符'
}
],
props: {
placeholder: '请设置密码',
onClick: this.setPasswordVisibility.bind(this, true),
autoComplete: 'new-password'
}
}
],
}
this.formModalRef = createRef();
this.addPermissionRef = createRef();
const defaultFormModalProps = {
width: 490,
cRef: this.formModalRef,
labelCol: 5,
wrapperCol: 19,
formList,
onFinish: this.handleSubmit,
onCancel: () => {
this.addPermissionRef.current.clearSelect();
}
};
<FormModal {...defaultFormModalProps}>
<p className={styles.modalDesc}>说明:.......</p>
<Divider className={styles.modalDivider} />
<AddPermissions
cRef={this.addPermissionRef}
form={this.formModalRef?.current?.form}
selectList={serverList}
/>
</FormModal>
import React, {useState, useEffect, useImperativeHandle} from 'react';
import {Form, Select, Button, Input} from 'antd';
import {CloseCircleFilled, PlusOutlined} from '@ant-design/icons';
import styles from './index.less';
const AddPermissions = ({cRef, selectList, form}) => {
const [list, setList] = useState([]);
const [selected, setSelected] = useState();
useEffect(() => {
setList(selectList.map(item => ({
label: item.name,
value: JSON.stringify({value: item.code, type: item.type}),
disabled: item.disabled || false
})));
}, [selectList]);
const clearSelect = () => {
setSelected([]);
setList(selectList.map(item => ({
label: item.name,
value: JSON.stringify({value: item.code, type: item.type}),
disabled: false
})));
};
let addFn;
const handleClickDisabled = () => {
setTimeout(() => {
if (form) {
let res = form.getFieldValue('permission');
setSelected(res);
let disabledAry = [];
res.map(item => {
if (item?.serviceCode === undefined) {
return;
}
let index = list.findIndex(attr => attr.value === item.serviceCode);
if (index > -1) {
disabledAry.push(index);
}
});
let _list = list.map((item, index) => {
item.disabled = disabledAry.findIndex(attr => attr === index) > -1;
return item;
});
_list = _list.sort((a, b) => a.disabled - b.disabled);
setList(_list);
}
});
};
const setContent = (key, need) => {
const contentObj = {
HOUR: '每日最大处理量',
QPS: '瞬时最大并发量',
CONNECTION: '瞬时最大并发量'
};
const unitObj = {
HOUR: '小时',
QPS: '并发',
CONNECTION: '并发'
};
if (!selected) {
return need === 'unit' ? unitObj.HOUR : contentObj.HOUR;
}
if (!selected[key]) {
return need === 'unit' ? unitObj.HOUR : contentObj.HOUR;
}
const res = JSON.parse(selected[key].serviceCode).type;
return (need === 'unit' ? unitObj : contentObj)[res];
};
useImperativeHandle(cRef, () => ({
addFn: addFn,
clearSelect,
handleClickDisabled
}));
return (<div>
<Form.List
name="permission"
labelCol={{span: 0}}
wrapperCol={{span: 24}}
>
{(fields, {add, remove}) => {
addFn = add;
return (
<div>
<Form.Item>
<Button
disabled={fields.length >= list.length}
onClick={() => {
add();
}}
type='primary'
icon={<PlusOutlined/>}
>添加服务权限</Button>
</Form.Item>
{fields.map(field => (
<Form.Item
key={field.key}
style={{marginBottom: 0}}
labelCol={{span: 0}}
wrapperCol={{span: 24}}
>
<div className={styles.addIcon}>
<div className={styles.addIcon}>
<Form.Item
{...field}
key={field.key + '1'}
name={[field.name, 'serviceCode']}
fieldKey={[field.fieldKey, 'serviceCode']}
rules={[
{
required: true,
message: '请选择服务名称'
}
]}
className={styles.addIcon}
>
<Select
onChange={handleClickDisabled}
className={styles.addIcon}
placeholder='请选择服务名称'
options={list}
/>
</Form.Item>
<span className={styles.addIcon}>
{setContent(field.fieldKey)}
</span>
<Form.Item
{...field}
key={field.key + '2'}
name={[field.name, 'value']}
fieldKey={[field.fieldKey, 'value']}
rules={[
{
required: true,
message: '请输入数字'
},
{
validator: (rule, value) => {
if (value === undefined || value === '') {
return Promise.resolve();
}
const reg = /^-?\d*(\.\d*)?$/;
if ((!isNaN(value) && reg.test(value))) {
if (/-/.test(`${value}`)) {
return Promise.reject('请输入正数');
}
return Promise.resolve();
}
return Promise.reject('请输入数字');
}
}
]}
className={styles.addIcon}
>
<Input
placeholder='请输入'
className={styles.addIcon}
/>
</Form.Item>
<span className={styles.addIcon}>
{setContent(field.fieldKey, 'unit')}
</span>
</div>
{fields.length > 1 ? (
<CloseCircleFilled
className={styles.addIcon}
onClick={() => {
remove(field.name);
handleClickDisabled();
}}
/>
) : <span className={styles.addIcon}/>}
</div>
</Form.Item>
))}
</div>
);
}}
</Form.List>
</div>);
};
export default AddPermissions;
import React, {useState, useImperativeHandle, useEffect} from 'react';
import {Modal, Form} from 'antd';
import renderForm from '@/utils/renderForm';
import styles from './index.less';
const FormModal = ({cRef, formList, title: _title, width, wrapperCol, labelCol, children, onCancel, onFinish, key, ...props}) => {
const [visible, setVisible] = useState(false);
const [title, setTitle] = useState(_title || '通知');
const [form] = Form.useForm();
const handleOk = e => {
form.submit();
};
useEffect(() => {
if (!visible) {
if (form) {
form.resetFields();
}
}
}, [visible]);
useImperativeHandle(cRef, () => ({
handleOk,
setVisible,
form: form,
init: ({title} = {}) => {
setTitle(title);
}
}));
const defaultModalProps = {
closable: false,
title: title,
width: width || 520,
maskClosable: false,
forceRender: true,
wrapClassName: styles.formModal,
onOk: handleOk,
onCancel: () => {
setVisible(false);
onCancel && onCancel();
}
};
const defaultFormProps = {
form: form,
colon: false,
labelCol: {span: labelCol || 4},
wrapperCol: {span: wrapperCol || 20},
labelAlign: 'left',
onFinish: onFinish
};
const FormContent = formList.map(item => renderForm(item));
return (
<Modal {...defaultModalProps} visible={visible}>
<Form {...defaultFormProps}>
{FormContent}
{children}
</Form>
</Modal>
);
};
export default FormModal;
import {Input, Radio, Form, Select} from 'antd';
import InputPassword from '@/components/InputPassword';
const formItemObj = {
'input': Input,
'radio': Radio.Group,
'select': Select,
'password': InputPassword,
'textarea': Input.TextArea
};
const msgItem = {
'input': '请输入',
'radio': '请选择',
'select': '请选择',
'password': '请输入',
'textarea': '请输入'
};
const renderForm = obj => {
const {
formType, label, name, require = false, list = [], rules = [], props = {}, ..._formProps
}
= obj;
const {placeholder, message, extendElement, ..._props} = props;
const Tag = formItemObj[formType || 'input'];
const msg = placeholder || msgItem[formType || 'input'] + label;
const defaultProps = {
placeholder: msg,
..._props
};
return (<Form.Item
key={name}
label={label}
name={name}
rules={[
{
required: require,
message: message || msg
},
...rules
]}
{..._formProps}
>
<Tag {...defaultProps} />
</Form.Item>);
};
export default renderForm;
antd modal 统一定制化弹窗 (可以只有一个确定按钮)
import React, {useState, useEffect, useImperativeHandle} from 'react';
import {Modal, Button} from 'antd';
import styles from './index.less';
const SystemModal = ({cRef, title: _title, content: _content, width, className}) => {
const [visible, setVisible] = useState(false);
const [onlyOk, setOnlyOk] = useState(false);
const [title, setTitle] = useState(_title || '系统通知');
const [content, setContent] = useState(_content || '第三方服务删除后不可恢复,请确认是否删除?');
const [okText, setOkText] = useState('确认');
const [okButtonProps, setOkButtonProps] = useState({});
const [handleOkCallback, setHandleOkCallback] = useState(undefined);
const handleOk = () => {
if (typeof handleOkCallback === 'function') {
handleOkCallback();
}
else {
setVisible(false);
}
};
useEffect(() => {
if (!visible) {
setOnlyOk(false);
setContent(undefined);
setTitle('系统通知');
setHandleOkCallback(undefined);
}
}, [visible]);
useImperativeHandle(cRef, () => ({
handleOk,
setVisible,
setOkButtonProps,
init: ({title, content, onlyOk = false, handleOkCallback, okButtonProps, callback, okText} = {}) => {
setTitle(title);
setContent(content);
setOnlyOk(onlyOk);
setHandleOkCallback(() => handleOkCallback);
okText && setOkText(okText);
okButtonProps && setOkButtonProps(okButtonProps);
callback && callback();
}
}));
const ButtonOk = <Button type='primary' key='ok' onClick={handleOk}>{okText}</Button>;
const defaultModalProps = {
closable: false,
title: title,
zIndex: 9999,
width: width || 520,
destroyOnClose: true,
maskClosable: false,
wrapClassName: `${styles.systemModal} ${className ? className : ''}`,
footer: onlyOk ? [ButtonOk] : undefined,
okText: okText,
onOk: handleOk,
okButtonProps,
cancelText: '取消',
onCancel: () => {
setVisible(false);
}
};
return (<Modal {...defaultModalProps} visible={visible}>{content}</Modal>);
};
export default SystemModal;
.system-modal {
:global {
.ant-modal-header {
background: #3A7EF9;
padding: 10px 24px;
text-align: center;
.ant-modal-title {
color: white;
}
}
.ant-modal-body {
padding: 25px 35px 10px;
text-align: center;
font-weight: 500;
}
.ant-modal-footer {
text-align: center;
margin: 0 35px;
padding: 20px 0;
border: 0;
.ant-btn {
padding: 0 29px;
&:first-child {
margin-right: 33px;
}
&:last-child {
margin-right: 0 !important;
}
}
}
}
}
this.systemModalRef.current.setVisible(true);
this.systemModalRef.current.init({
title: '系统通知',
content: action === 'add' ? '新增成功!' : '修改成功!',
onlyOk: true,
callback: () => {
this.formModalRef.current.setVisible(false);
this.getList();
}
});
this.systemModalRef.current.init({
title: '系统通知',
content: '删除后将导致.......,请谨慎操作!是否确认删除?',
handleOkCallback: this.deleteServer
});
为什么不用json.parse 、stringify 深拷贝
1. 对象中的时间类型会被拷贝成字符串。
2. 当对象中的属性值为undefined或function时,拷贝会直接丢失。
3. 当对象中有 NaN、Infinity和-Infinity时,拷贝的值会变成null。
4. 当对象循环引用的时候会报错。
new操作符做了哪些事情
1. 创建一个新对象。
2. 将构造函数的作用域赋予这个新对象 (因此this也指向了这个新对象)。
3. 执行构造函数中的代码(为新对象添加属性)。
4. 返回这个新对象。
5. 将构造函数的prototype属性与实例的__proto__属性关联。
重绘与回流
重绘一般指节点的样式方式改变而不会影响布局的。
如: outline, visibility, color、background-color
回流一般指页面的布局发生改变。
获取位置的方法会触发回流与重绘,我们应该避免频繁使用这些属性。
offsetTop、offsetWidth、offsetheight、scrollTop、clientTop、width、heigth,
getComputedStyle()
getBoundingClientRect()
rebase 和merge 的区别
场景: 开发中一班都是先在自己的分支开发,然后将自己的分支合并到主分支。
一般有两种操作 (merge 和 rebase), 那他们有什么区别呢。
merge 会让两个分支的 commit 提交按时间排序,并且会把两个最新的commit合并成一个新的commit,
最后分支树呈现非线形结构。
rebase 之后 master 不会在多出一个commit, 并且整个master分支的commit记录呈线性结构。
rebase 后 dev 分支 的那几次提交记录的哈希值都发生了变化,
但提交的内容全部都被保留了。
参考资料: https://juejin.cn/post/7123826435357147166#comment
二分法
① 二分查找的数组是有序的
② 二分查找是从数组中间开始查找,如果找到,则结束查找并返回其在数组中的下标。
否则将数组中间值(midValue)和要找的值(findValue)进行比较,
如果 findValue > midValue , 则将数组中 midValue 右侧的所有值再次一分为二,
从中间开始查找,以此递归。
反之如果 findValue < midValue ,
则将midValue左侧的所有值一分为二进行递归查找。若递归完成后未找到,则返回-1。
let arr = [1, 2, 3, 4, 5 ,6 ,7];
const twoDiviSionOne = (arr, target) => {
return search(arr, target, 0 , arr.length - 1);
function search(arr, target, from, to) {
if(from > to ) {
return - 1;
}
const mid = Math.floor((from + to) / 2);
if(arr[mid] > target) {
return search(arr, target, from , mid - 1);
}
else if(arr[mid] < target) {
return search(arr, target, mid + 1, to);
}
else {
return mid;
}
}
}
console.warn('twoDiviSionOne(arr, 4);',twoDiviSionOne(arr, 7));
function BinarySearch2 (arr, target) {
let from = 0;
let to = arr.length - 1;
let mid = Math.floor((from + to) / 2);
while (from <= to) {
mid = Math.floor((from + to) / 2);
if (arr[mid] > target) {
to = mid - 1;
} else if (arr[mid] < target) {
from = mid + 1;
} else {
return mid;
}
}
return - 1;
}
let a = [4, 6, 7, 8];
function solution(a,l,r){
let mid = Math.floor((l+r)/2),max1,max2
if (l < r){
max1 = solution(a,l,mid)
max2 = solution(a,mid+1,r)
return (max1 > max2) ? max1 : max2;
}
else return a[l];
}
console.log(solution(a, 0, 3));
https://juejin.cn/post/6964566234864025613#comment
https://juejin.cn/post/6844904121380667399
https://blog.csdn.net/qq_45859670/article/details/122219423
对象方法
var o = {
val: '小姐姐',
set a(value) {
this.val = `${value}` + this.val;
},
get a() {
return this.val;
}
};
o.a
o.a = '我爱';
o.a
cra 使用 scss
cnpm i sass --save
import style from './index.module.scss';
<div className={style.wrap}></div>
amis使用心得
如果想法起接口
在对应的api写好请求地址
data定义后端需要数据的字段
接口调用成功即可!
requestAdaptor 可以重写请求配置。
至于组件状态,
amis会帮你维护,
因此,
接口就只关心地址和data的参数,
json配置最后的fetch
则可以看做是类似axios的东西。
如果说想在一个操作中,
显示隐藏另一个amis组件,
请查看amis联动。
关闭、取消 和主题色在fetch后面配置即可!