简述Vue和React开发体验的异同(状态层)

前言

接上篇文章,本文咱们来聊聊对于状态这块,Vue和React有何异同。数组

state vs data

先说关键词命名,在Vue中,经过声明data来定义内部变量,data翻译为中文是数据的意思,这也符合Vue的总体设计,响应式数据,一个数据的变化,会引起一系列的关联动做。而在React中,则变成了关键词state,翻译过来为状态的含义,经过状态驱动视图的更新。markdown

在Vue中,数据是响应式的,这个响应式包含两方面:dom

  • JS内存中的变量值发生变化,通知DOM进行绘制
  • DOM中元素内容发生变化,通知JS内存中的变量值改变

在实现上,Vue利用JS的API,实现了点运算符的重载,利用如v-model等显式声明,经过对DOM元素的监听,及时反馈至内存变量的更新。Vue的这种作法实际上是有必定的性能损耗的,可是带来是开发者的低门槛、高效率。函数

React在状态更新这块采用的是显式声明(setState),状态更新后,调用render函数,通知DOM进行绘制,数据流的传递是单向的(固然想实现Vue中的反向更新也是简单的,只是官方并不提倡)工具

咱们来看个简单的例子,实现input组件输入值的绑定:性能

Vue:
<template>
    <input type="text" v-model="value" />
</template>
<script>
    export default {
        data() {
            return {
                value: ""
            }
        }
    }
</script>

React:
function render() {
    const [value, setValue] = useState("");
    return (
       <input type="text" onChange={(e) => setValue(e.target.value)} />
    )
}
复制代码

Vue能够经过v-model这个指令把数据进行了响应式关联,能够减小写监听回调的一部分代码,但事实上,Vue也能够写成这样:this

Vue:
<template>
    <input type="text" :value="value" @input="setValue">
</template>
<script>
    export default {
        data() {
            return {
                value: ""
            }
        },
        methods: {
            setValue(e) {
                this.value = e.target.value;
            }
        }
    }
</script>
复制代码

虽然真实开发中你们不会这么写,谁叫Vue已经提供了现成的指令了呢。编码

在Vue中,有一个比较好用的功能:computed,能够监听依赖项的改变而进行时时计算,好比咱们想实现第三个输入框为前两个输入框的值,咱们会这么写:spa

Vue:
<template>
    <input type="text" v-model="a" /> +
    <input type="text" v-model="b" /> =
    <input type="text" v-model="sum" />
</template>
<script>
    export default {
        data() {
            return {
                a: "",
                b: "",
            }
        },
        computed: {
            sum() {
                return this.a + this.b
            }
        }
    }
</script>
复制代码

computed的依赖收集

写到这里的时候,我产生了一个好奇的点,sum函数的调用时机如何肯定,直观反应是须要收集该函数的依赖项,在React中,直接会要求开发者传入一个deps数组,只要每次比较数组的引用地址就能够肯定,而在Vue中并无要求开发者声明。常见的依赖收集有如下两种方式翻译

  • 静态词法分析
  • 执行函数后获取

静态分析会比较消耗CPU性能,举个例子:

computed: {
    sum() {
        const a = "x";
        const b = a;
        const c = b;
        return this[c] * 2
    }
}
复制代码

很明显,这个函数的依赖是x变量,可是须要推到x变量须要依次推导 c => b => a => "x",若是里面涉及到循环引用还会更加复杂,显然Vue不会走这条路。那么执行代码呢,这条路貌似是可行的,由于在Vue中数据的读取操做能够被监听到,那么思路能够是:执行一次sum函数,完毕后取全部被调用get的变量,组成依赖项,查阅相关资料后,证实Vue也是这么作的。

若是代码写成这样的话:

computed: {
    sum() {
        if (Math.random() < 0.5) {
            return;
        }
        return this.a + this.b
    }
}
复制代码

这种状况下,有一半的几率致使数据没法及时更新,由于是首次执行的时候肯定依赖项的。若是想在React实现这个需求,能够本身封装自定义hooks,能够模拟实现computed的功能。

逻辑复用

再来谈谈逻辑的复用性,在React还没出Hooks以前,和Vue差很少,UI描述和逻辑是混在一块儿的,想抽也抽不出来。因此在平时开发中大部分场景都是复制代码的形式来作的,能作的一些事情也比较有限,好比抽工具库、精心设计一个组件的规格。在React Hooks出现后,这件事发生了一些变化,UI描述和逻辑自然被拆开了,逻辑的复用也变得瓜熟蒂落了。

总结

  • 从数据驱动UI上来讲,React和Vue没有什么本质上的区别,状态改变通知UI层重绘,只是Vue会比较隐晦,React则经过setState显式调用

  • Vue面向开发者作了不少“小工具”,来帮助开发者提升生产效率

  • 从开发体验上来讲,仍是仁者见仁智者见智了,毕竟你们的编码习惯都受着不少因素的影响

相关文章
相关标签/搜索