解除冒泡

  1. e.stopPropagation(); // 冒泡
  2. e.preventDefault(); // 捕获

数组-字符串转化

[1,2,3,4,5].join(',');
// 1,2,3,4,5

'1,2,3,4,5'.split(',')
[1,2,3,4,5]

a 标签

// rel
rel="noopener noreferrer"

// 去下划线
a { text-decoration: none; }
a:focus {
    text-decoration: none !important;
}

超出省略

.line-camp(@clamp:2) {
    text-overflow: -o-ellipsis-lastline;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: @clamp;

    /*! autoprefixer: off */
    -webkit-box-orient: vertical;
}

css 换行

word-break:break-all;只对英文起作用,以字母作为换行依据
word-wrap:break-word; 只对英文起作用,以单词作为换行依据
white-space:pre-wrap; 只对中文起作用,强制换行
white-space:nowrap; 强制不换行,都起作用
white-space:nowrap; overflow:hidden; text-overflow:ellipsis;不换行,超出部分隐藏且以省略号形式出现(部分浏览器支持)

文案两端对齐

div {
    margin: 10px 0;
    width: 100px;
    border: 1px solid red;
    text-align-last: justify;
}

form 清空缓存

可以单独设置表单中的元素

autocomplete='off'

英语-月份

月份 全称 简称
1 January Jan
2 February Feb
3 March Mar
4 April Apr
5 May May
6 June Jun
7 July Jul
8 August Aug
9 September Sep
10 October Oct
11 November Nov
12 December Dec

字符编码

escape() // 编码
decodeURIComponent() // 解码

创建指定位数的数组,并填充

new Array(10).fill(0)

数组字符串 -> 字符串英文逗号隔开

[1,2,3,4,5,6].toLocaleString();

antd-Form 的 开始时间与结束时间校验

// 开始时间与结束时间的比较
momentCompare = (callback) => {
    const values = this.props.form.getFieldsValue(['prodDate', 'effectTime']);
    const { prodDate, effectTime } = values;

    if (prodDate && effectTime) {
      const start = moment(prodDate).valueOf();
      const end = moment(effectTime).valueOf();

      if (start <= end) {
        return callback('生产日期应该大于生效日期');
      } else {
        this.props.form.setFields({
          prodDate: { value: prodDate, errors: null },
          effectTime: { value: effectTime, errors: null },
        });
      }
    }
  };

DatePicker.RangePicker 组件的时间限制

<DatePicker.RangePicker
  disabledDate={(current) => {
    if (current) {
      // 在指定日期范围内选择
      return current < moment('2019-06-06') || current > moment('2019-11-11');
    }
  }}
/>

moment

// 过去 n 天
moment().add(-n, 'day');

// 昨天
moment().add(-1, 'day');

flex 对齐

  • justify-content,水平方向
    flex-start:左对齐
    flex-end:右对齐
    center:居中对齐
    space-between:两端对齐
    space-around:沿轴线均匀分布
    

react 高阶组件

import React from 'react';

const setTitle = (title) => (WrappedComponent) => {
  return class extends React.Component {
    componentDidMount() {
      document.title = title
    }
    render() {
      return <WrappedComponent {...this.props} aaa="aaa" />
    }
  }
};

export default setTitle;

修改地址栏

export function historyState(url = `${window.location.origin}${window.location.pathname}`, isBack = false) {
  window.history[isBack ? 'pushState' : 'replaceState'](Date.now(),'', url);
}

代码行数统计

find . -name “*.js”|xargs cat|grep -v -e ^$ -e ^\s*\/\/.*$|wc -l

设备适配

  • 设计图页面宽度:1920
  • html { font-size: 100px }
// 当 屏幕小于 375 时
@media screen and (max-width: 375px){
  html {
    font-size: 19.53125px !important;
  }
}

元素可编辑

请查看 contentEditable 的兼容性

<div contentEditable="true">22222</div>

react-initial

// 原理 --> [].toString() = "";[{}].toString() = ['object' 'object']
componentWillReceiveProps(nextProps) {
    if (this.props.initial && nextProps.initial) {
      if (this.props.initial.toString() !== nextProps.initial.toString()) {
        this.setState({
          // fileList: nextProps.initialFiles,
        })
      }
    }
}

边框阴影

box-shadow: 2px 0 8px rgba(0,0,0,0.2);

chart

获取 chart 对象

