Vue 项目中为何选择 TSX 而非传统 .vue 文件

news/2024/11/8 7:37:46 标签: vue.js, 前端, javascript

近年来,Vue 项目中使用 TSX(TypeScript JSX)的写法逐渐增多,尤其在 TypeScript 项目中。

1. TSX 与 Vue 的结合背景

1、Vue 3 和 TypeScript

Vue 3 从设计之初便更好地支持 TypeScript。Vue 3 使用了 TypeScript 重写核心,增强了类型推断和类型安全的支持,使得 TypeScript 更适合与 Vue 3 配合使用。

2、组合式 API

Vue 3 推出组合式 API,使代码逻辑更加模块化,也更接近于函数式编程的风格,这让代码结构更贴近 TSX 的写法,方便在 TypeScript 和 JSX 中组织逻辑。

2. 简单的示例 🌰

下面结合几个具体的 🌰 详细说明在 Vue 中使用 TSX 和传统 .vue 文件之间的差异。

2.1 基础组件

假设需要创建一个简单的用户卡片组件,用于显示用户的姓名和年龄。

1、使用 .vue 文件编写

.vue 文件的模板语法非常适合这种简单的展示性组件,因为结构清晰,模板代码直观。

<!-- UserCard.vue -->
<template>
  <div class="user-card">
    <p>Name: {{ name }}</p>
    <p>Age: {{ age }}</p>
  </div>
</template>

<script setup lang="ts">
import { defineProps } from 'vue';
const props = defineProps<{
  name: string;
  age: number;
}>();
</script>

2、使用 tsx 编写

在 tsx 中写同样的组件,代码结构会略有不同,因为模板和逻辑是统一在一起的:

javascript">// UserCard.tsx
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'UserCard',
  props: {
    name: String,
    age: Number,
  },
  setup(props) {
    return () => (
      <div class="user-card">
        <p>Name: {props.name}</p>
        <p>Age: {props.age}</p>
      </div>
    );
  },
});
2.2 复杂组件:带插槽和事件处理

插槽和事件处理是 Vue 中常见的功能,在 .vue 文件和 .tsx 文件中实现会略有不同。

1、使用 .vue 文件编写

<!-- Modal.vue -->
<template>
  <div v-if="visible" class="modal">
    <div class="modal-content">
      <slot></slot>
      <button @click="close">Close</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { defineProps, defineEmits } from 'vue';
const props = defineProps<{ visible: boolean }>();
const emit = defineEmits<{ (e: 'close'): void }>();
function close() {
  emit('close');
}
</script>

<style scoped>
.modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}
.modal-content {
  background: white;
  padding: 1rem;
  margin: auto;
}
</style>

2、使用 .tsx 编写

tsx 中通过直接传递插槽内容来实现类似的功能。

javascript">// Modal.tsx
import { defineComponent, ref } from 'vue';

export default defineComponent({
  name: 'Modal',
  props: {
    visible: Boolean,
  },
  emits: ['close'],
  setup(props, { emit, slots }) {
    const close = () => emit('close');
    return () => (
      props.visible && (
        <div class="modal" style={{
          position: 'fixed', top: 0, left: 0, right: 0, bottom: 0,
          background: 'rgba(0, 0, 0, 0.5)', display: 'flex', justifyContent: 'center', alignItems: 'center'
        }}>
          <div class="modal-content" style={{ background: 'white', padding: '1rem' }}>
            {slots.default && slots.default()}
            <button onClick={close}>Close</button>
          </div>
        </div>
      )
    );
  },
});

展示为:

2.3 使用组件

1、使用 .vue 文件

<template>
  <div>
    <UserCard name="Alice" :age="25" />
    <Modal :visible="isModalVisible" @close="toggleModal">
      <p>This is the modal content!</p>
    </Modal>
    <button @click="toggleModal">Toggle Modal</button>
  </div>
</template>

<script setup>
import UserCard from './components/UserCard.vue';
import Modal from './components/Modal.vue';
import { ref } from 'vue';

const isModalVisible = ref(false);
const toggleModal = () => (isModalVisible.value = !isModalVisible.value);
</script>

2、使用 .tsx 文件

javascript">import { defineComponent, ref } from 'vue';
import UserCard from './components/UserCard';
import Modal from './components/Modal';

export default defineComponent({
  name: 'App',
  setup() {
    const isModalVisible = ref(false);
    const toggleModal = () => (isModalVisible.value = !isModalVisible.value);

    return () => (
      <div>
        <UserCard name="Alice" age={25} />
        <Modal visible={isModalVisible.value} onClose={toggleModal}>
          <p>This is the modal content!</p>
        </Modal>
        <button onClick={toggleModal}>Toggle Modal</button>
      </div>
    );
  },
});

