Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
T treasure
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 13
    • Issues 13
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • External wiki
    • External wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • FE
  • treasure
  • Issues
  • #54

Closed
Open
Created Dec 25, 2021 by JayChen@JayChenOwner

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的方法进行路由跳转;

Edited Jun 21, 2022 by JayChen
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking