JSX是一种嵌入式的类似XML的语法。 它可以被转换成合法的JavaScript,尽管转换的语义是依据不同的实现而定的。 JSX因React框架而流行,但也存在其它的实现。 TypeScript支持内嵌,类型检查以及将JSX直接编译为JavaScript。

本文涉及知识


  1. SFC
  2. 虚拟dom
  3. render 相关函数

Demo 已上传,请点击https://github.com/RainManGO/vue3-tsx-demo。

思考


问:SFC和JSX 优劣势,Vue模板语法快捷方便为什么还要学JSX?

答: 我的理解SFC更侧重Html语法,就像画一幅画,使用标签画好结构,再将数据使用js进行填充,这样js的灵活性就难以发挥。JSX侧重于JS语法,没有条条框框的架子,可以在白色画布灵活自由的画画。

有点类似于Vue3的 composation API和opitions API的关系。

SFC JSX
简单、迅速 、高效 灵活、对于复杂组件组合高效

Vue模板语法是怎么渲染的呢?


下面是Vue的模板:


<div><div><span>static</span><p>{{msg}}</p></div><span>static</span><span>static</span>
</div>

查看模板编译工具:传送门
Vue会将模板处理成下面的代码:


import { createVNode as _createVNode, toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock } from "vue"export function render(_ctx, _cache, $props, $setup, $data, $options) {return (_openBlock(), _createBlock("div", null, [_createVNode("div", null, [_createVNode("span", null, "static"),_createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)]),_createVNode("span", null, "static"),_createVNode("span", null, "static")]))
}// Check the console for the AST

从上面的例子可以看出模板语法会变成虚拟DOM,然后通过render函数渲染。

如何在项目中使用JSX

项目是Vue3.0 + TS

想要使用JSX必须做两件事:

  1. 给文件一个.tsx扩展名
  2. 启用jsx选项

TypeScript具有三种JSX模式:preserve,react和react-native。 这些模式只在代码生成阶段起作用 - 类型检查并不受影响。 在preserve模式下生成代码中会保留JSX以供后续的转换操作使用(比如:Babel)。 另外,输出文件会带有.jsx扩展名。 react模式会生成React.createElement,在使用前不需要再进行转换操作了,输出文件的扩展名为.js。 react-native相当于preserve,它也保留了所有的JSX,但是输出文件的扩展名是.js。

tsconfig 默认 “jsx”: “preserve”,

{"compilerOptions": {"target": "esnext","module": "esnext","strict": true,"jsx": "preserve","importHelpers": true,"moduleResolution": "node","experimentalDecorators": true,"skipLibCheck": true,"esModuleInterop": true,"allowSyntheticDefaultImports": true,"sourceMap": true,"baseUrl": ".","types": ["webpack-env","jest"],"paths": {"@/*": ["src/*"]},"lib": ["esnext","dom","dom.iterable","scripthost"]},"include": ["src/**/*.ts","src/**/*.tsx","src/**/*.vue","tests/**/*.ts","tests/**/*.tsx"],"exclude": ["node_modules"]
}

JSX也是通过babel 进行编译成js,最后变成虚拟DOM进行渲染。

路由添加一个TSX组件

1、创建一个组件:

import { defineComponent } from 'vue'
export default defineComponent({render () {return <div>my custom router</div>}
})

2、在Router里引用添加

