Vue.js 3 模板语法与JSX语法详解

你好,我是全栈王校长。

前面几节课,我们讲解了很多 Vue.js 3 编译相关的内容,了解完 Vue.js 两个编译打包工具后,我们是时候要开始学习如何使用 Vue.js 3 进行实际的代码开发了。

这节课,我主要会从 Vue.js 的两种主要开发语法进行讲解,它们分别是模板语法和 JSX 语法。从中你不仅能了解到两种开发语法的差异,还可以知道怎么因地制宜地根据需求场景选择合适的语法,从而扩大个人的技术知识储备,更从容地应对用 Vue.js 3 开发项目过程中遇到的各种问题。

Vue.js 从版本 1.x 到版本 3.x,官方代码案例和推荐使用都是模板语法,那么这里我们也根据官方的推荐,优先来了解一下模板语法是怎么一回事。

什么是模板语法?

我们可以把 Vue.js 的模板语法,直接理解为 HTML 语法的一种扩展,它所有的模板节点声明、属性设置和事件注册等都是按照 HTML 的语法来进行扩展设计的。按照官方的说法就是"所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析"。

现在我举个例子,带你了解下模板语法的概念及其不同内容的作用。代码如下所示:

xml 复制代码
<template>
  <div class="counter">
    <div class="text">Count: {{state.count}}</div>
    <button class="btn" v-on:click="onClick">Add</button>
  </div>
</template>

<script setup>
  import { reactive } from 'vue';
  const state = reactive({
    count: 0
  });
  const onClick = () => {
    state.count ++;
  }
</script>

<style>
.counter {
  padding: 10px;
  margin: 10px auto;
  text-align: center;
}

.counter .text {
  font-size: 28px;
  font-weight: bolder;
  color: #666666;
}

.counter .btn {
  font-size: 20px;
  padding: 0 10px;
  height: 32px;
  min-width: 80px;
  cursor: pointer;
} 
</style>

这是基于 Vue.js 3 的模板语法实现的加数器组件,代码基础结构都是基于 HTML 语法实现的,主要由视图模板、JavaScript 脚本代码和 CSS 样式代码构成的。我们拆分开来具体看看。

首先我们来看看视图层代码:

xml 复制代码
<template>
  <div class="counter">
    <div class="text">Count: {{state.count}}</div>
    <button class="btn" v-on:click="onClick">Add</button>
  </div>
</template>

上述视图代码中,只能有一个最外层的 template 标签,template 内部可以允许存在多个 template 标签,用来定义模板的"插槽"位置(slot)等更多插槽相关信息,你可以查看官方对插槽的说明了解一下。

Vue.js 的模板可以直接使用 HTML 语法的属性(Attribute),例如 class 也可以直接在 Vue.js 的模板中使用,但是 Vue.js 自己定义了一些属性语法,例如 v-on,这个就是 Vue.js 模板绑定事件的语法。以此类推,你大概可以猜到大部分 Vue.js 自定义的模板属性语法,都是以 "v-"为前缀的。更多 Vue.js 的模板语法,你可以查看官方文档

接下来我们看看 JavaScript 脚本代码:

xml 复制代码
<script setup>
  import { reactive } from 'vue';
  const state = reactive({
    count: 0
  });
  const onClick = () => {
    state.count ++;
  }
</script>

在模板语法中,JavaScript 代码只能放在 script 标签里,而且同一个文件里只能有一个顶级的 script 标签。

上述代码使用的是 Vue.js 的 Composition API,所以必须在 script 标签中声明 setup 属性。我们后续所有内容都默认是基于 Composition API 来讲解 Vue.js 3 里的 JavaScript 代码操作。这是因为它是官方推荐的 API 使用方式,使用起来简单清晰,方便复用逻辑代码,同时这也是 Vue.js 3 诞生的特色。

最后再来看下 CSS 样式代码:

xml 复制代码
<style>
.counter {
  padding: 10px;
  margin: 10px auto;
  text-align: center;
}

.counter .text {
  font-size: 28px;
  font-weight: bolder;
  color: #666666;
}

.counter .btn {
  font-size: 20px;
  padding: 0 10px;
  height: 32px;
  min-width: 80px;
  cursor: pointer;
}
</style>

这就是单文件组件(Single File Component,简称 SFC)的基本结构,通过这种形式,我们可以把 HTML 视觉效果、JavaScript 交互逻辑和 CSS 样式控制很好地整合在一起,形成一个独立的功能单元。

什么是JSX语法?

除了上面介绍的单文件组件(SFC)的模板语法,Vue.js 3 也支持 JSX 语法。JSX 是一种 JavaScript 的语法扩展,它允许你在 JavaScript 代码中编写类似 HTML 的标记。

JSX 语法最初是在 React 中广泛使用的,后来 Vue.js 也提供了对 JSX 的支持,让开发者有了更多的选择。

JSX语法的实现方式

我们还是以上面的加数器为例,用 JSX 语法来实现,代码如下所示:

javascript 复制代码
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const count = ref(0);

    const onClick = () => {
      count.value++;
    };

    return () => (
      <div class="counter">
        <div class="text">Count: {count.value}</div>
        <button class="btn" onClick={onClick}>Add</button>
      </div>
    );
  }
});

或者使用 Composition API 和 JSX 结合的方式:

javascript 复制代码
import { ref } from 'vue';

export default {
  setup() {
    const count = ref(0);

    const onClick = () => {
      count.value++;
    };

    return () => (
      <div class="counter">
        <div class="text">Count: {count.value}</div>
        <button class="btn" onClick={onClick}>Add</button>
      </div>
    );
  }
};

