vue转react的差异性和经验沉淀
1、react mixins和vue mixins的区别
react推荐HOC 不推荐mixins,而vue 并不认为mixins有问题
之所以导致这种差异对待的产生,其实还是有原因的。
两种框架的mixins虽然很相似,但是却存在一定的区别。
比如 react 的mixins是不允许不同的mixins内存在同名函数的,而 vue是根据引用顺序进行覆盖的。
再比如 react 的组件在使用mixins时,本身也不能再写同名函数,而 vue 同样可以覆盖mixins内的同名函数。
这个差异,导致react的mixins在使用的过程中,存在极大的局限性,所以只能通过不断地扩展二级,三级mixin进行修复和优化。
所以react内不推荐mixins,是没有问题的。
反观 vue,他并不存在这类问题,所以在vue内对于HOC和mixins都是保持乐观态度的,他也是没有问题的。
当然,相对于react的学院派风格来讲,vue如果是在超大型项目上,会有劣势。可能你有几百上千个公共组件~
2、空标签 Fragment
首先,vue是没有空标签的
Fragment 类似于小程序的 Block 标签,是空标签
如果不需要任何prop,同时工具已支持的情况下,可以使用短语法
<>
<ul>
<li></li>
</ul>
</>
3、子元素ref抛出
一般react都不建议通过ref来做通信
更推荐的还是 状态管理那套
4、类似 vue $attrs的透明包裹
<WrappedComponent {...this.props} {...this.state} />;
react里,event也在props里,这有别于vue, vue的props在 $attrs, event 在 $listeners
在react中,一般需要自行结构
const x = {
a:1,
b:1,
c:1
}
const { a, ...otherProps } = x;
console.log({
...otherProps
});
// 输出
{
b:1,
c:1
}
5、react Provider Cuonsumer这套
通过Consumer接收
或者 static contextType = userContext;
this.context =>
ps:整个使用过程更像是 vue.observable,而不太像vue的 provide inject
6、不同于vue的内置比较优化,react需要手动进行比较优化
React.PureComponent和React.memo ps: 仅能浅比较,所以传参需要注意
i.React.PureComponent 面向class
// 无法完成优化
<NocontextChild name={this.state.user.name} age={this.state.user.age}></NocontextChild>
// 正确写法
<NocontextChild {...this.state.user}></NocontextChild>
class NocontextChild extends React.PureComponent {
render(){
console.log("render testing")
return <div>{this.props.name} --- {this.props.age}</div>
}
}
ii.React.memo 相当于一个高阶函数,返还一个组件
const NocontextChild = React.memo(function(props){
console.log("render testing")
return <div>{props.name} --- {props.age}</div>
})
备注:
shouldComponentUpdate 钩子,默认 return true
PureComponent和memo其实就是对shouldComponentUpdate的一种优化,把nextProps和nextState都进行了判断
如果只想对个别参数进行判断处理,可以通过以下方式
shouldComponentUpdate(nextProps, nextState) {
if (this.props.name !== nextProps.name) {
return true; // 满足此条件触发render更新
}
if (this.state.sex !== nextState.sex) {
return true; // 满足此条件触发render更新
}
return false;
}
warning:
数组在使用浅比较时有更多的坑,建议直接使用 shouldComponentUpdate来手动判断
HOOK: useEffect、useMemo
7、diffing 算法(react/vue)
相同点:
都是不进行跨层级比较,只做同级比较。
不同点:
1.Vue进行diff时,调用patch函数,通过oldVnode和Vnode(虚拟dom)进行比较,边比较边给真实的DOM打补丁
2.节点对比
i.Vue通过sameVnode函数,对key是否一致,标签是否一致,是否同为注释,data是否一致等等在内的惊喜对比。
即使className不同时,也会认为是不同类型,立即删除重新创建
ii.react对元素进行对比,属性或者样式不同时,如className不同时,只是进行修改操作
3.列表比对
i.Vue采用从两端到中间的方式,oldChildrenVnode和childrenVnode两端各存在两个指针,两两进行比较.
如果匹配上了就按照新集合去调整旧集合,每次对比结束后,指针向队列中间移动;
粗糙易懂的源码解析:
仅当oldVnode和Vnode至少存在一个child且oldStartVnode,newStartVnode,oldEndVnode,
newEndVnode都不相同时触发位置替换。
ii.而react则是从左往右依次对比,利用元素的index和标识lastIndex进行比较。
如果满足nextIndex < lastIndex就移动元素,删除和添加则各自按照规则调整;
粗糙易懂的源码机制:
var prev = [0,1,2,3,4];
var next = [4,0,1,2,3];
for (name in next) {
var prevChild = prev[name];
var nextChild = next[name];
if (prevChild === nextChild) {
// 说明存在相同节点
// 然后调用 moveChild函数(ps:根据 child._mountIndex < lastIndex 去判断是否需要移动)
// 这将是一个依次移动的过程
...
} else {
// 挂载到对应节点
}
}
这种对比方式导致的结果:
假设当一个集合把最后一个节点(新节点)移动到最前面
react会把前面的节点依次移动
Vue会直接把最后一个节点插入到最前面
总结:Vue的diff性能是高于react
8、useReducer和vue.observable
本质上是redux/vux的阉割版
useState源码是通过useReducer实现的
无论是useReducer还是useContext,其本质还是状态管理
而vue主要是数据劫持,状态管理为辅
9、props.children和vue的slot
React中可以使用props传递任何类型的值,可以是string, array, object,也可以是一个组件等。
类组件中使用this.props.children,函数组件中使用props.children渲染传入的内容;
类似vue的slot
10、add image in js
react:import logo from './logo.png';
vue: const logo = require('./logo.png');
11、页面中使用useNavigate和useLocation(已添加到模版中)
location以props的方式传入到pages的entry里面,如果页面中需要使用location,可从props中取; 路由切换将navigate方式在app.tsx中绑定到document.event上,页面中使用navigate方法可通过引入dispatchNavigate的方法进行路由跳转;