JSX | TSX 教程

目录

  • 前言
  • 一、JSX 语法
    • 1、JSX 代码注释
    • 2、JSX 赋予数组的特性
    • 3、JSX 属性的特性
  • 二、TSX
    • 1、TypeScript 的 3 种 JSX 模式
    • 2、只能使用 as 操作符做类型断言
  • 三、React 中使用 JSX
    • 1、React 中 JSX 的渲染
    • 2、React 中 JSX 可以防止 XSS 注入攻击
  • 四、Vue 中使用 JSX
    • 0、Vue 中 SFC 与 JSX 模式的对比
    • 1、文本插值
    • 2、条件渲染
      • (1)、JSX 中使用 v-show 指令
      • (2)、使用 if/else
      • (3)、使用逻辑运算符
      • (4)、使用三目运算符
    • 3、列表渲染
    • 4、标签的动态属性绑定
    • 5、class 类名绑定
    • 6、style 样式绑定
    • 7、事件绑定
      • (1)、事件修饰符
    • 8、v-model 双向绑定
      • (1)、使用 v-model 指令绑定 modelValue
      • (2)、绑定自定义名称
    • 9、slot 插槽
      • (1)、Scoped Slots 作用域插槽
    • 10、在 JSX 中使用 h() 函数创建 Vnodes


前言

如果你需要将大量 HTML 代码移植到 JSX 语法,可以使用 一款在线的免费的代码转换器工具。

JSX 最早是由 facebook 起草的一个规范。

JSX 是 JavaScript 的语法扩展,可让您在 JavaScript 文件中编写类似 HTML 的标记。JSX 是一种嵌入式的类似 XML 的语法。

JSX 并没有扩展 JS 的语法,他只是缩略了 JS 的写法,其本质就是 JS 的语法糖。

一、JSX 语法

JSX 语法:

  • JSX 与 HTML 对比:
    • JSX 中可以正常的使用 HTML 元素嵌套构建页面。
    • JSX 必须返回单个根元素——顶层只能有一个根元素包裹,这个根元素可以是
      等等。
    • 添加自定义属性遵循 HTML5 的规则,需要使用 data- 前缀开头作为属性名并赋值。
    • JSX 比 HTML 更严格一些,JSX 要求标签被显式关闭。例如: 必须写成的自关闭标签
  • JSX 文件的类型:
    • 使用 JSX 语法的文件必须以 .jsx 作为文件的后缀名。
    • 如果用到了 TypeScript 则必须用 .tsx 作为文件的后缀名。
  • JSX 的代码注释:
    • JSX 的代码注释需要写在花括号 {} 中。
  • JSX 与 JavaScript 表达式:
    • 在 JSX 中可以使用 JavaScript 表达式,表达式需要写在花括号 {} 中。
    • 在 JSX 中可以使用 三元运算(? :) 表达式来实现按条件加载的逻辑。
    • JSX 允许在模板中插入数组,数组会自动展开所有成员。
    • JSX 特定属性:(二选一)
      • 可以指定为字符串字面量——属性值加上引号;
      • 也可以在属性值中使用大括号插入一个 JavaScript 表达式。

1、JSX 代码注释

JSX 的注释代码需要写在花括号 {} 中:

const content = (
  {/*注释...*/}
  <h1>hello world</h1>
);

2、JSX 赋予数组的特性

JSX 允许在模板中插入数组,数组会自动展开所有成员

var arr = [
  <h1>123</h1>,
  <h2>321</h2>,
];
const content = (
  <div>{arr}</div>
);

3、JSX 属性的特性

你可以通过使用引号,来将属性值指定为字符串字面量:

<script type="text/babel">
    const element = <div tabIndex="0"></div>;
</script>

也可以使用大括号,来在属性值中插入一个 JavaScript 表达式:

<script type="text/babel">
    const element = <img src={user.avatarUrl}></img>;
</script>

【注意】在对于同一属性不能同时使用这两种符号。

二、TSX

TS 的 JSX

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

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

1、TypeScript 的 3 种 JSX 模式

TypeScript具有三种JSX模式:preserve、react 和 react-native。

你可以通过在命令行里使用--jsx标记或tsconfig.json里的选项来指定模式。

模式 输入 输出 输出文件扩展名
preserve
.jsx
react
React.createElement(“div”) .js
react-native
.js

