React和Vue是目前前端最支流的两大框架,最近面试总是被问及React和Vue的异同比照,这次就大略梳理一下。

GitHub上star比照截图


设计思维

React官网介绍React是一个用于构建用户界面的 JavaScript 库。React举荐JSX + inline style, 也就是把HTML和CSS全都写进JavaScript了,即 ”all in js“,HTML和css都能够放到js中。React主张函数编程,举荐应用纯函数,数据不可变,单向数据流,然而能够手动编写onChange等事件处理函数实现双向数据流。联合JSX轻松实现渲染模板

Vue官网介绍Vue是一套用于构建用户界面的渐进式框架,与其它大型框架不同的是,Vue 被设计为能够自底向上逐层利用。Vue保留了html、css、js拆散的写法,使得现有的前端开发者在开发的时候能放弃原有的习惯,更靠近罕用的web开发方式,模板就是一般的html,数据绑定应用mustache格调,款式间接应用css。Vue认为数据是可变的,应用v-model实现双向数据流。

构建与调试

* 构建工具

React创立新的单页利用的最佳形式: Create React App

npx create-react-app my-appcd my-appnpm start

Vue官网构建工具: vue-cli

npm install -g @vue/clivue create my-appnpm run serve# ORyarn global add @vue/clivue create my-appnpm run serve

* 调试

React Developer Tools用来调试react
Redux DevTools用来调试redux
Vue.js devtools用来调试vue,vuex等

JSX vs 模板

React没有模板,是通过类组件的render办法的返回值或者函数式组件的返回值来渲染虚构DOM,通过原生js来实现条件渲染、循环渲染、插值等。也能够应用JSX语法糖来更简略地去形容树状构造;
Vue则是应用模板,模板更贴近HTML与js代码、css代码分来到,应用mustache进行数据绑定,应用指令来实现条件渲染、循环渲染等

数据变动监听

* 数据流比照


React是单向数据流,且是不容许子组件批改父组件传来的props,组件的state是容许批改的,能够通过setState(异步的)来进行更改,不容许通过this.state这种形式间接更改组件的状态。vue2.x中也不容许子组件批改父组件传递的props,组件与DOM之间能够通过v-model双向绑定

* 监听数据变动形式比照

React组件在调用setState后,默认状况下因为shouldComponentUpdate()里的返回值是true所以全副组件都会从新渲染,造成很多不必要的渲染,能够通过在组件的shouldComponentUpdate()生命周期办法中来进行渲染优化或者间接应用官网的PureComponent(shouldComponentUpdate()中进行状态和属性的浅比拟来决定是否须要渲染)
Vue2.x中通过Object.defineProperty()把data对象中所有属性增加到vm上。为每一个增加到vm上的属性,都指定一个getter/setter。在getter/setter外部去操作(读/写)data中对应的属性。Vue3中通过new Proxy()和Reflect来为数据指定一个getter/setter。当设置数据的时候会触发对应的setter办法,从而进一步触发vm的watcher办法,而后数据更改,vm则会进一步触发视图更新操作。vue可能更加准确的晓得数据变动,只从新渲染与变动数据绑定的DOM

事件

