Nodejs 常用语法
目录
- 1 ling-cloud-ui
- 2 常用语法
- 3 常用连接
- 4 axios
- 5 树的递归
- 6 Object.assign
- 7 对象复制
- 8 lodash.cloneDeep,!lodash.isEqual delete staticNextProps.columns
- 9 prop-->state
- 10 覆盖默认样式
- 11 标准PureComponent控件示例
- 12 React.Component
- 13 link
- 14 filter
- 15 命名规范
- 16 动态表达式
- 17 动态classname
- 18 自定义组件属性传递和PureComponent组件规范
- 19 字符串连接
- 20 属性的遍历
- 21 集合循环
- 22 常见问题
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}/>)}