共同点: 都是用虚拟dom、提供了响应式和组件化的试图组件、都有自己的周边
虚拟dom:
Vue: vue在2.0版本后引入了vdom。vdom是基于snabbdom库做的修改。先通过h函数将js模拟的DOm结构转换为虚拟dom之后,如果是初次渲染,则通过patch函数将虚拟dom转换成真实的dom渲染到页面上。如果是二次渲染,通过diff算法,找到俩个虚拟dom之间的最小变更,patch函数进行更新
React: react定义一种类似于xml的js扩展语法:xml+js,Babel会把jsx转译成React.createElement()函数调用。用来创建react虚拟dom
区别:
// 重新定义属性, J监听起来
function defineReactive(tartget, key ,value) {
// 深度监听
observer(value)
// 核心api
Object.defineProperty(target, key, {
get() {
return value
},
set(newValue) {
if(newValue !== value) {
//深度监听
observer(newValue)
value = newValue
// 触发更新视图
updateView()
}
}
})
}
// 监听对象属性
function observer(target) {
if(typeof target !== 'object' || tartget === null) {
// 不是数组或对象
return target
}
if(Array.isArray(target)) {
target._proto_ = arrProto
}
// 重新定义各个属性(for in也可以遍历数组)
for(let key in target) {
defineReactive(target, key, target[key])
}
}
Vue3用Proxy来实现响应式,Proxy对象用来创建一个对象的代理,从而实现基本操作的拦截和自定义(如查找、赋值、枚举、函数调用等)。Reflect: 递归是在 get方法即什么时候调用(obj.info)时什么时候,递归;性能提升、新增属性在set方法中触发,可以监听到、可监听数组变化; 无法兼容所有浏览器
React是 执行setState告知React数据已发生了变化。setState之后会重新走渲染流程,根据最新的state来创建ReactElement对象;setState第二个参数传入callback拿到更新后的state ;
3、渲染性能
Vue通过建立一个虚拟DOM对真是DOM发生的变化进行追踪;
new Vue,执行初始化; 挂载$mount方法,通过自定义render方法、template、el生成render函数; 通过watcher监听数据的变化; 当数据变化时,Render函数执行生成VNode对象; ps:虚拟dom: 基于snnabDom库:h函数(生成vnode)、patch函数根据diff算法更新dom 通过patch方法,对比新旧VNode对象,通过DOM Diff算法,添加、修改、删除真正的DOM元素
React的渲染建立在虚拟dom上, 状态发生变化时 setState, React重新渲染虚拟dom: render
Vue和react的diff算法,都是不进行跨层级比较,只做同级比较。如果节点没有就删除节点。对于不同类型的节点,直接替换
vue diff时调动patch函数,参数是vnode和oldVnode,分别代表新旧节点
vue比对节点,当节点元素类型相同,但是className不同,认为是不同类型元素,删除重建,而react会认为是同类型节点,只是修改节点属性
vue的列表对比,采用的是两端到中间比对的方式,而react采用的是从左到右依次对比的方式。当一个集合只是把最后一个节点移到了第一个,react会把前面的节点依次移动,而vue只会把最后一个节点移到第一个。总体上,vue的方式比较高效。
vuex是redux的基础上进行改变
vuex同步异步方式不一样
view -> commit -> mutations -> state变化 -> view变化 (同步操作)
view ->dispatch -> actions -> mutations -> state变化 -> view变化(异步操作)
// a组件中 import {mapGetters, mapMutations} from 'vuex'; computed: { ...mapGetters(['loading']), }, methods: { ...mapMutations(['updateIsLoading']), } // store文件夹下的 某个js文件 export default { state: { isLoading: false, //数据分析中 list: [] }, getters: { isLoading: state => state.isLoading, }, mutations: { updateIsLoading(state, payload) { state.isLoading = payload; }, updateList(state, payload) { state.list = payload } }, action: { // data是请求的参数,可有可无 requestList(context, data) { axios.get(url).then(res=>{ context.commit('updateList, res.data.list); }) } } }
redux的同步异步方式一样
view -> dispatch -> actions -> reducers -> state变化 -> view变化(同步异步一样)
vueX只能和vue配合,vuex把 redux里边的reducer部分改成了 mutations, 但是reducer里边需要分情况,判断action的type, 但是vuex里边的mutations,里边直接写方法就ok vuex取消了reducer中 action概念。redux中action必须是一个对象, vuex只要传递必要参数即可,形式不做要求
1 react-redux中的 provider 作用 ,通过react的context传递 subscription 和 redux中的store,并且建立了一个最顶部根Subscription。
2 Subscription 的作用:起到发布订阅作用,一方面订阅connect包裹组件的更新函数,一方面通过store.subscribe一致派发更新。
3 Subscription假设存在这父级的情况,会把本身的更新函数,传递给父级Subscription来一致订阅。
4. 路由: 路由跳转对比
vue-router
1.npm安装;
2. router.js
Vue.use(VueRouter) const routes = [{name:'', path:'',component:Map}] const router = new VueRouter({ mode: 'history', // 还有 hash routes routes }) export default router;
3.main.js
new Vue({router, render: h=>h(App)}).$mount('#app')
react-router、react-router-dom
不需要单独的router文件
1.yarn add 安装;
2. routes.js
import { Route, Redirect, Switch } from 'react-router-dom' const Index = () => (
) export default Index } exact key="first" /> 3.使用:App.js
import { BrowserRouter } from 'react-router-dom' import Routes from './routes' import store from './store' render() { return (
) }