当前位置: 首页 > Web前端 > vue.js

React和Vue这两个前端框架对比总结

时间:2023-03-31 14:52:12 vue.js

React和Vue是最主流的两个前端框架。最近面试总是被问到React和Vue的异同点。这一次,我将粗略地整理一下。GitHub上Star对比截图设计思路React官网介绍React是一个用于构建用户界面的JavaScript库。React推荐JSX+内联样式,也就是把HTML和CSS全部写进JavaScript,也就是“allinjs”,HTML和CSS都可以放到js里。React提倡函数式编程,推荐使用纯函数、不可变数据、单向数据流,但可以手动编写onChange等事件处理函数,实现双向数据流。结合JSX轻松实现渲染模板Vue官网介绍Vue是一个用于构建用户界面的渐进式框架。与其他大型框架不同,Vue被设计为从下到上逐层应用。Vue保留了html、css、js的分离写法,让现有的前端开发者在开发时可以保持原有的习惯,更接近于常见的web开发方式。模板是普通的html,数据绑定使用mustache风格,样式直接使用css。Vue认为数据是可变的,使用v-model实现双向数据流。构建和调试*构建工具React创建新单页应用程序的最佳方式:创建ReactAppnpxcreate-react-appmy-appcdmy-appnpmstartVue官方构建工具:vue-clinpminstall-g@vue/clivuecreatemy-appnpmrunserve#ORyarnglobaladd@vue/clivuecreatemy-appnpmrunserve*调试ReactDeveloperTools用于调试reactReduxDevTools用于调试reduxVue.jsdevtools用于调试vue、vuex和其他JSX与模板React没有模板,通过类组件的render方法的返回值或者函数组件的返回值来渲染虚拟DOM,通过原生js实现条件渲染、循环渲染、插值等。你也可以使用JSX语法糖来更简单地描述树结构;Vue使用模板,更接近HTML,js代码和css代码分离,使用mustache进行数据绑定,使用指令实现条件渲染和循环渲染等数据变化监听*数据流对比React是单向数据flow,并且不允许子组件修改父组件发送的props,组件的状态是允许修改的,可以通过setState(异步)来改变。允许通过this.state直接改变组件的状态。在vue2.x中,不允许子组件修改父组件传递的props。组件和DOM的双向绑定可以通过v-model*监听数据变化的方式来类比React组件。调用setState后,默认由于shouldComponentUpdate()的返回值为true,所以所有组件都会重新渲染,导致很多不必要的渲染。可以在组件的shouldComponentUpdate()生命周期方法中优化渲染或者直接使用官方的PureComponent(shouldComponentUpdate()进行state和properties浅比较决定是否渲染)在Vue2.x中,data中的所有properties对象通过Object.defineProperty()添加到vm。对于添加到vm的每个属性,指定一个getter/setter。操作(读/写)getter/setter内部数据中的相应属性。Vue3使用newProxy()和Reflect来指定数据的getter/setter。当设置数据时,会触发对应的setter方法,进而触发vm的watcher方法,然后数据发生变化,vm进一步触发视图更新操作。Vue可以更准确地知道数据的变化,并且只重新渲染与变化的数据绑定的DOM事件。React通过属性绑定事件。React类组件需要手动处理这个事件指向的问题。classDemoextendsReact.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(this.state);}showInfo3(){console.log(this.state);}showInfo4(数字){返回(e)=>{console.log(number);console.log(this.state);}}render(){return(

点我提示信息(不传参数)点我提示信息(无参数){this.showInfo2(e,66)}}>点我提示信息(传参)点我提示信息(传参)
)}}Vue中的事件处理函数把它们放到methods配置对象中,把各个事件处理函数放在methods上vm并将函数的this绑定到vm,通过指令实现事件绑定点我提示信息(不传参)点我提示信息(传参)constvm=newVue({el:'#root',methods:{showInfo1(event){console.log(这个);//这是vm},showInfo2(event,number){console.log(this);//这是vmconsole.log(number);//66}}})组件通信方式React组件通信的几种方式:父子组件通信:props兄弟组件(非嵌套组件):消息订阅-发布(pubs-sub),集中管理(redux,dva)孙子组件(跨级组件):消息订阅-发布(pubs-sub)、集中管理(redux、dva)、Context(生产者-消费者模式,用的少)Vue组件通信的几种方式:父子组件通信:props和自定义事件兄弟组件(非嵌套组件):全局事件总线、消息订阅-发布(pubs-sub)、集中管理(vuex、redux)孙组件(跨层组件):全局事件总线、消息订阅-发布(pubs-sub),集中管理(vuex,redux),provide/inject生态对比appletTaro(基于React)uni-app(基于Vue)mobileAppReactNativeWeex其他对比React认为dataisimmutable,所以一个Deeplynestedstatedataobj:{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来实现Component组合,vue使用mixins来实现,因为vue已经默默的为我们做了很多事情,所以如果我们直接包装组件声明返回一个HoC,那么包装好的组件是行不通的适当地。React一开始也是用mixins,但是后来觉得这种侵入组件的方式会带来很多问题,所以放弃了mixins,改用HoC。React使用props、renderprops和childrenprops来实现类似于Vue中的命名插槽、作用域插槽和默认插槽差异算法的比较。React和Vue都只进行同层比较,都使用key来优化diff算法。.React认为只要新旧虚拟DOM的标签名和key相同,就是同一个虚拟节点,Vue也是根据标签名和key是否相同来比较属性;Vue是基于snabbdom库,使用双向链表,同时比较和更新DOM,React主要是使用diff队列保存哪些DOM需要更新,获取patchtree,然后进行统一操作批量更新DOM。与Vuex相比,Redux认为数据是不可变的,所以reducer必须是纯函数,并且不允许修改传入的参数prevState,所以只能根据prevState返回一个新的state;Redux中action的值必须是一个通用对象,也就是说Redux不能实现异步action(value是一个函数),但是可以使用中间件来实现异步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是同步的,而action用于实现一些异步操作。当状态数据需要处理后再使用时,可以使用getters来处理;mapState帮助我们将状态中的数据映射到计算属性;mapGetters帮助我们将getter中的数据映射到计算属性;mapActions帮助我们生成触发动作的动作方法,即:包含$store.dispatch(xxx)的函数;mapMutations用于帮助我们生成触发突变的方法,即:包含$store.commit(xxx)的函数;使用模块和命名空间来实现模块化