Skip to content

JSX简明语法

Kagol edited this page Apr 21, 2022 · 7 revisions

简明语法

Vue DevUI组件库的所有组件使用JSX方式编写,因此特意准备了一份JSX简明语法指南,方便大家学习和参考。

嵌入表达式

使用大括号包裹,支持任何有效的 JavaScript 表达式,比如:2 + 2user.firstNameformatName(user)

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

条件渲染

jsx本身也是一个条件表达式。

使用 if/else

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>

类名 class

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

还可以使用数组:

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

样式 style

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>

Scoped Slots 作用域插槽

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

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

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>

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>

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>
    );
  },
});

参考

Vue 3 Babel JSX 插件

Vue3 JSX 使用指南

JSX 简介