前言

在日常开发中vue的模版语法在大多数情况都能够满足我们的需求,但是在一些复杂的业务场景中使用模版语法就有些麻烦了。这个时候灵活的JSX/TSX渲染函数就能派上用场了,大多数同学的做法都是将*.vue文件改为*.tsx或者*.jsx文件。其实我们可以直接在*.vue文件中直接使用JSX/TSX渲染函数。

什么场景需要使用JSX/TSX渲染函数

假设我们现在有这样的业务场景,在我们的页面中有个list数组。我们需要去遍历这个数组,根据每一项的item去渲染不同的组件。如果tem的数据满足条件A,那么就渲染组件A。如果item的数据满足条件B,那么就渲染组件B。如果item的数据满足条件C,那么就渲染组件C。

如果我们使用vue模版语法去实现这个需求,我们的Page.vue文件的代码就需要是这样的:

<template>
<template v-for="item in list">
<ComponentA v-if="isComponentA(item)" />
<ComponentB v-else-if="isComponentB(item)" />
<ComponentC v-else-if="isComponentC(item)" />
</template>
</template> <script setup lang="ts">
import ComponentA from "./component-a.vue";
import ComponentB from "./component-b.vue";
import ComponentC from "./component-c.vue"; const list: Array<number> = [1, 5, 3, 2, 1]; const isComponentA = (item): boolean => {
return item % 3 === 0;
}; const isComponentB = (item): boolean => {
return item % 3 === 1;
}; const isComponentC = (item): boolean => {
return item % 3 === 2;
};
</script>

这样虽然可以实现功能,但是明显不够优雅,领导code review时看了直呼摇头。

在*.jsx/tsx文件中使用JSX/TSX渲染函数

此时机智的小伙伴会说,我们可以使用vuesetup方法使用JSX/TSX渲染函数实现。确实可以,我们来看看具体实现的代码:

import { defineComponent } from "vue";
import ComponentA from "./component-a.vue";
import ComponentB from "./component-b.vue";
import ComponentC from "./component-c.vue"; export default defineComponent({
setup() {
const list = [1, 5, 3, 2, 1, 0]; function renderDataList(data: Array<number>) {
return data?.map((val) => {
if (val % 3 === 0) {
return <ComponentA />;
} else if (val % 3 === 1) {
return <ComponentB />;
} else {
return <ComponentC />;
}
});
} return () => {
return <div>{renderDataList(list)}</div>;
};
},
});

首先我们需要将原来的Page.vue文件改为Page.tsx文件,然后我们需要将原来写在template中的代码摞到setup中。这种写法有如下几个痛点:

由于没有使用vue的模版语法,所以vue内置的v-model等指令和项目中自己封装的指令等都不能使用了,只能使用js去自己实现。

按照常规的思维,setup直接返回一个值就行了,但是如果你这样写就会收到这样的报错:

[Vue warn]: setup() should not return VNodes directly - return a render function instead.

原因是setup() 函数在每个组件中只会被调用一次,而返回的渲染函数将会被调用多次。这样就导致我们的代码只能在外面包裹一层匿名函数:

return () => {
return <div>{renderDataList(list)}</div>;
};

在*.vue文件中使用JSX/TSX渲染函数

那么有没有方法可以让我们在使用JSX/TSX渲染函数的同时,也可以在vue文件中使用模版语法呢?答案是:当然可以!

首先我们需要导入@vitejs/plugin-vue-jsx

// vite.config.js
import vue from '@vitejs/plugin-vue' export default {
plugins: [vue()],
}

然后我们需要将vue文件的script标签的lang设置为tsx或者jsx。具体的Page.vue代码如下:

<template>
<RenderDataList :data="list" />
</template> <script setup lang="tsx">
import ComponentA from "./component-a.vue";
import ComponentB from "./component-b.vue";
import ComponentC from "./component-c.vue"; const list = [1, 5, 3, 2, 1]; const RenderDataList = (props: { data: Array<number> }) => {
return props.data?.map((val) => {
if (val % 3 === 0) {
return <ComponentA />;
} else if (val % 3 === 1) {
return <ComponentB />;
} else {
return <ComponentC />;
}
});
};
</script>

在上面这个例子中我们定义了一个RenderDataList,然后在template中可以直接将RenderDataList当作一个组件使用。vscode也会给出智能提示。

react中,这种场景我们可以将RenderDataList当作一个函数去使用,然后在模版中直接调用这个函数就行了。但是在vue中,RenderDataList只能当做一个组件使用,不能当做函数调用。

还有一点需要避坑的是,假如我们的props中定义了一个驼峰命名法的变量,例如:pageNum。在template中传入pageNum的时候必须写成:pageNum="xxx",不能写成:page-num="xxx"

总结

这篇文件介绍了如何在*.vue文件中直接使用JSX/TSX渲染函数,只需要导入@vitejs/plugin-vue-jsx,然后将script标签的lang设置为tsx或者jsx。就可以在script中直接定义组件,然后在template中直接使用组件就可以了。这样我们既可以使用JSX/TSX渲染函数的灵活性,也可以使用vue模版语法中内置的指令等功能。

如果我的文章对你有点帮助,欢迎关注公众号:【欧阳码农】,文章在公众号首发。你的支持就是我创作的最大动力,感谢感谢!

