-
Notifications
You must be signed in to change notification settings - Fork 289
JSX简明语法
Kagol edited this page Apr 21, 2022
·
7 revisions
Vue DevUI
组件库的所有组件使用JSX
方式编写,因此特意准备了一份JSX简明语法指南,方便大家学习和参考。
使用大括号包裹,支持任何有效的 JavaScript 表达式,比如:2 + 2
,user.firstName
,formatName(user)
。
const name = 'Vue DevUI'
const element = <h1>Hello, { name }</h1>
jsx本身也是一个条件表达式。
const element = (name) => {
if (name) {
return <h1>Hello, { name }</h1>
} else {
return <h1>Hello, Stranger</h1>
}
}
const element = icon ? <span class="icon"></span> : null;
const data = [{
id: 1,
title: '通用'
}, {
id: 2,
title: '导航'
}]
const element = data.map(item => {
return <div>{ item.title }</div>
})
const href = 'https://devui.design'
const element = <a href={href}></a>
const element = <div className={`devui-accordion-item-title ${ disabled ? 'disabled' : '' }`}></div>
还可以使用数组:
const element = <div className={['devui-accordion-item-title', disabled && 'disabled' }`]}></div>
const width = '100px'
const element = <button style={{ width: width, fontSize: '16px' }}></button>
注意:
- class -> className
- tabindex -> tabIndex
如果是具名插槽,则将default
改成具名插槽的名称,比如myslot
,则使用ctx.slots.myslot?.()
。
button.tsx:
import { defineComponent } from 'vue'
import './button.scss';
type IButtonType = 'button' | 'submit' | 'reset';
export default defineComponent({
name: 'd-button', // 组件名
props: { // 输入/输出
type: {
type: String as () => IButtonType,
default: 'button'
},
btnClick: {
type: Function as unknown as () => ((event: MouseEvent) => void)
}
},
setup(props, ctx) { // 逻辑
const { type, btnClick } = props;
return {
type, btnClick
}
},
render() { // 模板
const { type, btnClick } = this
return <button
type={type}
onClick={btnClick}
>{ this.$slots.default?.() }</button>
}
})
如果只写setup
,则插槽从ctx
获取,并且不需要再加$
前缀。
import { defineComponent } from 'vue'
import './button.scss';
type IButtonType = 'button' | 'submit' | 'reset';
export default defineComponent({
name: 'd-button', // 组件名
props: { // 输入/输出
type: {
type: String as () => IButtonType,
default: 'button'
},
btnClick: {
type: Function as unknown as () => ((event: MouseEvent) => void)
}
},
setup(props, { slots }) { // 逻辑
const { type, btnClick } = props;
return () => {
return <button
type={type}
onClick={btnClick}
>{ slots.default?.() }</button>
}
},
})
还可以使用renderSlot
方法:
import { renderSlot } from 'vue'
<button>
{ renderSlot(slots, 'default') }
</button>
使用作用域插槽可以实现插槽传参的,以下是具体的示例。
JSX
和SFC
中插槽使用的写法对比。
JSX
写法:
<d-tree data={data}>
{{
mySlot: (item: TreeItem) => (item.open ? <IconOpen /> : <IconClose />),
}}
</d-tree>
还可以通过v-slots
的方式使用:
<d-tree data={data} v-slots={{
mySlot: (item: TreeItem) => (item.open ? <IconOpen /> : <IconClose />),
}}>
<d-tree-node>xxx</d-tree-node>
</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.绑定modelValue
这种情况比较简单
JSX
写法:
<d-flexible-overlay v-model={menuShow.value}>
</d-flexible-overlay>
SFC
写法:
<d-flexible-overlay v-model="menuShow">
</d-flexible-overlay>
2.绑定自定义名称
比如绑定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>
jsx中给事件增加修饰符需要借助withModifiers
方法。
import { withModifiers, defineComponent } from "vue";
const App = defineComponent({
setup() {
const count = ref(0);
const inc = () => {
count.value++;
};
return () => (
<div onClick={withModifiers(inc, ["self"])}>{count.value}</div>
);
},
});