Nodejs 常用语法

来自ling
跳转至: 导航搜索

ling-cloud-ui

<DictTranslate input-value='0' dict-code="tenant_status_typetest"></DictTranslate>
<DictSelect v-model="formData.isSoe" dict-code="client_soe_type" placeholder="Please choose a type" size="small" :read-only=true></DictSelect>
import DictTranslate from "@/components/dict/DictTranslate";
import DictSelect from "@/components/dict/DictSelect";

常用语法

JSON.stringify(user); JSON.parse(teantOrgString);

常用连接

https://www.angular.cn/guide/displaying-data

axios

https://blog.csdn.net/u010467784/article/details/78623173

树的递归

if ( response.data && response.data.success ) {
			let dates = response.data.data;
			let treeData = [];
			dates.forEach( ( item: any ) => {
				let child = this.buildChild( item );
				treeData.push( child );
			} );
			// console.log( treeData );
			this.setState( { treeData: treeData } );
			if ( treeData.length > 0 ) {
				let parentId = treeData[0].id;
				this.loadChilds( parentId );
			}
		}


	buildChild = ( item: any ) => {
		let childs = [];
		item.children.forEach( ( childrenItem: any ) => {
			let child = this.buildChild( childrenItem );
			childs.push( child );
		} );
		return {
			...item,
			title: item.name,
			key: item.id,
			children: childs,
			icon: <CarryOutOutlined />,
		};
	};

Object.assign

[1] Object.assign() 方法用于把一个或多个源对象的可枚举属性值复制到目标对象中,返回值为目标对象。

Object.assign(target, ...sources)

Object.assign() 只是一级属性复制,比浅拷贝多深拷贝了一层而已。用的时候,还是要注意这个问题的。

发现一个可以简单实现深拷贝的方法,当然,有一定限制,如下:

const obj1 = JSON.parse(JSON.stringify(obj));

思路就是将一个对象转成json字符串,然后又将字符串转回对象。

const defaultOpt = {
    title: {
        text: 'hello world',
        subtext: 'It\'s my world.'
    }
};

const opt = Object.assign({}, defaultOpt, {
    title: {
        subtext: 'Yes, your world.'
    }
});

console.log(opt);

// 预期结果
{
    title: {
        text: 'hello world',
        subtext: 'Yes, your world.'
    }
}
// 实际结果
{
    title: {
        subtext: 'Yes, your world.'
    }
}

对象复制

json.stringify()和json.parse()

lodash.cloneDeep,!lodash.isEqual delete staticNextProps.columns

 componentWillReceiveProps(nextProps) {
   const staticNextProps = lodash.cloneDeep(nextProps)
   delete staticNextProps.columns
   const {columns, ...otherProps} = this.props
   if (!lodash.isEqual(staticNextProps, otherProps)) {
     this.props = nextProps
     this.fetch()
   }
 }

prop-->state

 componentWillMount() {
   this.state.inputValue = this.props.record.gpa;
 }
 componentWillReceiveProps(nextProps) {
   this.state.inputValue = nextProps.record.gpa;
 }

覆盖默认样式

.events {
  list-style: none;
  margin: 0;
  padding: 0;
}

.events {
  :global .ant-badge-status {
    overflow: hidden;
    white-space: nowrap;
    width: 100%;
    text-overflow: ellipsis;
    font-size: 12px;
  }
}

dateCellRender = value => {
    const listData = this.getListData(value);
    return (
      <ul className={styles.events}>{listData.map(item => <PopoverContent item={item} key={item.content}/>)}</ul>
    );
  };

标准PureComponent控件示例

import {Badge, Popover, Rate} from 'antd';
import React, {PureComponent} from 'react';

import moment from 'moment';
import 'moment/locale/zh-cn';

moment.locale('zh-cn');

export default class PopoverContent extends PureComponent {
  getContent = item => {
    return <Rate allowHalf defaultValue={2.5}/>;
  };

  constructor(props) {
    super(props);
    this.state = {
      item: props.item,
    };
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.item !== this.props.item) {
      this.setState({
        item: nextProps.item,
      });
    }
  }

  render() {
    const {item} = this.state;
    const content = this.getContent(item);
    return (
      <Popover content={content} title="item.content" trigger="hover" placement="leftBottom">
        <li>
          <Badge status={item.type} text={item.content}/>
        </li>
      </Popover>
    );
  }
}

React.Component

import React from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import { Input, Select, Button, Icon } from 'antd'
import styles from './Search.less'