3、TSX 写法的优缺点

优点:

1、类型支持与代码提示:TSX 能够利用 TypeScript 的类型推断功能,减少开发中的类型错误。

2、灵活性与复用性:TSX 的写法更贴近 JavaScript 和函数式编程的范式,因此能更灵活地编写高阶组件和传递 props。许多复杂逻辑可以通过更纯粹的函数式写法实现。

3、易于集成第三方库:TSX 更符合主流 JavaScript 库(例如 React)的写法。

4、更好的代码组织:对于团队开发中的大型项目,TSX 组件更容易分离逻辑和样式管理,提升代码模块化水平。

缺点:

1、学习成本增加:TSX 更贴近 JavaScript 函数式写法,Vue 开发者需要理解 JSX 语法。

2、可读性降低:TSX 将模板、逻辑和样式混合在一个文件中,尽管提升了灵活性,但可读性不如传统的 .vue 文件结构。

4. 趋势与发展方向

对于复杂的企业级应用,TSX 的灵活性、类型安全性更符合需求。虽然 Vue 社区仍然以 .vue 文件为主流,但对于某些 TS 和 JS 深度开发者来说,TSX 正成为常见选择。Vue 团队未来可能会继续增强对 TSX 的支持,以适应不同的编程习惯。


http://www.niftyadmin.cn/n/5743523.html

相关文章

qt QErrorMessage详解

1、概述 QErrorMessage是Qt框架中用于显示错误消息的一个对话框类。它提供了一个简单的模态对话框&#xff0c;用于向用户显示错误或警告消息。QErrorMessage通常用于应用程序中&#xff0c;当需要向用户报告错误但不希望中断当前操作时。它提供了一个标准的错误消息界面&…

Neo4j 和 Python 初学者指南:如何使用可选关系匹配优化 Cypher 查询

Neo4j 和 Python 初学者指南&#xff1a;如何使用可选关系匹配优化 Cypher 查询 查询需求分析目标查询结构 编写 Cypher 查询查询解析OPTIONAL MATCH 和 COALESCE 的作用 在 Python 中使用 Neo4j 驱动执行查询使用 neo4j 驱动的 Python 示例代码代码解析示例输出 总结 在使用 N…

漏洞分析 | Spring Framework路径遍历漏洞(CVE-2024-38816)

漏洞概述 VMware Spring Framework是美国威睿&#xff08;VMware&#xff09;公司的一套开源的Java、JavaEE应用程序框架。该框架可帮助开发人员构建高质量的应用。 近期&#xff0c;网宿安全演武实验室监测到Spring Framework在特定条件下&#xff0c;存在目录遍历漏洞&…

【SQL实验】高级查询(难点.三)含附加数据库操作

完整代码在文章末尾【代码是自己的解答&#xff0c;并非标准答案&#xff0c;也有可能写错&#xff0c;文中可能会有不准确或待完善之处&#xff0c;恳请各位读者不吝批评指正&#xff0c;共同促进学习交流】 将素材中的“学生管理”数据库附加到SQL SERVER中&#xff0c;完成以…

简单了解一下 TypeScript 的泛型

在 TypeScript (TS) 中&#xff0c;泛型是一个强大且灵活的工具&#xff0c;用于编写具有更高可复用性和类型安全性的代码。泛型允许我们在声明时将类型作为参数传入&#xff0c;使函数、接口和类能在不同的数据类型下复用&#xff0c;而无需重新编写逻辑。 1. 泛型的基本语法…

论文《基于柔顺控制的智能神经导航手术机器人系统设计》文献阅读分析报告

论文报告&#xff1a;基于卷积神经网络的手术机器人控制系统设计 摘要 本研究针对机器人辅助微创手术中定向障碍和缺乏导航信息的问题&#xff0c;设计了一种智能控制导航手术机器人系统。该系统采用可靠和安全的定位技术、7自由度机械臂以及避免关节角度限制的逆运动学控制策…

Android CCodec Codec2 (二十)C2Buffer与Codec2Buffer

在阅读Codec2框架代码时&#xff0c;我们可能会发现好几个名称中都带有“buffer”的类&#xff0c;如MediaCodecBuffer、ABuffer、CCodecBuffers、Codec2Buffer以及C2Buffer。它们分别是什么&#xff1f;各自承担着什么功能&#xff1f;它们之间有何联系&#xff1f;本文将围绕…

macos中安装和设置ninja

1、在安装ninja的过程中需要先安装re2c(github地址&#xff1a;https://github.com/skvadrik/re2c): git clone https://github.com/skvadrik/re2c.git&#xff08;也可直接下载最新的release压缩包&#xff0c;并解压。下载地址&#xff1a;https://github.com/skvadrik/re2c…