这些模式只在代码生成阶段起作用,类型检查并不受影响。

  • 在preserve模式下生成代码中会保留JSX以供后续的转换操作使用(比如:Babel)。 另外,输出文件会带有.jsx扩展名。
  • react模式会生成React.createElement,在使用前不需要再进行转换操作了,输出文件的扩展名为.js。
  • react-native相当于preserve,它也保留了所有的JSX,但是输出文件的扩展名是.js。

2、只能使用 as 操作符做类型断言

在 TSX 中只能使用 as 操作符来实现 类型断言,不能使用尖括号(<>),这两者是等价的。

const foo = bar as foo;// ✅正确
const foo = <foo>bar;// ❌错误

三、React 中使用 JSX

React 的 JSX 简介

JSX 和 React 是相互独立的,React 开发不一定使用 JSX ,但我们建议使用它。在 React 中使用 JSX,是一种非常棒的体验。

在 React 中使用 JSX 的注意事项:

  • React DOM 使用 className 属性替换 HTML 的 class 属性,使用 htmlFor 属性替换 HTML 的 for 属性。

1、React 中 JSX 的渲染

在 React 中 Babel 插件会把 JSX 转译成一个名为 React.createElement() 函数调用。

以下两种示例代码完全等效:

<script type="text/babel">
    const element = (
        <h1 className="greeting">Hello, world!</h1>
    );
</script>

// 等价于
<script>
    const element = React.createElement(
        'h1',
        {className: 'greeting'},
        'Hello, world!'
    );
</script>

React.createElement() 会预先执行一些检查,以帮助你编写无错代码,但实际上它创建了一个这样的对象:

// 注意:这是简化过的结构
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};

2、React 中 JSX 可以防止 XSS 注入攻击

你可以安全地在 JSX 当中插入用户输入内容:

const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element = <h1>{title}</h1>;

React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本)攻击。

四、Vue 中使用 JSX

渲染函数 & JSX
为什么我推荐使用JSX开发Vue3

0、Vue 中 SFC 与 JSX 模式的对比

SFC 模式:

<template>
    <span>{{text}}span>
template>
<script setup lang="tsx">
import { ref } from 'vue'

const props = {}
const emits = []
const directives = {}

const text = ref('示例')
script>
<style>
.sapn{ color: red }
style>

JSX 模式:

import { defineComponent, ref } from 'vue'

export default defineComponent({
  name: 'SelfComponent',
  props: {},
  emits: [],
  directives: {},
  setup() {
    const text = ref('示例')
    return { text }
  },
  render() {
    return (
      <div>{this.text}</div>
    )
  }
})

其实,jsx 的 render 函数是可以省略的,因为 setup 默认会返回一个 render 方法来渲染 jsx,所以你也可以这样写:

import { defineComponent, ref } from 'vue'

export default defineComponent({
  name: 'SelfComponent',
  props: {},
  emits: [],
  directives: {},
  setup(props, ctx) {
	const text = ref('示例')
    return () => (
      <span>{text.value}</span>
    )
  }
})

【注意】若在 setup 直接渲染 html 标签或组件,在使用 ref 定义的变量时需要带上 .value 关键字。

1、文本插值

Vue 里面文本插值默认是用双大括号:

<h1>{{ msg }}h1>

在JSX中变成了单大括号:

const name = '标题'
const element = <h1>Hello, { name }</h1>

与 template 模板语法中的文本插值一样,大括号内支持任何有效的 JavaScript 表达式。

2、条件渲染

在 JSX 中使用“if/else”、“逻辑运算符”、“三目运算符”来取代 v-if 指令来做条件渲染。因为 jsx 本身就是一个条件表达式,不需要 v-if 了。但是 JSX 支持 v-show 指令的使用。

(1)、JSX 中使用 v-show 指令

SFC写法:

<div v-show="isShow">div>

JSX写法:

<div v-show={isShow}>div>

(2)、使用 if/else

const element = (name) => {
  if (name) {
    return <h1>Hello, { name }</h1>
  } else {
    return <h1>Hello, Stranger</h1>
  }
}

(3)、使用逻辑运算符

js 的逻辑运算符包括:

  • ||(或)
  • &&(与)
  • !(非)
  • ??(空值合并运算符)
const element = icon && <span class="icon"></span>;

(4)、使用三目运算符

三目运算符:条件 ? A : B(满足条件值取A,否则值取B)。

const element = icon ? <span class="icon"></span> : null;

3、列表渲染

