Vue模板语法不能满足你那就来试试JSX吧

您好,我是沧沧凉凉,是一名前端开发者,目前在掘金知乎以及个人博客上同步发表一些学习前端时遇到的趣事和知识,欢迎关注。


其实对于在Vue中如何使用JSX我也是探寻了很久,但是一直没有找到什么好的机会尝试一下,一个原因是因为如果你在项目中使用JSX,别人来接手你代码时他可能并不会使用JSX。

第二个原因是因为Vue中的JSX并不是完全的JSX,不光比如React来讲少了很多功能,同时对于Vue自身的模板语法来讲也少了v-module的加持,所以也无法在Vue项目中大范围的使用JSX。

不过对于JSX这种神奇的语法,作为一个前端开发者,还是有学习的必要的,至于JSX是不是起源于React我也并不清楚,但是编写React肯定要使用到JSX,JSX有以下的几个优点:

  • JSX执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是类型安全的,在编译过程中就能发现错误。
  • 使用JSX编写模板更加简单快速。

而在Vue中,我们一般使用的是模板语法,即:

<template>
  <div>
    Hello,World!
  </div>
</template>

相信大部分人都是使用的这种模板语法来编写Vue项目,确实,这种写法能够应付我们项目中的绝大多数场景,但是对于一些特别极端的场景来说,使用这种语法就显得十分麻烦。

例如在一个比较大的组件中有几个地方代码比较耦合,但是该代码量非常少,而且仅仅只会用在当前界面,这个时候使用Vue模板语法的话就无法直接在当前文件中创建另一个新的组件,只有重新创建一个.vue,而使用JSX就不同,它可以直接在当前文件中再创建一个新的组件。

还有一种情况是一些比较复杂的递归组件,使用vue模板语法来写就显得比较困难,因为JSX拥有JavaScript的完全编程能力,所以它也可以使用几乎所有的JavaScript语法,从而来书写递归组件。

Vue2.x

在Vue官方文档中,有一章是讲《渲染函数 & JSX》,但是这一章非常多的笔墨都是在讲渲染函数,关于JSX只是轻描淡写的一笔带过,那么渲染函数是什么呢?这显然不是本章的重点,不过简单的将,虚拟DOM的实现就离不开渲染函数,并且Vue的模板语法最终也是会编译成为渲染函数,而JSX同样也会被编译成为渲染函数。

在Vue中,JSX语法有两种使用方式,一种是写在.vue文件中,这种写法的好处就是可以使用Vue带来的<style>模板语法,坏处就是失去了很多JSX提示。

vue文件

下面我们来看一下在.vue文件中如何使用JSX:

<script>
// 声明NewTest组件
const NewTest = {
  name: "NewTest",
  render() {
    return <header>NewTest</header>;
  }
};
    
// 声明SlotTest组件
const SlotTest = {
  name: "SlotTest",
  data() {
    return {
      time: "2021-4-18 15:52:59"
    };
  },
  render() {
    return (
      <div>
        {this.time}
        <NewTest />
      </div>
    );
  }
};

export default SlotTest;
</script>

<style scoped>
header {
  font-size: 30px;
  font-weight: bold;
}
</style>

上面的代码中声明了两个组件,分别是 NewTest SlotTest,默认导出的是SlotTest。

jsx文件

还有一种方法就是写在.JSX文件中,这种写法的好处就是获得JSX的提示,坏处就是不能享受Vue的<style>模板语法,你需要另想办法实现css样式之间的隔离。

const NewTest = {
  name: "NewTest",
  render() {
    return <div>NewTest</div>;
  }
};

const SlotTest = {
  name: "SlotTest",
  data() {
    return {
      time: "2021-4-18 15:52:59"
    };
  },
  render() {
    return (
      <div>
        {this.time}
        <NewTest />
      </div>
    );
  }
};

export default SlotTest;

可以看到,当使用.jsx文件后,你就无法再使用<style />模板语法。所以这两种写法是各有利弊的,并且如果使用了.jsx这种后缀的文件时,引入时要加上后缀.jsx。

import SlotTest from "@/views/SlotTest.jsx";

总得来说,我还是推荐在.vue文件中书写JSX。

函数式组件

在React中,因为引入了React Hook之后,函数式组件已经不单单只用来展示,还可以处理大量的逻辑,而在Vue2.x中,函数组件依然只能用来展示数据。

// 声明NewTest组件
const NewTest = () => {
  return <header>NewTest</header>;
};

// 声明SlotTest组件
const SlotTest = () => {
  return (
    <div>
      <NewTest />
    </div>
  );
};

export default SlotTest;

可以看到,在Vue Devtools中有functional标识,并且在右侧没有任何的数据显示。

image-20210418202845094

Vue3.x!

在Vue3.x中,由于