阅读 921

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

前言

最近刚加入新公司,组内的前端技术栈以Vue为主,之前在上家公司写React会多一些,花了几个小时的时间重新过了一遍Vue的文档,毕竟已经快三年没接触了。两个事物在某些方面具有共通点,才能比较差异性,而差异性可能会是我们平常关注比较多的方向。在日常业务开发中,我们主要会关注两点,状态(state || data)和展示(UI),本文以阐述UI为主,状态层面的问题会在后续文章中做剖析。

UI层的描述方式

Vue是以template进行描述,而React以JSX进行描述。(当然Vue也可以用jsx进行描述,但其实本质还是template,只是提供开发的一层糖,这里不再做展开讨论。)

Vue:
<template>
    <div>hello</div>
</template>

React:
function render() {
    return (
       <div>hello</div>
    )
}
复制代码

这么一看感觉上差不多,但是要知道Vue也好,React也罢,都是现代化的前端开发套件,在开发的时候势必要考虑这段代码是否可以复用,放到不同的上下文后如何做通信。到这一步的时候,我们的代码就变成了这样:

Vue:
<template>
    <div>{{text}}</div>
</template>
<script>
    export default {
      props: ['text']
    }
</script>

React:
function render(props) {
    return (
       <div>{props.text}</div>
    )
}
复制代码

借助jsx天然的优势,在React中,传参和组件规格的定义可以直接使用函数的特性,而在Vue中,因为是模版,模版是不可以直接执行的,是需要把模版字符串拿来做解析的,然后再根据当前的上下文信息,去替换类似{{text}}这样的字符串,而组件规格的定义,也落到了script里,用js去做描述。而对于当前组件内可用的状态,在Vue中没有明确的区分,不论是data还是props,都可以通过this.xxx进行访问。在React中,还是有区分的,分别通过props和state去做访问。

我们再看看如何子组件调用父组件方法的

Vue:
<template>
    <div @click="onClick">{{text}}</div>
</template>
<script>
    export default {
      props: ['text'],
      methods: {
          onClick() {
              this.$emit('click')
          }
      }
    }
</script>

React:
function render(props) {
    return (
       <div onClick={props.click}>{props.text}</div>
    )
}
复制代码

React同样也是借助函数的特性,简单的完成函数调用。在Vue中得借助自身的runtime来实现,通过调用$emit,$emit继续去查找并触发目标事件,完成通信。

说完了传属性、传函数,当然在日常开发中还有传UI描述(element)的需求。

Vue:
<template>
    <modal>
        <solt></solt>
    </modal>
</template>

React:
function render(props) {
    return (
       <Modal>{props.children}</Modal>
    )
}
复制代码

我们以一个模态框举例,想要实现调用者能自绘内容区域,这时候通过属性就不够用,得传入一段UI描述(element),在Vue中,使用了一个关键字solt插槽来占位,在实例化时做替换,而在React中,一如既往的变量引用。

我们在调用modal组件的时间,代码是这样的

Vue:
<template>
    <modal>
        <template>
            <div>hello</div>
        <template>
    </modal>
</template>

React:
function render(props) {
    return (
       <Modal>
           <div>hello</div>
       </Modal>
    )
}
复制代码

好像差不多,不过涉及到多个element传入的时候,会变成这样

Vue:
<template>
    <modal>
        <template #title>
            <div>hello</div>
        <template>
        <template #content>
            <div>hello</div>
        <template>
    </modal>
</template>

React:
function render(props) {
    return (
       <Modal title={<div>hello</div>}>
           <div>hello</div>
       </Modal>
    )
}
复制代码

是不是不太一样,其实在React中也可以写成像Vu e一样平铺,不过在子组件那就成了props.children[0] props.children[1] 这样的模式了,不够语义话,所以会放在自定义参数那,只是参数类型是element,从数据结构上来说,都是一个name对应一个element,只是在写法上略有差异。

结语

Vue在template这块还是做了很多事情的,比如没有提到的指令系统等。通过描述来代替逻辑编码。好处很明显,描述会更加易读,上手成本低,但弊端也恰恰是对方的优势,逻辑编码的灵活性更高。但凡事都讲究一个够用,DSL设计的足够完备,能满足日常的开发需求,也就够了。

在Vue中,判断只有一种写法:
<template>
    <div v-if="show">hello</div>
</template>

在React中,判断有N中写法:
function render1(props) {
    if (props.show) {
        return <div>hello</div>
    }
    return null;
}
function render2(props) {
    return props.show ? <div>hello</div> : null;
}
function render3(props) {
    return props.show && <div>hello</div>;
}
...
复制代码

嗯,JS真灵活。

文章分类
前端