在 JSX 中使用 JS 数组的 map 方法取代 v-for 指令做列表渲染。

const data = [{
  id: 1,
  title: 'qqqq'
}, {
  id: 2,
  title: 'wwww'
}]

const element = data.map(item => {
  return <div>{ item.title }</div>
})

4、标签的动态属性绑定

标签的动态属性绑定用“大括号包裹”即可,无需用 v-bind 指令。

const href = 'https://www.baidu.com/'
const element = <a href={href}>baidu</a>

5、class 类名绑定

直接使用 JS 模板字符串即可。

const element = <div className={`self-accordion-item-title ${ disabled ? 'disabled' : '' }`}></div>

也可以使用数组:

const element = <div class={
    [
      'self-accordion-item-title',
      disabled && 'disabled'
    ]
  }
>Item</div>

6、style 样式绑定

样式绑定需要用双大括号

const width = '100px'
const element = <button style={{ width, fontSize: '16px' }}></button>

7、事件绑定

绑定事件也是用大括号

事件名前要加 on 前缀,比如:click 事件要写成 onClick。

const confirm = () => {
  // 确认提交
}
<button onClick={confirm}>确定</button>

如果要带参数,需要使用箭头函数进行包裹:

const confirm = (name) => {
  // 确认提交
}
<button onClick={() => confirm('123')}>确定</button>

(1)、事件修饰符

jsx 中给事件增加修饰符需要借助 withModifiers 方法。

import { withModifiers, defineComponent, ref } from 'vue'

const App = defineComponent({
  setup() {
    const count = ref(0);

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

    return () => (
      <div onClick={ withModifiers(inc, ['stop']) }>{ count.value }</div>
    );
  },
})

8、v-model 双向绑定

需要使用大括号

(1)、使用 v-model 指令绑定 modelValue

SFC写法:

<SelfComponent v-model="menuShow" />

JSX写法:

<SelfComponent v-model={ menuShow.value } />

(2)、绑定自定义名称

比如绑定 visible,JSX 中不能直接用 v-model:visible 的语法,需要传入一个数组 [menuShow.value, ‘visible’],数组的第二个参数就是要绑定的自定义名称。

SFC写法:

<SelfComponent v-model:visible="menuShow" />

JSX写法:

<SelfComponent v-model={ [menuShow.value, 'visible'] } />

9、slot 插槽

jsx 中没有 标签,定义插槽需要使用双大括号。

如果是具名插槽,则将 default 改成具名插槽的名称,比如:mySlot,则使用 ctx.slots.mySlot?.()。

插槽从 setup 的第二个参数 ctx 中获取,不需要在其前面加 $ 符号。

import { defineComponent } from 'vue'

export default defineComponent({
  setup(props, { slots }) { // 逻辑
    return () => {
      return <button>{ slots.default?.() }</button>
    }
  },
})

还可以使用renderSlot方法:

import { renderSlot } from 'vue'

<button>
  { renderSlot(slots, 'default') }
</button>

(1)、Scoped Slots 作用域插槽

使用作用域插槽可以实现插槽传参,以下是具体的示例。

JSX和SFC中插槽使用的写法对比。

JSX写法:

<self-tree data={data}>
  {{
    mySlot: (item) => (item.open ? <IconOpen /> : <IconClose />),
  }}
self-tree>

还可以通过 v-slots 的方式使用:

 (item.open ? <IconOpen /> : <IconClose />)
}}>
self-tree>

SFC写法:

<self-tree :data="data">
  <template #mySlot="item">
    <IconOpen v-if="item.open" />
    <IconClose v-else />
  template>
self-tree>

其中的item是插槽的参数,通过:ctx.slots.mySlot(item) 的方式给插槽传入参数。或者使用 renderSlot 方法,第三个参数就是要传给插槽的参数:

import { renderSlot, useSlots } from 'vue'

<button>
  { renderSlot(useSlots(), 'mySlot', item) }
</button>

10、在 JSX 中使用 h() 函数创建 Vnodes

在 JSX 中 h() 函数可以大展身手。

vue 用 h() 函数创建 Vnodes




【参考推荐文章】

TS 的 JSX

React 的 JSX 简介

Vue 渲染函数 & JSX
为什么我推荐使用JSX开发Vue3
Vue3中使用JSX简明语法

你可能感兴趣的:(#,React.js,#,Vue.js,JavaScript,react,vue,JSX,TSX)