/** @Description:* @Author: ZY* @Date: 2020-12-11 15:27:32* @LastEditors: ZY* @LastEditTime: 2020-12-12 14:38:31*/
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import Home from '../views/Home.vue'
import Test from '../views/Test'
import MyRouter from '../views/MyRouter'const routes: Array<RouteRecordRaw> = [{path: '/',name: 'Home',component: Home},{path: '/about',name: 'About',// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')},{path: '/test',name: 'Test',component: Test},{path: '/myRouter',name: 'MyRouter',component: MyRouter}
]const router = createRouter({history: createWebHashHistory(),routes
})export default router

运行下应该可以看到效果了。

渲染函数

Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。

通过例子实现一个通过属性实现动态生成标签的组件:

1、通常我们可以这么写

<template><h1 v-if="level === 1"><slot></slot></h1><h2 v-else-if="level === 2"><slot></slot></h2><h3 v-else-if="level === 3"><slot></slot></h3><h4 v-else-if="level === 4"><slot></slot></h4><h5 v-else-if="level === 5"><slot></slot></h5><h6 v-else-if="level === 6"><slot></slot></h6>
</template><script lang="ts">
import { defineComponent } from 'vue'export default defineComponent({props: {level: {type: Number,required: true}},setup () {return {}}
})
</script><style scoped></style>

2、我们也可以通过渲染函数和h函数这么写

<script lang="ts">
import { defineComponent, h } from 'vue'export default defineComponent({props: {level: {type: Number,required: true}},setup () {return {}},render () {return h('h' + this.level, // 标签名字{}, // props/attributesthis.$slots // array of children)
})
</script>

3、当然你也可以换个函数写法


<script lang="ts">
import { defineComponent, openBlock as _openBlock, createBlock as _createBlock } from 'vue'export default defineComponent({props: {level: {type: Number,required: true}},setup () {return {}},render () {return (_openBlock(), _createBlock('h' + this.level, null, this.$slots))}
})
</script>

JSX 语法

看了Vue中的各种render函数写法,你是否感觉写哪种都比较不舒服,这时候JSX可以出场了。

jsx 语法和vue模板语法思想大致相同,{{}}变成了{},class支持面向对象style,等…

属性

支持data,setup和基本写法

import { defineComponent, ref } from 'vue'
import CustomCompent from '@/components/CustomCompent'
export default defineComponent({setup () {const msg = ref('msg')return { msg }},data () {return {msg3: 'msg3'}},render () {const msg1 = 'msg1'return <div>{1 + 1}{true?"this is true":"false"}my custom router{msg1}-{this.msg}-{this.msg3}</div>}
})

表达式和函数

同理method 和 setup 倒出去的函数也是支持的。

import { defineComponent, ref } from 'vue'
import CustomCompent from '@/components/CustomCompent'
export default defineComponent({render () {function getElement (str: string) {return <h1>{str}</h1>}return <div>{1 + 1}{true?"this is true":"false"}{getElement('ceshi')}</div>}
})

样式

JSX 你可以选择css 或者 面向对象的style,同理可以使用setup 挂在this上。

import { defineComponent, ref } from 'vue'
import CustomCompent from '@/components/CustomCompent'
export default defineComponent({setup () {const myStyle = {fontSize: 100,color: '#FF0000'}return { myStyle }},render () {const myStyle1 = {fontSize: 100,color: 'red'}return <div style={myStyle1}>my custom router{msg1}-{this.msg}-{this.msg3}</div>}
})

组件

关于组件,可以和.vue 组件共存,import 导入使用即可。

详情看demo代码

灵活组合

我们可以定义标签,动态组合插入render函数,组合渲染。

import { defineComponent, ref } from 'vue'
import CustomCompent from '@/components/CustomCompent'
export default defineComponent({components: {'custom-compent': CustomCompent},render () {const el = <h1>el</h1>const elArray = [<h1>h1</h1>,<h3>h3</h3>]const dymicArray = ['demo1', 'demo2']const dymicElAray = dymicArray.map((str: string) => {return <h1>{str}</h1>})return <div style={myStyle1}>{el}{elArray}{dymicElAray}<custom-compent></custom-compent></div>}
})

TSX 在Vue项目的使用相关推荐

  1. 9102年webpack4搭建vue项目

    前言 首先祝大家元宵节快乐,最近已经好久没有写过文章了,刚好趁着这几天刚刚上班,领导还没有来,偷偷的写一篇关于webpack搭建vue的博客.因为公司使用vue比较多,构建vue项目使用vue-cli ...

  2. jset编写测试vue代码_详解使用jest对vue项目进行单元测试

    最近领导对前端提出了新的要求,要进行单元测试.之前使用vue做了一个快报名小程序的pc端页面,既然要做单元测试,就准备用这个项目了,之前有些react的经验,vue还是第一遭 vue-cli3.0单元 ...

  3. typescript vuex_将已有的Vue项目升级支持TypeScript

    TypeScript是js的超集,是由微软开发的.越来越多的项目使用TypeScript.像现在很火的Visual Studio Code就是使用TypeScript开发. 本人开发过一段Angula ...

  4. vue项目引入typescript(vue与ts混用)

    说明 为什么要在vue项目中使用ts? 新公司给了一个关于vue项目的需求,又由于ts是JavaScript的超集,强类型数据,组件化友好.故我选择在vue项目中引入ts. 下载typescript和 ...

  5. 从零开始使用webpack 搭建vue项目

    从零开始使用webpack 搭建vue项目 1 创建项目 npm init 生成 package.json 创建 index.html webpack.confug.js project-name|- ...

  6. 手把手教你从0开始搭建一个vue项目(完结)

    前言 上一节webpack实战之(手把手教你从0开始搭建一个vue项目)最后我们完成了css样式的配置: webpack.config.js: const path = require("p ...

  7. 在vue项目中使用prismjs(网页代码高亮插件)

    在vue项目中使用prismjs 什么是prismjs prismjs是一款代码高亮美化插件,在一些技术博客类的网站中需要展示代码时,可以使用它类似与markdown的代码块, 官网链接:https: ...

  8. Vue项目中ESLint配置(VScode)

    Vue项目中ESLint配置(VScode) 1.VScode的配置格式化代码 1.1下载eslint插件 1.2配置setting.json 打开左上角文件-首选项-设置,在设置中搜索eslint, ...

  9. 使用veu-cli3/4搭建vue项目详细配置

    文章目录 使用vue-cli4 搭建vue项目 一.安装vue-cli4 二.创建一个vue项目 三.预设选项 四.启动项目 五.可视化UI 使用vue-cli4 搭建vue项目 一.安装vue-cl ...

  10. canvas java 上传截图_在Vue项目中使用html2canvas生成页面截图并上传

    使用方法 项目中引入 npm install html2canvas html代码 //html代码 js代码 // 引入html2canvas import html2canvas from 'ht ...

最新文章

  1. 去除php_eol,php去除换行符的方法小结(PHP_EOL变量的使用)
  2. python定义字符串数组_从字符串数组(或元组)在Python中创建动态sql“ in list”子句的“最佳”方法是什么?...
  3. 新手坐高铁怎么找车厢_一女子坐高铁回桂平坐过站,到了平南南站,怎么办?...
  4. pandas demo 示例
  5. Android NDK开发之旅1 NDK介绍
  6. 59 MM配置-后勤发票校验-维护税代码缺省值
  7. fastjson.toJSONString字段排序
  8. 请问spfa+stack 和spfa+queue 是什么原理
  9. 安装VMware时,出现 安装程序无法继续 Microsoft Runtime DLL 安装程序未能完成安装 您无权输入许可证密钥,请使用系统管理员账户重试 VMware15.5.x 安装问题处理
  10. 苹果4s刷linux,苹果4s降级教程【图解】
  11. 郝兵c语言_郝斌C语言笔记——C语言概述
  12. 一、Windows许可证即将过期怎么办
  13. 【IOS】《捕鱼达人》的简单实现(一)
  14. IDEA重置maven配置的问题解决
  15. 成为会带团队的技术人 架构设计:治理好系统复杂度才最务实
  16. 如何唤起支付宝支付调用接口
  17. Arduino TFT_eSPI库来驱动SPI接口的LCD显示文字详解
  18. git format-patch的使用【转】
  19. How To install a NAV Application Server (NAS)?
  20. 全国民众信息泄露,包括总统、政要和明星

热门文章

  1. python读文件-read_csv()-常用参数
  2. @那些想要转行AI的人:送你一份人工智能入门指南
  3. 【DX12】DirectX Math库 Vector和Matrix类型 XMVECTOR、XMMATRIX
  4. html 中数字换行,CSS实现连续数字和英文的自动换行的方法
  5. JVM垃圾回收的二次标记
  6. 看到强烈的太阳光你会不由自主的打喷嚏吗?
  7. 工作绩效数据、工作绩效信息、工作绩效报告
  8. 哒螨灵使用注意事项_常用杀虫剂-哒螨灵使用方法
  9. 调试The Annotated Transformer
  10. MySQL数据库的主从同步和读写分离