july-10th-report


July 10th report

关闭浏览器安全策略

mac

新建一个 ChromeDevUserData 文件夹,

再打开终端输入以下命令。

open -n /Applications/Google\ Chrome.app/ --args --disable-web-security --user-data-dir=/Users/v_lixiaofei04/Documents/MyChromeDevUserData

即可打开关闭安全策略后的窗口

windows

同样是新建 ChromeDevUserData 文件夹,

然后桌面复制一个 chrome 快捷方式 ,打开属性 ---> 快捷方式

在后面追加

--user-data-dir="D:\ChromeDevUserData" --test-type --disable-web-security

点保存,然后点这个快捷方式启动chrome,就是关闭安全策略后的窗口。

关闭安全策略的作用:

这也是支持跨域的一种方式。

参考资料: https://www.cnblogs.com/cmyoung/p/13355388.html

event.srcElement

event.srcElement.tagName 获得的是当前作用对象的大写标签名称 ,'DIV''A';

利用 event.srcElement 获取子对象:

  第一个子标签:event.srcElement.firstChild;

  最后一个:event.srcElement.lastChild;

  第几个子对象: event.srcElement.children[i];

  所有子对象:event.srcElement.children;

  所有子对象节点:event.srcElement.childNodes;

event.target 它永远都是直接接收事件的dom元素。

获取这个对象的id:

let targetId = event.target ? event.target : event.srcElement ;

antd Transfer

// targetKeys 表示右边的项, 类型多为 string[] , number[],

// dataSource any[] 表示左边,targetKeys 的 除外。

onSelectChange 函数包含两个参数

const onSelectChange = (sourceSelectedKeys: string[], targetSelectedKeys: string[]) => {
  
  // sourceSelectedKeys 表示左边
  
  // targetSelectedKeys 表示右边
  
  // 如果左右两边的项同时需要移位,可以把这两个参数的变量保存起来,在点击确定时一同传给后端。
  
  // 可以用对象的形式用key表示左右
  
  const saveKeys = {
      0: sourceSelectedKeys, // 左
      1: targetSelectedKeys, // 右
  };
}

/**
* nextTargetKeys 表示 变化后的右边
*
* direction 表示此次移动的方向 为 'left' || 'right'
*
* moveKeys 表示移动的 key 集合。
*
* change 事件里,只能是单向的移动,或左或右。
*/
const onChange = (nextTargetKeys: string[], direction: string, moveKeys: string[]) => {
    setTargetKeys(nextTargetKeys);

    const chooseDirection = direction === Direction.right ? 1 : 0;
    const params: SendParams = {
        categoryIdList: moveKeys,
        categoryState: chooseDirection,
    };
    changeVerticalStatus(params);
};

map async 形式

const result = arr.map(async item => {
  const res = await getApiFunc();
  return res
});

/**
* map 使用的形式得到的是 promise 数组,使用 Promise.all 来处理,
*
* 再 Promise.all(result).then(res => console.log('res', res));
* 
* .then 里面的 res 就是 正常数组,将res 保存就和平常 any[] 一样可以直接使用。
*/

分页自带跳转button => renderButtonView

/**
* 将 分页属性里的 showQuickJumper 的值设为一个函数 renderButtonView();
*
* return 一个对象,对象的键必须 是 goButton, 值可以是一个ReactNode
*
* 这样的一个按钮,在点击时,可以跳转到指定页,无须再做额外操作,
*
* 这种 点击跳转 也可以被 onChange 监听到。
*
* 如果对 button 的样式有要求,可以自行修改css。
*/

const renderGoButton = () => ({goButton: <div className={styles.goPage}>GO</div>});

classnames 插件 : 非对象形式,满足条件的class

// cn(styles['timer'], showDate && styles['plus-icon'])

<ClockCircleOutlined
    className={cn(styles['timer'], showDate && styles['plus-icon'])}
    onClick={dateClick}
/>

antd useForm 校验

/**
* values 表示表单域的字段对象
* 
* 如果有必选项没有输入,就会走catch
*/
form.validateFields()
    .then(values => {
      if (values) {
      console.log('values', values);
    }
  })
 .catch(err => console.err(err));

设置 :global 属性,要在当前组件的class下

设置 :global 属性,要在当前组件的class下, 不然会影响其他组件。

antd 自定义校验

/**
* 这种方式 change 和 提交时都可触发
*
* Promise.resolve() 表示通过
*
* Promise.reject('') 给出错误提示
*/
rules: [
  {
      validator: (rule, value) => {
          if (value === undefined || value === '') {
              return Promise.resolve();
          }
          // eslint-disable-next-line max-len
          const result = /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?                 ^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?/.test(value);
          if (result) {
              return Promise.resolve();
          }
          return Promise.reject('请输入正确的服务地址');

      }
  }
]

