📝 前端Vuer,请收下这份《Vue3中使用JSX简明语法》

阿轩的BUG
文章191
评论56
标签101
站点日志
作者总数:1位
置顶文章:0篇
标签总数:101条
文章总数:196篇
评论总数:56条
微语总数:201条
运行天数:2320天
最近更新:2026-07-28
文章标签
最新评论
Sherlock
2025-08-21
不是应该打包成apk文件吗,怎么突然就运行编译了,下一步呢
老金er
2025-05-25
人生设计非常必要,在信息化发达的今天,周围大部分人依然只能过着人生工程模式生活,长时间生活洗礼后,尽管“人生工程”已经不再适合很多人,他们也无法做出任何改变,人生设计给我们提供了新的思路,值得尝试
赏帮赚
2025-05-25
职场太多的尔虞我诈
三笑
2024-08-16
emlog6.0.1可以升级支持吗?
pony
2024-07-08
这篇文章提供了一种新的人生规划方法——"人生设计",它借鉴了产品设计的理念,鼓励人们以创造性和探索性的方式思考和规划自己的生活。以下是对这篇文章的几个评价维度: 创新性:将产品设计的理念应用于人生规划是一个新颖的视角,为人们提供了一种跳出传统生活轨迹,探索个性化生活路径的方法。 实用性:文章不仅提出了理念,还详细介绍了具体的实施步骤,包括自我评估、制定计划、原型设计和实践选择等,具有很强的操作性。 启发性:通过强调好奇心、不断尝试、重新定义问题等心态,文章鼓励人们打破常规,勇于探索未知,这对于激发个人潜能和创造力具有积极作用。 适应性:"人生设计"理念适用于不同人生阶段和不同背景的人,无论是希望从头开始的人,还是已经取得一定成就但希望探索新方向的人,都可以从中获得启发。 情感共鸣:文章对许多人对传统生活轨迹的不满和对改变的渴望进行了深刻的洞察,能够引起读者的共鸣。 可持续性:人生设计强调的是一个持续迭代和试错的过程,这与现实生活的发展规律相吻合,有助于人们在不断变化的环境中做出适应性调整。 教育意义:作为一种人生规划方法,"人生设计"可以作为教育的一部分,帮助年轻人更早地学会自我探索和规划,为未来的生活和职业发展打下基础。 局限性:尽管"人生设计"提供了一种新的思考框架,但它可能需要个人具备一定的自我认知和反思能力,对于一些缺乏自我探索经验的人来说,可能需要额外的指导和支持。 总体来说,这篇文章提供了一种有价值的人生规划方法,对于那些渴望改变、寻求个性化生活的人来说,是一种有益的参考和指导。
首页实用干货 🌋

本文汇集了所有你在写 Vue3 项目可能会用到的常用 JSX 语法。

1 文本插值

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

<h1>{{ msg }}</h1>

在JSX中变成了单大括号:

const name = 'Vue JSX'
const element = <h1>Hello, { name }</h1>

和Vue模板语法中的文本插值一样,大括号内支持任何有效的 JavaScript 表达式,比如:2 + 2user.firstNameformatName(user)等。

2 条件渲染

jsx本身也是一个条件表达式,不再需要使用v-if指令。

2.1 使用 if/else

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

以上代码等效于:

const element = (name) => <h1>Hello, { name || 'Stranger' }</h1>

2.2 使用三目运算符

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

以上代码等效于:

const element = icon && <span class="icon"></span>;

3 列表渲染

列表渲染直接使用JS数组的map方法即可,不需要使用v-for指令。

const data = [{
  id: 1,
  title: '通用'
}, {
  id: 2,
  title: '导航'
}]

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

4 标签属性绑定

属性绑定也是使用大括号包裹,不需要使用v-bind指令。

const href = 'https://yxbug.cn/'
const element = <a href={href}>阿轩的Bug</a>

5 class 类名绑定

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

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

也可以使用数组:

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

6 style 样式绑定

样式绑定需要使用双大括号。

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

7 事件绑定

绑定事件也是用大括号,注意事件名前面要加上on前缀,比如click事件要写成onClick,mouseenter事件要写成onMouseenter

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

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

const confirm = (name) => {
  // 确认提交
}

<button onClick={() => confirm('devui')}>确定</button>

7.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, ['self']) }>{ count.value }</div>
    );
  },
})

注意:Vue模板中ref变量是可以直接解构的,但是在jsx中不行,需要记得添加.value,比如上面的{ count.value }

8 v-model 双向绑定

  1. 绑定modelValue

这种情况比较简单。

JSX写法:

<d-flexible-overlay v-model={ menuShow.value }></d-flexible-overlay>

SFC写法:

<d-flexible-overlay v-model="menuShow"></d-flexible-overlay>
  1. 绑定自定义名称

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

JSX写法:

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

SFC写法:

<d-flexible-overlay v-model:visible="menuShow"></d-flexible-overlay>

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>

9.1 Scoped Slots 作用域插槽

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

JSXSFC中插槽使用的写法对比。

JSX写法:

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

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

<d-tree data={data} v-slots={{
  mySlot: (item) => (item.open ? <IconOpen /> : <IconClose />)
}}>
</d-tree>

SFC写法:

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

其中的item是插槽的参数,通过

ctx.slots.mySlot(item)

的方式给插槽传入参数。

或者使用renderSlot方法,第三个参数就是要传给插槽的参数:

import { renderSlot, useSlots } from 'vue'

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

补充:

  1. 属性绑定
const properties = {a: 1, b: 2}

SFC中 <div v-bind="properties"></div> 批量绑定标签属性。在JSX中的替换方案是 <div {...properties}></div>

  1. class绑定

使用CSS Modules,引入局部样式,相当于SFC中的scoped

import styles from './index.module.scss'
<div class={styles.wrap}></div>
上一篇
🛢️ 打造高效能研发团队的 5 个关键步骤
下一篇
🧱 程序猿:我真的写不出代码了......