<Chart
  onGetG2Instance={(chart) => {
    this.chart = chart;
  }}
>
  ...
</Chart>

字符串补齐

// 前补齐
const a = '7';
a.padStart(4, '0'); // '0007'

// 后补齐
const a = '7';
a.padEnd(4, '0'); // '7000'

日期转毫秒数

// 当前时间毫秒数
Date.parse(new Date());

// 指定日期的毫秒数
Date.parse('YYYY-MM-DD');

css文本间距

letter-spacing: .6px;

emoji 正则

var regRule = /\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g;
'😈'.match(regRule);

React.Fragment 标签判断

// 如 react 对象
{
  $$typeof: Symbol(react.element),
  key: null,
  props: { children: Array(2) },
  type: Symbol(react.fragment),
}

React.isValidElement(ele) && ele.type === React.Fragment

symbol 判断

// 如 react 对象
{
  $$typeof: Symbol(react.element),
  key: null,
  props: { children: Array(2) },
  type: Symbol(react.fragment),
}

// element 指上面的对象
(typeof element.type === 'symbol') && element.type.description === 'react.fragment'

flex 布局下 overflow 失效

将 auto 自适应的 width 设置成 0

.container {
  display: flex;
}
.left {
  flex: 1;
  overflow: auto;
  width: 0;
}
.right {
  width: 500px;
}

debounce

function debounce(fn, time) {
  // 定时器,用来 setTimeout
  let timer;
  // 返回一个函数,这个函数会在一个时间区间结束后的 delay 毫秒时执行 fn 函数
  return function() {
    // 保存函数调用时的上下文和参数,传递给 fn
    const context = this;
    // eslint-disable-next-line
    const args = arguments;

    // 每次这个返回的函数被调用,就清除定时器,以保证不执行 fn
    clearTimeout(timer);

    // 当返回的函数被最后一次调用后(也就是用户停止了某个连续的操作),
    // 再过 time 毫秒就执行 fn
    timer = setTimeout(() => {
      fn.apply(context, args);
    }, time)
  }
}

dva

effects 中 callback 和 select 的使用。

export default {
  namespace: 'global',
  state: {
    data: {},
    tcgData: [],
  },
  effects: {
    *query({ payload, callback }, { call, put, select }) {
      const res = yield call(fetch, payload);

      yidld put({
        type: 'setData',
        payload: {
          data: res.dataObject,
        },
      })

      const state = yield select(state => state.global); // 获取自己或其他 namespace 的数据
      callback && callback(); // 回调函数
    },
  },
  reducers: {
    setData(state, { payload }) {
      return { ...state, ...payload };
    },
  },
}

use 的使用

import { useSelector, useDispatch } from 'dva';

const tcgDataMaster = useSelector(({ global }) => global.tcgDataMaster);
const dispatch = useDispatch();

动画

transition: all .3s ease-in;
-moz-transition: all .3s ease-in;
-webkit-transition: all .3s ease-in;

h5 防穿透

onTouchEnd={(e) => {
  e.stopPropagation(); // 冒泡
  e.preventDefault(); // 捕获
  // todo
}}

注意的细节

  1. transition 需要明确知道,开始状态和结束状态的具体数值,才能计算出中间状态。比如,height从0px变化到100px,transition可以算出中间状态。但是,transition没法算出0px到auto的中间状态,也就是说,如果开始或结束的设置是height: auto,那么就不会产生动画效果。类似的情况还有,display: none到block,background: url(foo.jpg)到url(bar.jpg)等等。
  2. 在使用 React.Children.map() 时,key 的值有可能会被替换。详见源码中的方法 cloneAndReplaceKey。 map 方法会把多层嵌套的数组经过递归处理后展平。
  3. useCallback 在 onChange 中使用时,设置第二个参数会无效,还是能执行 onChange 事件
  4. input 标签的 type=number 时,maxlength 失效。在移动端时可使用 type=tel 代替。tel 在 IOS 上会有输入框阴影,可使用 css -moz-appearance: none; -webkit-appearance: none; 去掉。

    onChange={useCallback(() => {console.log(1)}, [])}
    
  5. 正则中小括号()内的是整体,中括号[]内的是匹配其中一个。

    // 以下两种规则是相同效果
    const phoneReg = /^1(2|3|4)\d{9}$/;
    const phoneReg2 = /^1[234]\d{9}$/;
    

知识点

  1. 堆栈队列