在 JSX 语法中,我们需要通过 Babel 插件来转换 JSX 语法,使其能够在浏览器中正常运行。

JSX 与模板语法的比较

模板语法的优势:

  1. 直观性:对于熟悉 HTML 的开发者来说,模板语法更加直观,因为它与标准的 HTML 非常相似。
  2. 简洁性:在处理简单的 UI 逻辑时,模板语法通常比 JSX 更简洁。
  3. 工具支持:大多数编辑器和 IDE 对 HTML 模板都有很好的支持,包括语法高亮、自动补全等。
  4. 性能优化:Vue.js 可以在编译时对模板进行静态分析和优化,因为模板的结构是固定的。

JSX 语法的优势:

  1. 灵活性:JSX 提供了更强大的编程能力,你可以像写 JavaScript 一样写视图逻辑,能够更灵活地处理复杂的 UI 逻辑。
  2. 逻辑表达:在处理复杂条件渲染或循环时,JSX 可能会更直观,因为你直接使用 JavaScript 的逻辑操作符。
  3. 类型检查:如果你使用 TypeScript,JSX 可以提供更好的类型检查支持。
  4. 社区生态:如果你的团队已经熟悉 React 或其他使用 JSX 的框架,那么在 Vue.js 中使用 JSX 可以降低学习成本。

如何选择模板语法还是JSX?

在实际开发中,选择哪种语法主要取决于以下几个因素:

项目类型和规模

  • 中小型项目:对于功能相对简单、页面数量不多的项目,模板语法通常是更好的选择,因为它更容易理解和维护。
  • 大型复杂项目:对于功能复杂、逻辑繁多的项目,JSX 的灵活性可能更有优势,尤其是在处理复杂的数据流和条件逻辑时。

团队技能和偏好

  • 传统前端团队:如果团队成员更熟悉 HTML 和传统的 Web 开发模式,模板语法会更受欢迎。
  • React 背景团队:如果团队成员有 React 开发经验,他们可能会更倾向于使用 JSX。

生态系统和工具链

  • Vue 生态:模板语法是 Vue 的原生语法,拥有更完善的生态系统和工具支持。
  • 跨框架项目:如果项目需要在多个框架之间共享组件逻辑,JSX 可能更容易迁移和复用。

学习曲线

  • 初学者:对于刚接触 Vue.js 的开发者,模板语法的学习曲线可能更平缓,因为它更接近标准的 HTML。
  • 有经验的开发者:有 React 或其他 JSX 经验的开发者可能会更快适应 JSX 语法。

实际应用场景举例

场景一:简单的表单组件

对于简单的表单组件,模板语法更加清晰直观:

vue 复制代码
<template>
  <form @submit.prevent="handleSubmit">
    <input 
      v-model="formData.name" 
      type="text" 
      placeholder="姓名" 
      class="form-input"
    />
    <input 
      v-model="formData.email" 
      type="email" 
      placeholder="邮箱" 
      class="form-input"
    />
    <button type="submit" class="submit-btn">提交</button>
  </form>
</template>

场景二:复杂的数据展示组件

对于需要根据多种条件动态渲染元素的复杂数据展示组件,JSX 可能更灵活:

javascript 复制代码
setup() {
  const renderData = (data, level = 0) => {
    if (!data || !Array.isArray(data)) return null;

    return data.map(item => (
      <div class={`level-${level}`}>
        {item.title && <h3>{item.title}</h3>}
        {item.content && <p>{item.content}</p>}
        {item.children && renderData(item.children, level + 1)}
      </div>
    ));
  };

  return () => (
    <div class="data-container">
      {renderData(props.dataList)}
    </div>
  );
}

总结

Vue.js 3 同时支持模板语法和 JSX 语法,各有其优势和适用场景。模板语法更适合简单直观的 UI 逻辑,而 JSX 语法则提供了更大的灵活性,适合处理复杂的视图逻辑。

作为 Vue.js 开发者,了解这两种语法的特点和适用场景,可以帮助我们在不同的项目中做出合适的选择。无论选择哪种语法,核心都是实现高质量、可维护的用户界面。

在学习 Vue.js 3 的过程中,建议先掌握模板语法,因为它更接近 Vue 的设计理念,并且拥有更好的工具支持。当你需要更灵活的视图逻辑处理能力时,再考虑使用 JSX 语法。

最重要的是,选择最适合你的团队和项目的语法,而不是盲目追求某种特定的写法。无论使用哪种语法,最终的目标都是构建出高效、稳定、易于维护的应用程序。

相关推荐
全栈王校长2 小时前
Vue.js 3 项目构建:从 Webpack 到 Vite 的转变之路
vue.js
重铸码农荣光2 小时前
CSS 也能“私有化”?揭秘模块化 CSS 的防坑指南(附 Vue & React 实战)
前端·css·vue.js
绝世唐门三哥4 小时前
工具函数-精准判断美东交易时间
前端·javascript·vue.js
我的div丢了肿么办5 小时前
vue使用h函数封装dialog组件,以命令的形式使用dialog组件
前端·javascript·vue.js
Irene19916 小时前
Vue3 <script setup> 中不需要使用 defineComponent
vue.js·definecomponent
xkxnq6 小时前
第二阶段:Vue 组件化开发(第 21天)
前端·javascript·vue.js
内存不泄露7 小时前
基于 Spring Boot 的医院预约挂号系统(全端协同)设计与实现
java·vue.js·spring boot·python·flask
0_18 小时前
封装了一个vue版本 Pag组件
前端·javascript·vue.js
Code知行合壹8 小时前
Vue.js进阶
前端·javascript·vue.js