Kwai一些解决方案


  • 巧妙运用 continue 和 undefined(本次用到的场景是过滤无效字段,如果要判断的字段为 undefined,则用 continue 跳出赋值阶段)

  • Number (moment ().subtract (1, ‘months’).endOf (‘months’)) 可以获取到一个月之前月初的日子

  • moment ().startOf (‘months’).valueOf () 获取这个月第一天的日期

  • Homebrew 安装文档:https://www.jianshu.com/p/f4c9cf0733ea,使用命令 2 进行安装

  • 部署测试脚本

    xxx-test1.test.com : sh deploy-test.sh
    xxx-test2.test.com : sh deploy-test.sh 1
    xxx-test3.test.com : sh deploy-test.sh 2
  • 零点时间戳:new Date (new Date (你要转换的时间).toLocaleDateString ()).getTime ()

  • 23:59 时间戳:new Date (new Date (你要转换的时间).toLocaleDateString ()).getTime () + 246060*1000-1

  • React 中 Form 表单组件:被设置了 name 属性的 Form.Item 包装的控件,表单控件会自动添加 value(或 valuePropName 指定的其他属性) onChange(或 trigger 指定的其他属性),数据同步将被 Form 接管

  • 解决 optiontID 问题

    const getReqName = () => {
      const map = {};
      return (
        operationId: string,
        path: string,
        method: string,
        controllerName: string
      ) => {
        let funcName = operationId;
        if (map[controllerName] && map[controllerName][operationId] === 0) {
          funcName += `_${++map[controllerName][operationId]}`;
        } else {
          map[controllerName] = map[controllerName] || {};
          map[controllerName][operationId] = 0;
        }
        return funcName;
      };
    };
  • hook 监听路由

    import React, { FC, useState, useEffect } from "react";
    import { useLocation } from "react-router-dom";
    const Handle: FC = () => {
      // pageFlag:根据路由判断是否可以进行交互
      const [pageFlag, setPageFlag] = useState < boolean > true;
      // 这里是监听路由
      const { pathname } = useLocation();
    
      useEffect(() => {
        if (pathname.includes("/ruleOperate/riskManage/handle")) {
          setPageFlag(false);
        } else {
          setPageFlag(true);
        }
        console.log("path", pathname, "pageFlag", pageFlag);
      }, [pathname]);
    };
    export default Handle;
  • 下载乱码解决方案

    async handleDownloadList() {
      const res: any = await $Service.downloadUsingPOST_1({ param: this.queryRecallListReq.param } as any).catch(err => {
        // new Blob( array, options ); 第一个参数 是要下载的数据,它将会被放进 Blob,会被编码为UTF-8。
        // text/plain: 是一个 普通文本类型 ,需要什么类型去问度妈
        const blob = new Blob(['\uFEFF' + err], { type: 'text/plain' });
        const fileName = `risk_manage_${moment().format('YYYY-MM-DD')}.csv`;
        const elink = document.createElement('a');
        elink.download = fileName;
        elink.style.display = 'none';
        // 创建一个 url
        elink.href = URL.createObjectURL(blob);
        document.body.appendChild(elink);
        elink.click();
        // 释放 url
        URL.revokeObjectURL(elink.href);
        document.body.removeChild(elink)
      })
    }
  • Uncaught (in promise) 可能需要来个 catch 嘿嘿嘿,手动滑稽 🤪

  • Antd 组件库中 Form 的 getFieldValue 获取对应字段名的值 form.getFieldValue (‘formItem 的 name 值’) 这里的 form 是 const [form] = Form.useForm ();

  • Antd 组件库中 Form 的 onValuesChange 方法:字段值更新时触发回调事件 function (changedValues, allValues)

  • 提交 git:

    • 在当前自己创建的分支下提交,git push origin 你创建的分支名

    • 提交注意点:

    • 切不过 master,提示 error: Your local changes to the following files would be overwritten by checkout: 解决方案
      git checkout – ./

    • 提交到 master 解决方案
      git pull origin master

    • git status 命令用于显示工作目录和暂存区的状态。使用此命令能看到那些修改被暂存到了,哪些没有,哪些文件没有被 Git tracked 到。

    • git checkout 你的分支名

    • git merge master

    • git 三连

    • git checkout master

    • git pull origin master

  • git commit 需要语法注意点:git commit 的时候要执行 git commit -m ‘fix: 你要提交的信息’, 遵循的规则是 https://github.com/conventional-changelog/commitlint,fix:后边要有空格

  • 表格组含有表格列注意事项:要将数据弄成 antd 所要求的,如果不是需要进行数据转换
    数据举例,这里只是举例,具体格式根据需求去决定:
    一级表头和二级表头弄成一个对象数据,{key:xxx,title:xxx,children:[几个数据]}
    表格具体内容 (dataIndex) 要和二级表头的 key 一样

    • 举个实战例子:
      这里的数据是一级表头一个接口,二级表头一个接口,具体内容一个接口
      且返回的都是一个字符串数组,但是后端这里提供的二级表头数据和具体内容顺序是一致的

      // 这里是将一级表头和二级表头合在一起,且给了每一个数据一个 id 值
      // res.data 是一级表头的接口数据,eleData是二级表头的接口返回值
      const header = res.data.map((item1: string, ind: number) => ({
        key: uuidv4(),
        title: item1,
        children: eleData[ind].map((item2: string, ind2: number) => ({
          key: uuidv4(),
          title: item2,
        })),
      }));
      
      // 这里是将二级表头单独拎出来,方便和具体内容进行操作
      let hashTable: any = [];
      header.forEach((item: any) => {
        item.children.forEach((item2: any) => {
          hashTable.push(item2);
        });
      });
      
      // 这里是具体转换表格数据的操作
      // oData 是后端返回的具体内容数据
      let ans: any = [];
      oData.forEach((item: string[], index: number) => {
        let res: any = {
          key: uuidv4(),
        };
      
        item.forEach((item2: string, index2) => {
          const targetKey = hashTable[index2].title;
          res[targetKey] = item2;
        });
        ans.push(res);
      });
  • 表单初始化
    表单的 initialValues 不能接收异步数据,要用表单的 form.setFieldsValue 去进行初始化,因为 initialVlues 不能接受 store 的异步数据

  • 表单切换时的清除操作,form.setFieldsValue ({name:[{}]})

  • React 组件不会在 foreach 循环中呈现,要用 map

  • Form.List 初始化 initialValue={[

  • 将大数组转换成多个小数组

    let result = [];
    for (let x = 0; x < Math.ceil(fieldsAlias.length / 3); x++) {
      var start = x * 3;
      var end = start + 3;
      result.push(fieldsAlias.slice(start, end));
    }
  • 动态 Form.list 默认值,应该给 name 设置 setFieldsValue 然后将 Form.List 中的 Form.Item 处理成 [{item 名字:item 值……},{item 名字:item 值……}] 这种形式

  • select 没有备注文本可能是有初始值

  • 解决格式化报错问题

    • vscode 的 settings.json 文件
      {
        "editor.formatOnType": true,
        "debug.console.fontSize": 18,
        "terminal.integrated.fontSize": 18,
        "workbench.startupEditor": "newUntitledFile",
        "workbench.editor.enablePreview": false,
        "[typescriptreact]": {
          "editor.defaultFormatter": "esbenp.prettier-vscode"
        },
        "[css]": {
          "editor.defaultFormatter": "esbenp.prettier-vscode"
        },
        "[less]": {
          "editor.defaultFormatter": "esbenp.prettier-vscode"
        },
        "editor.defaultFormatter": "esbenp.prettier-vscode",
        "editor.formatOnPaste": true,
        "javascript.preferences.quoteStyle": "single",
        "editor.tabSize": 2,
        "editor.formatOnSave": true,
        "appworks.materialSources": [],
        "workbench.iconTheme": "vscode-icons",
        "editor.fontSize": 14,
        "workbench.editor.untitled.hint": "hidden"
      }
  • 自定义校验规则

    moneyValidate = [
         ({ getFieldValue }: any) => ({
             validator: (rule: any, value: number) => {
                 const reg = /^\d{1,}[.]\d{3}$/
                 if (reg.test(getFieldValue('billAmount'))) {
                     this.$form.setFieldsValue({
                         accountBalanceAfterOperation: this.toFixed(this.req.accountBalanceBeforeOperation! - this.$form.getFieldValue('billAmount'), 3)
                     })
                     return Promise.resolve();
                 } else if (getFieldValue('billAmount') < 0) {
                     return Promise.reject("必须为正数")
                 } else {
                     return Promise.reject('请输入3位小数');
                 }
             }
         }),
     ]
  • 正则表达式:数字字母下划线,且可以有英文逗号

    //这里需要主要的是转义字符用 \\ 而不是 \
    rules={[
      {
        pattern: new RegExp(/^[0-9a-zA-Z_\\,]{1,}$/, 'g'),
        message: '只允许数字字母下划线,多个参数值用英文逗号分隔。',
      },
    ]}
  • 获取 url 参数

    import { useHistory, useRouteMatch } from 'react-router-dom';
    const history = useHistory();
    const routeMatch = useRouteMatch();
    useDidMount(() => {
      const { params } = routeMatch;
      const { status, id } = params as IPageStatus;
      reducers.setPageStatus({
        pageStatus: status,
        pageId: id,
      });
      if (status !== 'update') {
        reducers.setInited();
      }
      if ((params as IPageStatus).status === 'update') {
        effects.getDataConfInfo(Number(id));
      }
    });
  • 获取查询字符串

    parseUrl($context: Context) {
          const params = new URLSearchParams(decodeURI($context.router.location.search));
          const llsid = params.get('llsid');
          if (!isNumeric(llsid)) {
              return;
          }
          this.userId = params.get('userId')
          this.llsid = llsid;
          this.posName = params.get('posName');
          this.time = Number(params.get('time'));
    }
  • 获取 url 参数 2

    export function getQueryString(searchUrl) {
    //得到指定url参数
    var params = {} as any;
    var search = searchUrl;
    if (search.indexOf('?') !== -1) {
      var searchArr = search.substr(1).split('&');
      searchArr.forEach(function(item) {
        var paramsArr = item.split('=');
        params[paramsArr[0]] = paramsArr[1];
      });
    }
    return params;
    }
  • 解决随着其他内容变化而变化死循环的问题

    const [formatArr, setFormatArr] = useState([]);
    const arr1 = props.form.getFieldValue("EditCorrlationSheet");
    const arr2 = props.form.getFieldValue("EditCorrlationSheetTwo");
    useEffect(() => {
      let mergeArr = [arr1, arr2];
      let formatArr = [];
      mergeArr.forEach((ele: any) => {
        ele?.forEach((item: any) => {
          const { price1, price2, price3 } = item;
          if (price1 !== "" && price1 !== undefined) {
            formatArr.push(price1);
          }
          if (price2 !== "" && price2 !== undefined) {
            formatArr.push(price2);
          }
          if (price3 !== "" && price3 !== undefined) {
            formatArr.push(price3);
          }
        });
      });
      setFormatArr(formatArr);
    }, [arr1, arr2]);
  • 文件预览事件

    async handlePreview(file: any) {
          if (file.type !== "image/jpeg" && file.type !== "image/png") {
              return
          }
    
          if (!file.url && !file.preview) {
              file.preview = await this.getBase64(file.originFileObj)
          }
          this.previewImage = file.url || file.preview
          this.previewVisible = true
          this.previewTitle = file.name || file.url.substring(file.url.lastIndexOf('/') + 1)
      }
  • 文件下载事件

    handleDownload(file: any) {
      const fileName = file.response.data
      this.downloadFile({
          url: '/rest/frameMargin/download',
          data: {
              fileName,
          },
          filename: file.name,
          ext: fileName ? this.getFileExt(fileName) : undefined,
      })
    }
    
      async downloadFile({ url, filename, method = 'GET', data, ext }: Params) {
        const config: any = {
            cache: 'no-cache',
            credentials: 'same-origin',
            headers: {
                'content-type': 'application/octet-stream',
            },
            method,
        }
    
        if (data) {
            if (method === 'GET') {
                url = `${url}?${this.param(data)}`
            } else if (method === 'POST') {
                config.body = JSON.stringify(data)
            }
        }
    
        fetch(url, config)
            .then(res => res.blob())
            .then(blob => {
                const fileUrl = window.URL.createObjectURL(blob)
                const link = document.createElement('a')
    
                link.href = fileUrl
                link.setAttribute('download', `${filename}`)
                link.click()
        })
    }
  • event 值转换成字段值

    normFile(e: any) {
      if (Array.isArray(e)) {
          return e;
      }
      if (e.file.status === 'done') {
          const response = e.file.response
          if (response.result === 9) {
              e.fileList = e.fileList.filter((file: any) => file.response.result !== 9)
              $Message.error(response.errorMsg || '上传文件失败!')
          }
          if (response.result !== 1) {
              e.fileList = e.fileList.filter((file: any) => file.response.result !== 1)
              $Message.error(response.errorMsg || '请求失败,请重试!')
          }
      }
    
      return e && e.fileList
    };
  • antd 组件 Modal 中的 destroyOnClose={true}:关闭时销毁 Modal 里的子元素,当 和 Form 一起配合使用时,设置 destroyOnClose 也不会在 Modal 关闭时销毁表单字段数据,需要设置

    。

  • 页面中的表单无法设置默认值的情况:

// 把它扔到宏任务里边去。。。。就是这么狗血。。。
setTimeout(() => {
  this.$form.setFieldsValue({
    orderNo: 1123,
  });
});

文章作者: Mrr-cxh
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Mrr-cxh !
赏
 上一篇
Vue3 Vue3
Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
2022-06-20
下一篇 
ReactRouter6 ReactRouter6
React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”。
2022-06-16
  目录