这两款框架用了这么久,写一写心得体会用来日后缅怀。。
两个框架虽然出身不同,内在的联系却也是千丝万缕,都是通过虚拟DOM来合并DOM操作,Vue有VNode虚拟节点,React有ReactNode虚拟节点。
同为框架,自然少不了模板语法,Vue使用模板字符串简单粗暴,React为了在js里清晰地表达DOM结构,使用了jsx语法。相同点是两者最终要到被各自的createElement方法解析并形成一个层次分明的对象(虚拟dom)。
对于可以触发事件的事件监听器,React对传入的Event原型进行了再包装,删删减减,自立一个合成Event,毕竟众浏览器的口味难以调和,Vue的话则是搬运原生Event。
Vue在官网就旗帜鲜明地宣称是一个渐进式的非侵入式框架,言下之意就是某些框架是侵入式的;Vue使用Slot来解决dom结构灵活性的问题,React则利用jsx语法的props轻松实现各种dom的交叉混用,并且特意强调这和某些框架的"slot“这一概念不同,言下之意就是某些框架实现一个简单的问题老费劲了,还特意弄了个概念出来。
对于侵入,说实话我刚开始也不太明白这是个啥意思,看了官网解释,把其归结到Vue用setter实现的原理,难道把属性改成存取器就是非侵入性?这样说的话React是否就具有侵入性呢,毕竟不是简单通过setter来实现响应式的。
Vue和React两者在render函数方面的处理也有不同:
<body> Vue: <div id="app"> <button onclick="appExm.$mount('#app')">刷新Vue视图</button> <ul> <li v-for="(val,index) in arr" :key="index"> {{ val }} </li> </ul> </div> React: <div id="app2"></div> <script> var appExm = new Vue({ el: '#app', data: { arr: [1, 2, 3] }, mounted() { console.log('Vue did mount'); this.arr[1] = Math.random(); } }); </script> <script type="text/babel"> const { useEffect, Fragment, Component } = React; const render = () => ReactDOM.render(<M />, app2); // 函数组件 // const arr = [1, 2, 3]; // const M = props => { // useEffect(() => { // arr[1] = Math.random(); // }); // return ( // <Fragment> // <button onClick={render}>刷新React视图</button> // <ul> // {arr.map(ele => ( // <li>{ele}</li> // ))} // </ul> // </Fragment> // ); // }; // 类组件 class M extends Component { state = { arr: [1, 2, 3] }; componentDidMount() { console.log('React M did mount'); this.state.arr[1] = Math.random(); } // static getDerivedStateFromProps(props, state) { // state.arr[1] = Math.random(); // } render() { return ( <Fragment> <button onClick={render}>刷新React视图</button> <ul> {this.state.arr.map(ele => ( <li>{ele}</li> ))} </ul> </Fragment> ); } } render(); </script> </body>
可以发现React的加载完成后的钩子即便重复点击也只会触发一次,而Vue的钩子在每次都会触发响应周期函数,因而为了让React达到点击更新视图的效果,只有通过在其他钩子比如getDerivedStateFromProps中嵌入逻辑来实现重新渲染。