在 Vue 3 中使用 JSX 需要以下步骤和注意事项:
一、环境配置
- 安装依赖:
bash
npm install @vue/babel-plugin-jsx
- 配置
babel.config.js
:
javascript
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
'@vue/babel-plugin-jsx'
]
}
二、基础用法示例
1. 简单组件
jsx
// MyComponent.jsx
import { defineComponent } from 'vue'
export default defineComponent({
setup() {
const count = ref(0)
const increment = () => count.value++
return () => (
<div class="container">
<h1>{count.value}</h1>
<button onClick={increment}>+1</button>
</div>
)
}
})
2. 使用 Props
jsx
// Child.jsx
const props = defineProps({
msg: String
})
return () => <div>{props.msg}</div>
3. 事件绑定
jsx
// Parent.jsx
const handleClick = () => console.log('Clicked!')
return () => (
<Child onClick={handleClick} />
)
// Child.jsx
const emit = defineEmits(['click'])
return () => (
<button onClick={() => emit('click')}>
Click me
</button>
)
三、高级用法
1. 条件渲染
jsx
const isLoading = ref(true)
return () => (
<div>
{isLoading.value
? <Spinner />
: <Content />}
</div>
)
2. 列表渲染
jsx
const items = ref(['Apple', 'Banana', 'Orange'])
return () => (
<ul>
{items.value.map(item => (
<li key={item}>{item}</li>
))}
</ul>
)
3. 插槽使用
jsx
// Parent.jsx
return () => (
<Child>
<template #header>
<h1>Custom Header</h1>
</template>
<p>Default slot content</p>
</Child>
)
// Child.jsx
return () => (
<div>
<header>{slots.header?.()}</header>
<main>{slots.default?.()}</main>
</div>
)
四、注意事项
-
属性命名:
- 使用驼峰式命名(如
class
→className
) - 事件监听使用
onClick
而非@click
- 使用驼峰式命名(如
-
样式处理:
jsx
// 内联样式
<div style={{ color: 'red', fontSize: '16px' }} />
// CSS 类
<div class="my-class" />
- 组件注册:
jsx
import MyComponent from './MyComponent.jsx'
export default {
components: {
MyComponent
}
}
- TypeScript 支持:
tsx
// 使用 .tsx 扩展名
interface Props {
count: number
}
const Component = defineComponent<Props>({
setup(props) {
return () => <div>{props.count}</div>
}
})
五、性能优化技巧
- Memoization:
jsx
import { memo } from 'vue'
const MemoizedComponent = memo(() => (
<div>Expensive rendering</div>
))
- Key 的正确使用:
jsx
{items.map(item => (
<div key={item.id}>{item.name}</div>
))}
- 避免内联函数:
jsx
// Bad
<button onClick={() => handleClick(item)}>Click</button>
// Good
<button onClick={withDefaults(handleClick, item)}>Click</button>
通过合理使用 JSX,可以:
- 提升复杂模板的可维护性
- 更好地利用 TypeScript 类型检查
- 实现更灵活的动态渲染逻辑
建议根据项目需求选择使用模板语法或 JSX,对于需要复杂逻辑或类型安全的场景,JSX 是更好的选择。