class Search extends React.Component {
  state = {
    clearVisible: false,
    selectValue: (this.props.select && this.props.selectProps) ? this.props.selectProps.defaultValue : '',
  }
  handleSearch = () => {
    const data = {
      keyword: ReactDOM.findDOMNode(this.refs.searchInput).value,
    }
    if (this.props.select) {
      data.field = this.state.selectValue
    }
    if (this.props.onSearch) this.props.onSearch(data)
  }
  handleInputChange = (e) => {
    this.setState({
      ...this.state,
      clearVisible: e.target.value !== '',
    })
  }
  handleSelectChange = (value) => {
    this.setState({
      ...this.state,
      selectValue: value,
    })
  }
  handleClearInput = () => {
    ReactDOM.findDOMNode(this.refs.searchInput).value = ''
    this.setState({
      clearVisible: false,
    })
    this.handleSearch()
  }
  render () {
    const { size, select, selectOptions, selectProps, style, keyword } = this.props
    const { clearVisible } = this.state
    return (
      <Input.Group compact size={size} className={styles.search} style={style}>
        {select && <Select ref="searchSelect" onChange={this.handleSelectChange} size={size} {...selectProps}>
          {selectOptions && selectOptions.map((item, key) => <Select.Option value={item.value} key={key}>{item.name || item.value}</Select.Option>)}
        </Select>}
        <Input ref="searchInput" size={size} onChange={this.handleInputChange} onPressEnter={this.handleSearch} defaultValue={keyword} />
        <Button size={size} type="primary" onClick={this.handleSearch}>搜索</Button>
        {clearVisible && <Icon type="cross" onClick={this.handleClearInput} />}
      </Input.Group>
    )
  }
}


Search.propTypes = {
  size: PropTypes.string,
  select: PropTypes.bool,
  selectProps: PropTypes.object,
  onSearch: PropTypes.func,
  selectOptions: PropTypes.array,
  style: PropTypes.object,
  keyword: PropTypes.string,
}

export default Search

link

https://reacttraining.com/react-router/web/api/Link

https://segmentfault.com/a/1190000010251949

import { Link } from 'react-router-dom'

<Link to="/about">About</Link>

<Link to={{
  pathname: '/courses',
  search: '?sort=name',
  hash: '#the-hash',
  state: { fromDashboard: true }
}}/>

 Route component as this.props.location
 Route render as ({ location }) => ()
 Route children as ({ location }) => ()
 withRouter as this.props.location

Web Link to
Native Link to
Redirect to
history.push
history.replace

locationurl ={
  key: 'ac3df4', // not with HashHistory!
  pathname: '/somewhere'
  search: '?some=search-string',
  hash: '#howdy',
  state: {
    [userDefined]: true
  }
}
<Link to={location}/>
<Redirect to={location}/>

this.props.history.push({ pathname: '/form/advanced-form' })

this.props.history.push(locationurl )

filter

configComList = configComList.filter(_ => _.id !== payload)

命名规范

内部为handelXXX 外部实现为onXXX

 handleCancel = (e) => {
   const onCancel = this.props.onCancel;
   if (onCancel) {
     onCancel(e);
   }
 }

动态表达式

<Alert message={`You selected date: ${selectedValue && selectedValue.format('YYYY-MM-DD')}`} />

动态classname

{message}
import classNames from 'classnames';
   let alertCls = classNames(prefixCls, {
     [`${prefixCls}-${type}`]: true,
     [`${prefixCls}-close`]: !this.state.closing,
     [`${prefixCls}-with-description`]: !!description,
     [`${prefixCls}-no-icon`]: !showIcon,
     [`${prefixCls}-banner`]: !!banner,
   }, className);
         {showIcon ? <Icon className={`${prefixCls}-icon`} type={iconType} /> : null}
         {message}
         {description}
         {closeIcon}

自定义组件属性传递和PureComponent组件规范

agenda传递到state是因为props中agenda为空时会报错,语法不简洁

        <AgendaModal visible={this.state.editModalVisible} onOk={() => this.onModalOk()}
                     onCancel={() => this.onModalCancel()} agenda={this.state.currentAgenda}>
        </AgendaModal>
import {Modal, Row} from 'antd';
import React, {PureComponent} from 'react';
import {red} from './index.less';
// @Form.create()
export default class AgendaModal extends PureComponent {
  state = {
    agenda: {},
  };

  constructor(props) {
    super(props);
    this.state = {
      agenda: props.agenda,
    };
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.agenda !== this.props.agenda) {
      this.setState({
        agenda: nextProps.agenda,
      });
    }
  }

  render() {
    return (
      <Modal
        title="Vertically centered modal dialog"
        wrapClassName="vertical-center-modal"
        visible={this.props.visible}
        onCancel={this.props.onCancel}
        onOk={this.props.onOk}
        // onOk={() => this.setModal2Visible(false)}
        // onCancel={() => this.setModal2Visible(false)}
      >
        <p>`You selected date: '+{this.state.agenda.content}</p>
        <p>some contents...</p>
      </Modal>
    );
  }
}

字符串连接

selectedOptions.map(o => o.label).join(',');

属性的遍历

S6 一共有 5 种方法可以遍历对象的属性。

(1)for...in

for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

(2)Object.keys(obj)

Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

(3)Object.getOwnPropertyNames(obj)

Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

(4)Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。

(5)Reflect.ownKeys(obj)

Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。

首先遍历所有数值键,按照数值升序排列。

其次遍历所有字符串键,按照加入时间升序排列。

最后遍历所有 Symbol 键,按照加入时间升序排列。

Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
// ['2', '10', 'b', 'a', Symbol()]

上面代码中,Reflect.ownKeys方法返回一个数组,包含了参数对象的所有属性。这个数组的属性次序是这样的,首先是数值属性2和10,其次是字符串属性b和a,最后是 Symbol 属性。

集合循环

array1.forEach(function(item,index){
 console.log(item+'---'+index);
});

常见问题

Each child in an array or iterator should have a unique "key" prop

    {listData.map(item => <PopoverContent item={item}/>)}

==>

    {listData.map(item => <PopoverContent item={item} key={item.content}/>)}