最近在写一个项目,在写react的过程当中遇到过不少坑,如今总结一下,为之后的项目做参考.另外借此项目来比较一下 vue.js 和 react.js 之间的一些异同.html
刚刚开始写组件的时候,感受难度不大(跟vue差很少)。最有意思的应该是jsx语法,我的感受,jsx的功能性确实比vue的template更强,并且可读性更高.vue
举个栗子
// vue <p :id="text" :class="{'active':isActive}" v-text="'hello! ' + msg"></p>
// jsx <p id={text} className={isActive && 'active'}>hello !{msg}</p>
{}
表明要执行的js语句,它的效果相似 return
,它会有返回值.这样的话,更好理解jsx的内容,jsx里面的dom不是真正的dom,只是一种表示dom的语法,{}
里面的内容能够彻底理解为js,这种整个jsx就能够完成理解为原生js写的html模版.:
,在jsx里面则不须要.contentText
不使用{{}}
来渲染,使用由于在vue页面生成以前,模版语法部分没有渲染出来,就会在页面上先出现{{content}}
,再一闪变成真正的文本内容.再举个数组遍历渲染的栗子
// vue <ul> <li v-for="(item,index) in list" :key="index" v-if="showItem(item)"> <span v-text="item.label"></span> </li> </ul> // vue的methods属性 methods:{ showItem(item){ return item.label.indexOf('abc') !== -1 } }
// jsx <ul> {list.map((item,index) => { return item.label.indexOf('abc') !== -1 && ( <li key={index}> <span>{item.label}</span> </li> ) })} </ul>
你会发现,在一些比较简单渲染需求时,使用vue的template会比较简单直接,并且很易懂.可是若是涉及一些比较复杂的逻辑处理渲染,jsx更直观,由于jsx的语法跟js的差别不大,至关于用js来描述须要如何渲染dom结构.固然jsx并非说能够完成使用js的语法来写dom,{}
里面只能是一个表达式,因此像if else
或者switch
这种语法在{}
是不能用的.react
在写redux的时候,不是很习惯。后来慢慢的去适应。因为还用到了saga
,以致于书写方法上与redux官方的推荐的有所不一样。vuex
'action type'定义的不一样类型。
第一种状况:触发action
以后直接commit一个reducer
。redux
// action {type:'do/update-some-data',payload}
第二种状况,触发的action
会被saga
拦截,而后saga
完成必定的操做后(通常是从后台获取数据);put
一个action
,做用到reducer
。数组
// saga action {type:'start/get-some-data',payload} // reducer action {type:'success/get-some-data',payload} {type:'failed/get-some-data',payload} {type:'error/get-some-data',payload}
由于之前在写代码的时候一直都没有肯定好一个规范,致使代码风格一直有变化(已经被同事吐槽好几回了)。后来在这个项目里面看了其余的同事的代码再结合网上推荐的一些代码规范,目前总结出一些当心得(也不算什么心得)。dom
1.注释的问题我我的一直都重视的,一份好的注释可让别人在开始看代码以前就能对内容有一个大概清晰的了解。
/** * @name:组件名称 * @author:谁维护的 * @version:2017-12-28 日期或者版本号 * @description:描述 * 你会发现没有’param‘,这个部分在组件定义的地方会提到。 */
这些只是基本的信息,还能够添加其余你想加的内容。函数
2.模块引入的部分通常有这些分类
3.内部方法
内部方法通常是针对该组件须要的功能而定义的,并且不想跟类一块儿export出去。好比,组件里拿到后台的一个对象数组,须要根据这个数组的信息计算出一个值,而后在组件中使用。
若是这个方法在多个组件中使用到的话,还能够把它提到utils
文件夹中。this
4.组件定义
通常状况下,组件都会使用类来定义。好比:
class MyComponent extends Component{ static defaultProps = { a:0, b:1 } constructor(props) { super(props) this.state = { c:2, d:3 } } handleClick = () = >{ // some stuff } render() { const {a,b} = this.props const {c,d} = this.state const e = false return( <div> <div a={a} b={b}></div> <div {...{a,c}}></div> <div {...this.props} {...this.state}></div> e && {<div>some code</div>} </div> ) } }
首先,为啥子要写defaultProps
?我以为,有两点:spa
state
就略过了。
类的方法。这里使用了箭头函数
来定义,主要是为了使用this
,由于大多数状况下,handle里面都会调用this.setState
,这样写就不须要去constructor
一个个bind(this)
了。其实若是方法里面没有使用指向类的this
,用函数定义的方式也是能够的。
render部分。我通常习惯将使用到的props
和state
以及其余的数据所有在return
前定义出来。这样会更清晰明白组件里面使用了哪些数据。
另外是给元素设置属性的一些小技巧。平时最经常使用的方式是这样的key={value}
,还可使用对象解构的方式设置属性。
redux seletct & export
说到redux
必定要扯上vuex
(看完下面的内容,若是有不一样意见的战友,请不要打我)。
这里先从组件部分来看一下redux
和vuex
的区别。在组件里面主要是看如何让当前组件使用到store
中的数据和方法。
// react import React, { Component } from 'react' import { connect } from 'react-redux' import * as actions from '../actions' import { bindActionCreators } from 'redux' class MyComponent extends Component{} function mapStateToProps(state){ return { ...state, stateOne:state=>state.stateOne, stateTwo:state=>state.stateTwo } } functino mapDispatchToProps(dispatch){ return { ...bindActionCreators(actions,dispatch), handleOne:(arg)=>dispatch(actions.handleOne(arg)), handleTwo:(arg)=>dispatch(actions.handleTwo(arg)) } } export connect(mapStateToProps,mapDispatchToProps)(MyComponent)
react里面要使用connect
方法把state和dispatcher和当前组件链接起来.
// vue import { createNamespacedHelpers } from 'vuex' const { mapState, mapActions } = createNamespacedHelpers('theModule') export default { computed:{ ...mapState(['stateOne','stateTwo']), ...mapState({ stateThree:state=>state.theModule.stateThree, stateFour:state=>state.theModule.stateFour }) }, methods:{ ...mapActions(['handleOne','handleTwo']), ...mapActions({ handleThree:'actionThree', handleFour:'actionFour' }) } }
在vue里面也有相应的辅助函数,并且vuex的store
包含来数据和方法,在根组件注入以后,全部的子组件均可以经过this.$store
使用,辅助函数只是用来过滤而已.
待续...