直接在*.vue文件(SFC)中使用JSX/TSX渲染函数,真香!的更多相关文章

  1. 如何在 vue3 中使用 jsx/tsx?

    我们都知道,通常情况下我们使用 vue 大多都是用的 SFC(Signle File Component)单文件组件模式,即一个组件就是一个文件,但其实 Vue 也是支持使用 JSX 来编写组件的.这 ...

  2. Vue躬行记(7)——渲染函数和JSX

    除了可通过模板创建HTML之外,Vue还提供了渲染函数和JSX,前者的编码自由度很高,后者对于开发过React的人来说会很熟悉.注意,Vue的模板最终都会被编译成渲染函数. 一.渲染函数 虽然在大部分 ...

  3. VScode 中 vue文件template中不能使用tab补齐标签

    选择 文件-->首选项-->设置-->搜索  emmet,选择 编辑 setting.json, 添加下列代码: "emmet.includeLanguages" ...

  4. sublime text3支持Vue文件高亮显示

    sublime text 默认打开.vue文件全部都是白色的,不是特别方便.安装插件可以做到代码高亮显示 1.插件vue-syntax-highlight 下载地址:github https://gi ...

  5. VSCode Vue文件格式化

    参考文档:https://vuejs.github.io/vetur/formatting.html 自从将VSCode更新之后,vue文件的html格式化就失效了,而且vue文件中的js ,css格 ...

  6. 【C++】C++中的lambda表达式和函数对象

    目录结构: contents structure [-] lambda表达式 lambda c++14新特性 lambda捕捉表达式 泛型lambda表达式 函数对象 函数适配器 绑定器(binder ...

  7. Vue基础-渲染函数-插槽

    Vue 测试版本:Vue.js v2.5.13 先看个插槽的例子: <div id="app"> <child > <span slot-scope= ...

  8. 在Vue中使用JSX,很easy的

    摘要:JSX 是一种 Javascript 的语法扩展,JSX = Javascript + XML,即在 Javascript 里面写 XML,因为 JSX 的这个特性,所以他即具备了 Javasc ...

  9. vue中使用JSX报错,如何解决

    Support for the experimental syntax 'jsx' isn't currently enabled (32:12): 30 | }, 31 | render() { & ...

  10. 在使用 vscode 时 eslint 检测 .vue 文件中的less 部分内容

    问题: 在使用 vscode 以及 eslint 来检测 基于 webpack 的 vue-cli 的项目中,eslint 无法检测到 .vue 文件中的less 部分内容. 解答: 1.通过 下载 ...

随机推荐

  1. 爬虫系列——Scrapy

    文章目录 一 介绍 二 安装 三 命令行工具 四 项目结构以及爬虫应用简介 五 Spiders 六 Selectors 七 Items 八 Item Pipeline 九 Dowloader Midd ...

  2. Termius for macOS or Windows Download ssh

    mac电脑   苹果系统 window 系统 链接  服务器,访问 ecs ,ssh链接 工具 下载地址:http://pgyd.online/?website/53.html Termius for ...

  3. PostgreSQL主备库搭建

    pg主备库的搭建,首先需在2个节点安装pg软件,然后依次在2个节点配置主备. 本文采用os为CentOS7.6,pg版本使用14.2,以下为详细部署步骤. 本文两个节点的ip地址如下: [root@n ...

  4. 16.2 ARP 主机探测技术

    ARP (Address Resolution Protocol,地址解析协议),是一种用于将 IP 地址转换为物理地址(MAC地址)的协议.它在 TCP/IP 协议栈中处于链路层,为了在局域网中能够 ...

  5. AGC 补题笔记

    [AGC001] A.BBQ Easy 由于最大数肯定要和一个比自己小的数搭配保留该数,不如选择保留次大数,如此递归即解.因此将序列排序后输出序号为奇数的数即可. B.Mysterious Light ...

  6. go语言写http踩得坑

    1.在运行http时,报错:panic: listen tcp: address xxxx: missing port in address, 初始 代码如下 func HelloWordHander ...

  7. 数据结构与算法 | 哈希表(Hash Table)

    哈希表(Hash Table) 在二分搜索中提到了在有序集合中查询某个特定元素的时候,通过折半的方式进行搜索是一种很高效的算法.那能否根据特征直接定位元素,而非折半去查找?哈希表(Hash Table ...

  8. 在NestJS应用程序中使用 Unleash 实现功能切换的指南

    前言 近年来,软件开发行业迅速发展,功能开关(Feature Toggle)成为了一种常见的开发实践.通过功能开关,可以在运行时动态地启用或禁用应用程序的特定功能,以提供更灵活的软件交付和配置管理.对 ...

  9. CSP2023游击

    Day-1 上车了,玩了一路. 到酒店里,玩了一晚上. Day 1 爆O! Day 2 走了,玩了一路. AF0了, 哎不是,谁给我反对了 考完了,心情不是很好 分数就不说出来了吧,太低了怕你们笑话我 ...

  10. re1-100

    虽然关键的判断函数和"成功"的提示也在这里,但是具体对输入flag的操作却在后面 看到对数组bufParentRead[1]开始赋值"53fc275d81",b ...