1.vue-router 和 react-router的区别
首先,我们先看一下在vue-router和react-router中的用法本质
Vue-Router
- hash:使用URL hash值来作路由。默认模式
- history:依赖HTML5 History API和服务器配置。查看HTML5 History模式。
- abstract:支持所有的JavaScript运行环境,入Node.js服务器端
React-Router
- <HashRouter>URL格式为Hash路由组件
- <MemoryRouter>内存路由组件
- <NativeRouter>Native的路由组件
- <StaticRouter>地址不改变的静态路由组件
了解以上知识后,我们看一下前端路由的本质:
前端路由本质的两种支持:(改变视图的同时不会向后端发出请求)
1.hash——即地址栏URL中的#符号以及之后的数据。
2.history——利用了HTML5 History Interface中新增的pushState()和replaceState()方法。(使用需要注意兼容性)(Apache或者Nginx需要配置)
前端路由,简单来说,就是当浏览器的url产生变化时,不向服务器进行请求,而是直接控制前端页面产生变化,以期待前端在比如功能切换时,产生类似页面跳转等效果。
典型代码:
vue-router
JS:
const Foo = { template: '<div>foo</div>' } //声明的组件
const Bar = { template: '<div>bar</div>' }
const routes = [ //声明的路由数据,数组包对象
{ path: '/foo', component: Foo }, //路径+组件 需要的数据
{ path: '/bar', component: Bar }
]
const router = new VueRouter({ //new了一个路由实例,传入参数routes
routes
})
const app = new Vue({ //new一个vue实例,传入一个router参数
router
}).$mount('#app')//挂载到#app dom上
HTML:
<div id="app">
<h1>Hello App!</h1>
<p>
<router-linkto="/foo">Go to Foo</router-link> //路由跳转组件,点击跳到/foo
<router-linkto="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口-->
<router-view></router-view> // 展示匹配到的组件
</div>
react-router
JS/JSX:
// modules/Foo.js
import React from 'react'
export default React.createClass({ //导出一个类组件
render() {
return<div>Foo</div>
}
})
// modules/Bar.js
import React from 'react'
export default React.createClass({ //导出一个bar
render() {
return<div>Bar</div>
}
})
// index.js
// ...配置路由信息 , 需要引入配置的组件
render((
<Routerhistory={hashHistory}> //声明路由使用模式
<Route path="/" component={App}> //主路由入口
<Route path="/foo" component={Foo}/> //子路由
<Route path="/bar" component={Bar}/>
</Route>
</Router>
), document.getElementById('app'))
// modules/App.js
// ...
render() {
return (
<div>
<h1>React RouterTutorial</h1>
<ulrole="nav">
<li><Linkto="/foo">Go To Foo</Link></li> //linkto 跳转到foo
<li><Linkto="/bar">Go To Bar</Link></li> //linkto 跳转到bar
</ul>
{/* 路由匹配到的组件将渲染在这里 */}
{this.props.children} //子组件作为children传入父组件
</div>
)
}
// ...
接下来我们回到主题:vue-router和react-router的区别
本质区别:
- vue-router是全局配置方式,react-router是全局组件方式
- vue-router仅支持对象形式的配置,react-router支持对象形式和jsx语法的组件形式配置。
- vue-router任何组件都会被渲染到<router-view/>的位置,react-router子组件作为children被传入父组件。而根组件被渲染到<Router/>位置。
- 使用方式上的不同,获取参数的方式不同
vue-router 使用:<router-link> <router-view>
reacrt-router使用:router包裹,<linkto="" > <route>
vue-router获取参数:this.$router //全局路由的实例 this.$route //当前的路由信息
react-router获取参数:import {userParams} from "react-router-dom" let {id}=useParams()
2.如果你是管理员,做管理系统项目,vue和react你会怎么选择
vue适合webapp,适合做用户交互多,各种动态效果变化丰富的应用。特别是PC、手机的网页版,商城等页面。
原因:vue实现逻辑复杂的功能比较简单。
react适合oa系统,适合大批量的数据展示、适合做大型应用。特别适合公司的后台管理系统。
原因:react对那种比较复杂的交互,实现起来比较麻烦,没有vue方便。同时react的渲染原理是渲染整个组件树,所以,一方面是费性能,而且代码写起来逻辑复杂。但是react对批量数据操作很厉害。
总而言之,项目要求比较高的适合使用react,因为react的社区更活跃一些,尤其是各种UI框架比较稳定、系统,可以信赖。Vue的社区也很活跃,但相对而言各种组件五花八门,大多数不够完善,缺乏系统性和迭代性,对于项目的后期维护和新手入手都不太友好。
从应用上来看,react打出来的包会大一些,相对来说,vue的包小一些,如果项目场景对加载速度由要求,建议使用vue。
3.react的生命周期
挂载
constructor():组件的初始化
componentWillMount:组件将要挂载时促发
render()渲染
componentDidMount:组件第一次挂载完成时触发
更新
shouldComponentDidMount:是否需要更新数据,返回false则不更新
componentWillUpdate:将要更新数据触发
componentDidUpdate:组件更新完成触发
卸载
componentWillUnmount:组件销毁的时候触发
16.3版本后新增:getDerivedStateFrinOrios前面要加上static保留字,声明为静态方法,不然会被react忽略掉,不常用,componentWillMount,componentWillUpdate弃用
4.渲染一个react组件的过程
1.在组件渲染过程中,会先走constructor处理里面的逻辑,如:设置初始的state
2.再执行getDeriveStateFromProps钩子,return prevProps的操作就是将props的内容映射到state中,使用getDeriveStateFromProps钩子,需要先使用this.state
3.组件渲染的过程中都会走一遍componentDidMount钩子
4.如果有触发state更新,钩子会从getDeriveStateFromProps开始处理
5.再执行shouldComponentUpdate钩子,满足条件后返回true触发更新走render函数
6.render之后还要看是否有进一步的更新操作
7.看是否有getSnapshotBeforeUpdate钩子拦截 它的返回值是componentDidupdate钩子的第三个参数snapshot
8.不管有咩有getSnapshotBeforeUpdate,都会走到componentDidUpdate钩子,如果再这个过程中还有操作引起state的内容变化,会再次从getDerivedStateFromProps --- shouldComponentUpdate --- render ---getSnapshotBeforeUpdate --- componentDidUpdate
5.如果进行三次setState会发生什么,循环执行setState组件会一直重新渲染吗
setState这个方法是用来告诉react组件数据有更新,有可能需要重新渲染。它是异步的,react通常会集齐一批需要更新的组件,然后一次性更新来保证渲染的性能,所以进行三次只有一次的效果,并不会导致多次渲染。
此外再使用setState改变状态之后,立刻使用this.state去拿最新的状态往往是拿不到的,如果需要最新的state做业务的话,可以在componentDidUpdate或者setState的回调函数里获取。(官方推荐第一种)
6.react diff的原理
1.React通过制定大胆的diff策略,将 O(n3) 复杂度的问题转换成 O(n) 复杂度的问题;
React是如何将O(n3) 复杂度的问题转换成 O(n) 的?
-只进行同级比较
-不同类的React组件会被当做完全不同的DOM结构而被完全替换
-key prop:开发人员可以通过给Virtual DOM一个唯一的key属性暗示React这是同一个DOM结构,反之若key值不同则会被当做完全不同的DOM结构。
2.React通过分层求异的策略,对tree diff进行算法优化;
3.React通过相同类生成相似树形结构,不同类生成不同树形结构的策略,对component diff进行算法优化。
4.React通过设置唯一key的策略,对element diff进行算法优化;
5.建议,在开发组件时,保持稳定的DOM结构会有助于性能的提升;
6.建议,在开发过程中,尽量减少类似将最后一个节点移动到列表首部的操作,当节点数量过大或更新操作过于频繁时,在一定程度上会影响React的渲染性能。