React通过属性来绑定事件,React类组件须要本人手动处理事件this指向的问题

        class Demo extends React.Component{            /*                 通过onXxx属性指定事件处理函数(留神大小写)                        a.React应用的是自定义(合成)事件, 而不是应用的原生DOM事件 —————— 为了更好的兼容性                        b.React中的事件是通过事件委托形式解决的(委托给组件最外层的元素) ————————为了的高效             */            constructor(props){                super(props);                //初始化状态                this.state = {                    number: 22                }                //解决this指向问题                this.showInfo3 = this.showInfo3.bind(this)            }                        showInfo1 = ()=> {                console.log(this.state);            }            showInfo2 = (e, number)=> {                console.log(number);                console.log(this.state);            }            showInfo3() {                console.log(this.state);            }            showInfo4(number) {                return (e) => {                    console.log(number);                    console.log(this.state);                }            }            render(){                return(                    <div>                        <button onClick={this.showInfo1}>点我提示信息(不传参)</button>                        <button onClick={this.showInfo3}>点我提示信息(不传参)</button>                        <button onClick={(e) => {this.showInfo2(e,66)}}>点我提示信息(传参)</button>                        <button onClick={this.showInfo4(88)}>点我提示信息(传参)</button>                    </div>                )            }        }

Vue中的事件处理函数都放到methods配置对象中,并把methods中的每一个事件处理函数都放到vm身上并把函数的this绑定到vm身上,通过指令来实现事件绑定

<button @click="showInfo1">点我提示信息(不传参)</button><button @click="showInfo2($event,66)">点我提示信息(传参)</button>        const vm = new Vue({            el:'#root',            methods:{                showInfo1(event){                    console.log(this); //此处的this是vm                },                showInfo2(event,number){                    console.log(this); //此处的this是vm                    console.log(number); //66                }            }        })

组件通信形式

React组件通信的几种形式:

  1. 父子组件通信:props
  2. 兄弟组件(非嵌套组件):音讯订阅-公布(pubs-sub)、集中式治理(redux、dva)
  3. 祖孙组件(跨级组件):音讯订阅-公布(pubs-sub)、集中式治理(redux、dva)、Context(生产者-消费者模式,用的少)

Vue组件通信的几种形式:

  1. 父子组件通信:props与自定义事件
  2. 兄弟组件(非嵌套组件):全局事件总线、音讯订阅-公布(pubs-sub)、集中式治理(vuex、redux)
  3. 祖孙组件(跨级组件):全局事件总线、音讯订阅-公布(pubs-sub)、集中式治理(vuex、redux)、provide/inject

生态比照

小程序

  • Taro(基于React)
  • uni-app(基于Vue)

挪动端App

  • ReactNative
  • Weex

其余比照

  • React认为数据不可变,所以一个嵌套比拟深的状态数据obj:{a:{b:{c: '2'}}},批改obj.a.b.c = '3'是不会进行页面渲染的,只有this.setState({obj:{a:{b:{c: '3'}}}})才会进行页面渲染。Vue认为数据是可变的,然而只有data中初始化的数据才是响应式的,间接data中某个对象数据增加新数据是无奈实现响应式的,得应用Vue.set(),对于数组,Vue不容许间接利用索引来批改数组能够应用Vue.set()或array.splice()
  • React应用高阶组件HoC来实现组件组合,vue则应用mixins来实现,因为vue默默帮咱们做了这么多事,所以咱们本人如果间接把组件的申明包装一下,返回一个HoC,那么这个被包装的组件就无奈失常工作。React最早也是应用mixins的,不过起初他们感觉这种形式对组件侵入太强会导致很多问题,就弃用了mixins转而应用HoC。
  • React应用props、render props与children props来实现相似Vue中的具名插槽、作用域插槽和默认插槽
  • diff算法比照,React和Vue都只进行同层比拟,且都是用key来优化diff算法。React中认为只有新旧虚构DOM的标签名和key一样就是同一个虚构节点,而Vue在标签名和key雷同的根底上还要比照属性;Vue基于snabbdom库,应用双向链表,边比照,边更新DOM,React次要应用diff队列保留须要更新哪些DOM,失去patch树,再对立操作批量更新DOM。

Redux 与 Vuex比照


  • Redux认为数据是不可变的,所以reducer中必须是纯函数,不容许批改传入的参数prevState,所以只能返回一个基于prevState的一个全新的state;
  • Redux中的action的值必须是一个个别对象,这也就注定Redux不能实现异步action(值为函数),然而能够应用中间件来实现异步action,罕用的有redux-thunk、 redux-promise、redux-saga等;
  • Redux应用combineReducers(reducers)来实现模块化编码;
  • 应用react-redux的connect办法来创立容器组件把redux中的state、action传给UI组件的props中并实现监测redux中状态的扭转并且从新渲染组件;

  • Vuex认为数据是可变的,所以不必像reducer那样的纯函数; Vue.use(Vuex)后创立完store,则vm上就增加了$store属性
  • Vuex中mutations是同步的,actions用来实现一些异步操作,当state中的数据须要通过加工后再应用时,能够应用getters加工;
  • mapState帮忙咱们映射state中的数据为计算属性;mapGetters用于帮忙咱们映射getters中的数据为计算属性;mapActions用于帮忙咱们生成触发actions的办法,即:蕴含$store.dispatch(xxx)的函数;mapMutations用于帮忙咱们生成触发mutations的办法,即:蕴含$store.commit(xxx)的函数;
  • 应用modules和namespaced来实现模块化