Vue DevUI 所有组件都是 Vue3 + JSX 语法写的,我尽管会 Vue3,然而我不会 JSX 怎们办?
有了这份《Vue3中应用JSX扼要语法》宝典就不慌啦!
这份宝典会集了所有你在写 Vue3 我的项目可能会用到的罕用 JSX 语法。
1 文本插值
Vue外面文本插值默认是用双大括号:
<h1>{{ msg }}</h1>
在JSX中变成了单大括号:
const name = 'Vue DevUI'const element = <h1>Hello, { name }</h1>
和Vue模板语法中的文本插值一样,大括号内反对任何无效的 JavaScript 表达式,比方:2 + 2
,user.firstName
,formatName(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://devui.design/'const element = <a href={href}>DevUI Design</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 双向绑定
- 绑定
modelValue
这种状况比较简单。
JSX
写法:
<d-flexible-overlay v-model={ menuShow.value }></d-flexible-overlay>
SFC
写法:
<d-flexible-overlay v-model="menuShow"></d-flexible-overlay>
- 绑定自定义名称
比方绑定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中没有<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>
9.1 Scoped Slots 作用域插槽
应用作用域插槽能够实现插槽传参,以下是具体的示例。
JSX
和SFC
中插槽应用的写法比照。
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>
10 小结
本文是一个小册子,次要介绍在 Vue3 中应用 JSX 的语法和实际,蕴含了文本插值、属性绑定、事件绑定、双向绑定、条件渲染、列表渲染、插槽等简直所有的 Vue3 语法,如果你也在 Vue3 中写 JSX,这份指南或者能提供一点参考。
欢送退出 Vue DevUI 开源我的项目,一起摸索更多 Vue3 + JSX 的玩法!
增加DevUI小助手微信:devui-official,退出咱们的技术交换群,一起玩开源!
https://github.com/DevCloudFE/vue-devui/
DevUI:体验让世界更美妙!