如何在vue中正确使用jsx

302 阅读2分钟

使用JSX心得

JSX 是 JavaScript 的一个类似 XML 的扩展,有了它,我们可以用以下的方式来书写代码

const vnode = <div>hello word</div>

基础语法

1、基础写法

const vnode = <div>hello word</div>

2、嵌入表达式

const name = 'hello word'
const vnode = <div>{name}</div>

3、属性

const name = 'hello word'
const handleClick = () => {
    console.log('hello word')
}
const vnode = <div name={name} onClick={handleClick}>hello word</div>// 特殊情况
// 类名使用className
const vnode = <div className="my-class">hello word</div>// 样式使用对象
const vnode = <div style={{ width: '200px' }}>hello word</div>

4、注释

const element = (
  <div>
    {/* 这是JSX中的注释 */}
    <h1>标题</h1>
  </div>
);

进阶用法

1、三元表达式

const isLoggedIn = false
const element = (
  <div>
    {isLoggedIn ? <LogoutButton /> : <LoginButton />}
  </div>
);

2、使用逻辑与运算符

const showWarning = true
const element = (
  <div>
    {showWarning && <WarningMessage />}
  </div>
);

3、列表渲染

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>{number}</li>
);
​
const element = <ul>{listItems}</ul>;

Vue中使用jsx

jsx虽然最早是由 React 引入,但实际上 JSX 语法并没有定义运行时语义,并且能被编译成各种不同的输出形式。如果你之前使用过 JSX 语法,那么请注意 Vue 的 JSX 转换方式与 React 中 JSX 的转换方式不同,因此不能在 Vue 应用中使用 React 的 JSX 转换。与 React JSX 语法的一些明显区别包括:

  • 可以使用 HTML attributes 比如 classfor 作为 props - 不需要使用 classNamehtmlFor
  • 传递子元素给组件 (比如 slots) 的方式不同

存在的差异

1、可以使用class和for作为 props
// vue中的写法
const render = (
    <div class="my-class" for="forSomething">
        hello word
    </div>
)
​
// 相当于jsx的写法
const render = (
    <div className="my-class" htmlFor="forSomething">
        hello word
    </div>
)

在Vue中要如何使用jsx

像我们开发中,模版编译的写法确实很方便,但有时候就是需要使用jsx,即是使用js形式来写组件会相对简单,但是在使用上,像我一开始不是能理解其中写法,很容易用错语法,写出不能编译的代码,如下所示

<template>
    <h1>
        hello word
    </h1>
​
    {{ renderSomething }}
</template><script lang=“jsx” setup>
const renderSomething = (
    <div>hello javascript</div>
)
</script>

这种方式是没办法直接渲染jsx的变量,因为在vue的模板中不能直接渲染jsx变量(或者说是不能直接渲染编译好的虚拟节点),但可以Vue提供了另一种方式,可通过函数式组件渲染

<template>
    <h1>
        hello word
    </h1><renderSomething />
</template><script lang=“jsx” setup>
const renderSomething = (
    <div>hello javascript</div>
)
</script>

useSlots

Setup 上下文中返回 slots 对象,其中包含父组件传递的插槽。这些插槽为可调用的函数,返回虚拟 DOM 节点。像我们上面的例子中,定义的jsx变量可以理解为是定义一个虚拟DOM节点(其中转化过程vue已经帮忙我们处理过了)

<template>
    <render />
</template><script setup lang="jsx">
const slots = useSlots()
​
const render = () => {
    const defalutSlot = slots.default() // 返回一个默认插槽的虚拟节点
    const titleSlot = slots.title() // 返回一个具名插槽为title的虚拟节点
    return (
        <div>
            {defalutSlot}
            {titleSlot}
        </div>
    )
}
</script>

总结

之前写过次很多的vue项目,也大量的使用jsx,但发现自身的对jsx的语法和使用上并不是很了解,趁着这段时间没那么繁忙,赶紧总结输出下相关的基础概念和使用注意事项