moment 时间时期格式化

可以格式化 new Date() 、 moment 对象, 后端传过来的字符串对象

moment(date).format('YYYY-MM-DD HH:mm:ss')

直系span

// 只会作用于自己的子元素 span , 不会影响 例如 span 下 div 的 icon 组件的 span 。
>span:nth-child(1) {} 

直接操作 dom 更改 antd message 的值

/**
*
* useState 更新不到 message 的值,明明值已经变过来了,但就是不能更新 message上的值。
*
* 怀疑是值不及时的问题,使用  sync hook 函数,发现可以拿到最新的值,但
*
* hook 无法 return message(config) 的 reactNode 。
*
* 最后无奈操作了dom。
*
*/

// 倒计时函数 使用 innerHtml 可能存在 Xss 攻击的问题,因此使用 innerText

// 值为 (5) 形式,因此 innerText[1]可以取到中间的值
const countDown = () => {
    setTimeout(() => {
        const newText = numsRef.current.innerText[1] - 1;
        numsRef.current.innerText = `(${newText})s`;
        if (newText <= 0) {
            return;
        }
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        // 递归轮询
        countDown();
    }, 1000);
};

// 封装的 message, 支持多种类型,success,warning, error

// import {MessageInstance} from 'antd/lib/message/index';

const commonMessage = (key: keyof MessageInstance, text: string, status: MessageType, dur: number) => {
  return message[`${key}`]({
      content: renderMessage(text, status),
      duration: dur,
      key: MES,
      className: cn(styles.message),
  });
};

// 使用 commonMessage
commonMessage('success', ele.name, params.status, 5);

commonMessage('warning', '输入内容不合法!', undefined, 5);


const numsRef: MutableRefObject<any> = useRef(null);

// message 定制化视图; 给到元素 numsRef 
const renderMessage = (name: string, status: string | number | undefined) => {
    return (
        <div style={
            {
                display: 'flex',
                justifyContent: 'space-between',
                height: '100%',
            }}
        >
            <div style={{lineHeight: '32px'}}>
                {
                    status
                        ? `“${name}”审核已${EXAIMNETEXT[status as ExamineType]}`
                        : name
                }
            </div>
            <div style={{marginRight: '15px', display: 'flex', alignItems: 'center'}}>
                <p style={{margin: '0px', marginRight: '10px'}} ref={numsRef}>({count})s</p>
                <CloseOutlined onClick={() => message.destroy()} style={{color: '#84868b', cursor: 'pointer'}} />
            </div>
        </div>
    );
};

forwardRef 使用

// 主要的作用是 子组件暴露方法或是变量 能够让父组件使用

// 子组件
const CreateHot = (props: PropsCreateHot, ref: ForwardedRef<Mutable>) => { 

// 暴露
useImperativeHandle(ref, () => {
        return {getFormValue, resetForm};
    });
  
  return <div>
    ...
    ..
  </div>
};

export default forwardRef<Mutable, PropsCreateHot>(CreateHot);

// 父组件

const hotRef: MutableRefObject<any> = useRef(null);

<CreateHot ref={hotRef} />

// 使用 

// 可以直接调用,也可由父组件传递给其他子组件,

// 其他子组件在发生相应行为时调用 forwardRef暴露的 函数

// 父组件直接使用

const submitForm = () => {
    hotRef.current.getFormValue();
};

react svg图标 icon 组件用法

/**
* 新建一个文件夹,
* 
* 放入svg图片,后缀以 .svg 结尾。
*
* 新建 index.tsx 文件,
*
* 文件内容如下
*/

import History from './history.svg?react';
import WaitExamine from './waitexamine.svg?react';

export const historyIcon = () => {
    return <History className="anticon" />;
};

export const waitExamineIcon = () => {
    return <WaitExamine className="anticon" />;
};

// 使用 直接调用

const renderTitleExtra = () => (
    <div
        key={1}
        className={styles.history}
        onClick={() => {
            setVisible(true);
        }}
    >
        {historyIcon()}
        <span style={{marginLeft: 5}}>history</span>
    </div>
);

/**
* 若作为路由组件的icon,直接引入,
*
* 再使用 react-router-config 插件的 renderRoutes 函数 将route数组注入即可。
*/

const route = [
      {
        path: '/companyPortrait',
        name: 'companyPortrait',
        exact: true,
        component: lazy(() => import('@/page/Home/List')),
        title: '首页',
        icon: UserPortraitIcon,
        auth: [authKeys.CUSTOMER_VIEW.CUSTOMER_VIEW],
    },
]

import {renderRoutes} from 'react-router-config';

<Router history={history}>
    {renderRoutes(routes)}
</Router>

文章作者: KarlFranz
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 reprint policy. If reproduced, please indicate source KarlFranz !
评论
  目录