赞
踩
如果你需要将大量 HTML 代码移植到 JSX 语法,可以使用 一款在线的免费的代码转换器工具。
JSX 最早是由 facebook 起草的一个规范。
JSX 是 JavaScript 的语法扩展,可让您在 JavaScript 文件中编写类似 HTML 的标记。JSX 是一种嵌入式的类似 XML 的语法。
JSX 并没有扩展 JS 的语法,他只是缩略了 JS 的写法,其本质就是 JS 的语法糖。
JSX 语法:
<div>
等等。data-
前缀开头作为属性名并赋值。.jsx
作为文件的后缀名。.tsx
作为文件的后缀名。{}
中。{}
中。? :
) 表达式来实现按条件加载的逻辑。JSX 的注释代码需要写在花括号 {}
中:
const content = (
{/*注释...*/}
<h1>hello world</h1>
);
JSX 允许在模板中插入数组,数组会自动展开所有成员
var arr = [
<h1>123</h1>,
<h2>321</h2>,
];
const content = (
<div>{arr}</div>
);
你可以通过使用引号,来将属性值指定为字符串字面量:
<script type="text/babel">
const element = <div tabIndex="0"></div>;
</script>
也可以使用大括号,来在属性值中插入一个 JavaScript 表达式:
<script type="text/babel">
const element = <img src={user.avatarUrl}></img>;
</script>
【注意】在对于同一属性不能同时使用这两种符号。
想要使用 JSX 必须做两件事:
TypeScript具有三种JSX模式:preserve、react 和 react-native。
你可以通过在命令行里使用--jsx
标记或tsconfig.json
里的选项来指定模式。
模式 | 输入 | 输出 | 输出文件扩展名 |
---|---|---|---|
preserve | <div /> | <div /> | .jsx |
react | <div /> | React.createElement(“div”) | .js |
react-native | <div /> | <div /> | .js |
这些模式只在代码生成阶段起作用,类型检查并不受影响。
在 TSX 中只能使用 as 操作符来实现 类型断言,不能使用尖括号(<>),这两者是等价的。
const foo = bar as foo;// ✅正确
const foo = <foo>bar;// ❌错误
JSX 和 React 是相互独立的,React 开发不一定使用 JSX ,但我们建议使用它。在 React 中使用 JSX,是一种非常棒的体验。
在 React 中使用 JSX 的注意事项:
className
属性替换 HTML 的 class 属性,使用 htmlFor
属性替换 HTML 的 for 属性。在 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!'
}
};
你可以安全地在 JSX 当中插入用户输入内容:
const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element = <h1>{title}</h1>;
React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本)攻击。
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
关键字。
Vue 里面文本插值默认是用双大括号:
<h1>{{ msg }}</h1>
在JSX中变成了单大括号:
const name = '标题'
const element = <h1>Hello, { name }</h1>
与 template 模板语法中的文本插值一样,大括号内支持任何有效的 JavaScript 表达式。
在 JSX 中使用“if/else”、“逻辑运算符”、“三目运算符”来取代 v-if 指令来做条件渲染。因为 jsx 本身就是一个条件表达式,不需要 v-if 了。但是 JSX 支持 v-show 指令的使用。
SFC写法:
<div v-show="isShow"></div>
JSX写法:
<div v-show={isShow}></div>
const element = (name) => {
if (name) {
return <h1>Hello, { name }</h1>
} else {
return <h1>Hello, Stranger</h1>
}
}
js 的逻辑运算符包括:
||
(或)&&
(与)!
(非)??
(空值合并运算符)const element = icon && <span class="icon"></span>;
三目运算符:条件 ? A : B
(满足条件值取A,否则值取B)。
const element = icon ? <span class="icon"></span> : null;
在 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>
})
标签的动态属性绑定用“大括号包裹”即可,无需用 v-bind 指令。
const href = 'https://www.baidu.com/'
const element = <a href={href}>baidu</a>
直接使用 JS 模板字符串即可。
const element = <div className={`self-accordion-item-title ${ disabled ? 'disabled' : '' }`}></div>
也可以使用数组:
const element = <div class={
[
'self-accordion-item-title',
disabled && 'disabled'
]
}
>Item</div>
样式绑定需要用双大括号。
const width = '100px'
const element = <button style={{ width, fontSize: '16px' }}></button>
绑定事件也是用大括号。
事件名前要加 on 前缀,比如:click 事件要写成 onClick。
const confirm = () => {
// 确认提交
}
<button onClick={confirm}>确定</button>
如果要带参数,需要使用箭头函数进行包裹:
const confirm = (name) => {
// 确认提交
}
<button onClick={() => confirm('123')}>确定</button>
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>
);
},
})
需要使用大括号。
SFC写法:
<SelfComponent v-model="menuShow" />
JSX写法:
<SelfComponent v-model={ menuShow.value } />
比如绑定 visible,JSX 中不能直接用 v-model:visible 的语法,需要传入一个数组 [menuShow.value, ‘visible’],数组的第二个参数就是要绑定的自定义名称。
SFC写法:
<SelfComponent v-model:visible="menuShow" />
JSX写法:
<SelfComponent v-model={ [menuShow.value, 'visible'] } />
jsx 中没有 <slot> 标签,定义插槽需要使用双大括号。
如果是具名插槽,则将 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>
使用作用域插槽可以实现插槽传参,以下是具体的示例。
JSX和SFC中插槽使用的写法对比。
JSX写法:
<self-tree data={data}>
{{
mySlot: (item) => (item.open ? <IconOpen /> : <IconClose />),
}}
</self-tree>
还可以通过 v-slots 的方式使用:
<self-tree data={data} v-slots={{
mySlot: (item) => (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>
在 JSX 中 h() 函数可以大展身手。
【参考推荐文章】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。