Vue3 JSX 以 JS 原生逻辑替代模板语法,核心转换规则如下:
- 条件渲染:
v-if→&&/ 三元表达式;v-show直接保留 - 循环渲染:
v-for→ 数组map遍历 - 事件处理:事件名驼峰化,修饰符用
withModifiers包裹 - 双向绑定:
v-model支持基础、自定义名、修饰符及多 model 场景 - 插槽:支持默认 / 具名 / 作用域插槽,渲染与传递写法清晰
import { ref } from 'vue'
export default function add(props, ctx) {
let visible = props.visible
let form = props.form
let plus = props.isPlus
let addFormRef = ref()
async function handleOk() {
const error = await addFormRef.value.validate()
if (error) return
let url = plus ? 'insert' : 'update'
let msg = plus ? '新增成功' : '更新成功'
proxy.post(`/api/mapbus/pm/project/${url}`, form).then((res) => {
proxy.$message.success(msg)
ctx.emit('success')
})
}
return (
<a-drawer visible={visible} title={plus ? '新建' : '编辑'} width="30%" onOk={handleOk}>
<a-form ref={addFormRef} model={props.form} auto-label-width>
<a-form-item field="projectName" label="项目名称" validate-trigger="blur" rules={{required: true, message: '项目名称必填'}}>
<a-input v-model={form.projectName}></a-input>
</a-form-item>
<a-form-item field="remark" label="说明">
<a-input v-model={form.remark}></a-input>
</a-form-item>
</a-form>
</a-drawer>
)
}
一、常规逻辑
v-if: 转换成js逻辑,三元表达式也可;v-show: 支持;可直接写成v-show;v-for:转换成js逻辑,forEach,map...等数组循环方式;- 事件:依驼峰命名方式写,
onClick,onMouseOver...等等 js: 用花括号包起来;- 对象:用两个花括号,外围的括号是
js的括号,里面括号才是对象的括号;
二、事件
-
事件以驼峰命名方式定义;
-
事件要是有修饰符的话:
- 以常规驼峰命名写;
<input
onClickCapture={() => {}}
onKeyupOnce={() => {}}
onMouseoverOnceCapture={() => {}}
/>
- 可以使用
withModifiers函数
<div onClick={withModifiers(() => {}, ['self'])} />
三、v-model
Vue3 jsx新特性,支持v-model使用
(一)、modelValue
如果组件的v-model是modelValue的话,那使用很简单;
renderDropdown(h){
const value = "value"
return <custom-component v-mode={value}>
code...
</custom-component>
}
自定义value
比如v-model:visible=show写法如下:
renderDropdown(h){
const show = "true"
return <el-popover v-model={[show, 'visible']}>
code...
</el-popover>
}
修饰符
v-model后面跟着,使用(_)代替(.);vModel_trim = {value}withModifiers
// template<input v-model="val" />
<input v-model:name="val">
<input v-model.trim="val">
<input v-model:name.trim="val">
// tsx
<input v-model={val} />
<input v-model={[val, 'name']} />
<input v-model={[val, ['trim']]} />
<input v-model={[val, 'name', ['trim']]} />
多个model
// template
<A v-model="foo" v-model:bar="bar" />
// tsx
<A v-models={[[foo], [bar, "bar"]]} />
四、插槽
(一·)、渲染插槽
js的方式
// 默认插槽
<div>{slots.default()}</div>
// 具名插槽
<div>{slots.footer({ text: props.message })}</div>
- 以
dom的形式
export default function common(props, ctx) {
const children = ctx.slots.default()[0]
function handleBack() {
ctx.emit('back', 12)
}
return (
<div className={commonCss.panelContainer}>
<div className={commonCss.header}>
<MyIcon name="return" size={16} style={{cursor: 'pointer'}} onClick={handleBack}></MyIcon>
</div>
<children></children>
</div>
)
}
(二)、传递插槽
// 默认插槽
<MyComponent>{() => 'hello'}</MyComponent>
// 具名插槽
<MyComponent>{{
default: () => 'default slot',
foo: () => <div>foo</div>,
bar: () => [<span>one</span>, <span>two</span>]
}}</MyComponent>
也可以如下:
// 具名插槽
<MyComponent v-slots={{
default: () => 'default slot',
foo: () => <div>foo</div>,
bar: () => [<span>one</span>, <span>two</span>]
}}></MyComponent>
(四)、作用域插槽
<MyComponent>{{
default: ({ text }) => <p>{ text }</p>
}}</MyComponent>
五、总结
| 模板语法(Template) | JSX/TSX 语法 | 说明 |
|---|---|---|
v-if="show" | {show && <div>内容</div>} | 三元表达式也可:{show ? <div>显示</div> : <div>隐藏</div>} |
v-show="show" | <div v-show={show}>内容</div> | 直接支持 v-show |
| v-for="item in list" | {list.map(item => <div>{item}</div>)} | 需加 key |
@click.stop="handleClick" | onClick={withModifiers(handleClick, ['stop'])} | 修饰符用 withModifiers 包裹 |
| v-model:visible="show" | <el-popover v-model={[show, 'visible']}> |
感谢您抽出宝贵的时间观看本文;本文是 Vue3 核心 API 系列的第 2 篇,后续会持续更新 computed、ref/reactive、生命周期等实战内容,同时正在整理「Vue3 完整项目实战小册」(包含从 0 到 1 开发小程序 / 管理系统的全流程),欢迎关注~