Vue3 JSX 语法速查:v-model、事件、插槽一网打尽

Vue3 JSX 以 JS 原生逻辑替代模板语法,核心转换规则如下:

  • 条件渲染v-if&&/ 三元表达式;v-show 直接保留
  • 循环渲染v-for → 数组 map 遍历
  • 事件处理 :事件名驼峰化,修饰符用 withModifiers 包裹
  • 双向绑定v-model 支持基础、自定义名、修饰符及多 model 场景
  • 插槽:支持默认 / 具名 / 作用域插槽,渲染与传递写法清晰
typescript 复制代码
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...等数组循环方式;
  • 事件:依驼峰命名方式写,onClickonMouseOver...等等
  • js: 用花括号包起来;
  • 对象:用两个花括号,外围的括号是js的括号,里面括号才是对象的括号;

二、事件

  1. 事件以驼峰命名方式定义;

  2. 事件要是有修饰符的话:

  • 以常规驼峰命名写;
typescript 复制代码
<input
  onClickCapture={() => {}}
  onKeyupOnce={() => {}}
  onMouseoverOnceCapture={() => {}}
  />
  • 可以使用 withModifiers 函数
typescript 复制代码
<div onClick={withModifiers(() => {}, ['self'])} />

三、v-model

Vue3 jsx新特性,支持v-model使用

(一)、modelValue

如果组件的v-modelmodelValue的话,那使用很简单;

typescript 复制代码
renderDropdown(h){
	const value = "value"
	return <custom-component v-mode={value}>
		code...
	</custom-component>
}

自定义value

比如v-model:visible=show写法如下:

typescript 复制代码
renderDropdown(h){
  const show = "true"
  return <el-popover v-model={[show, 'visible']}>
    code...
  </el-popover>
}

修饰符

  1. v-model后面跟着,使用(_)代替(.);vModel_trim = {value}
  2. withModifiers
typescript 复制代码
// 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

typescript 复制代码
// template
<A v-model="foo" v-model:bar="bar" />

// tsx
<A v-models={[[foo], [bar, "bar"]]} />

四、插槽

(一·)、渲染插槽

  1. js的方式
typescript 复制代码
// 默认插槽
<div>{slots.default()}</div>

// 具名插槽
<div>{slots.footer({ text: props.message })}</div>
  1. dom的形式
typescript 复制代码
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>
    )
}

(二)、传递插槽

typescript 复制代码
// 默认插槽
<MyComponent>{() => 'hello'}</MyComponent>

// 具名插槽
<MyComponent>{{
  default: () => 'default slot',
  foo: () => <div>foo</div>,
  bar: () => [<span>one</span>, <span>two</span>]
}}</MyComponent>

也可以如下:

typescript 复制代码
// 具名插槽
<MyComponent v-slots={{
  default: () => 'default slot',
  foo: () => <div>foo</div>,
  bar: () => [<span>one</span>, <span>two</span>]
}}></MyComponent>

(四)、作用域插槽

typescript 复制代码
<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 开发小程序 / 管理系统的全流程),欢迎关注~

相关推荐
学以智用2 小时前
Vue3 状态管理库 Pinia 完整教程
前端·vue.js
harrain2 小时前
vue3多个watch监听统一等待触发再执行后续逻辑的处理方案
前端·javascript·vue.js
wuhen_n2 小时前
Vite 核心原理:ESM 带来的开发时“瞬移”体验
前端·javascript·vue.js
nibabaoo2 小时前
前端开发攻略---vue3长列表性能优化终极指南:虚拟滚动、分页加载、时间分片等6种方案详解与代码实现
前端·javascript·vue.js·虚拟滚动·分页加载·长列表·时间分片
wuhen_n2 小时前
函数式组件 vs 有状态组件:何时使用更高效?
前端·javascript·vue.js
李剑一3 小时前
Cesium 海量点位不卡顿!图标动态聚合效果深度解析,看完直接抄代码!
前端·vue.js·cesium
予你@。3 小时前
Vue 项目中如何引用本地字体(完整指南)
前端·javascript·vue.js
daols884 小时前
vue表格vxe-table实现表头合并,分组表头自定义合并
前端·vue.js·vxe-table
芭拉拉小魔仙4 小时前
Vue v-html 中事件绑定失效问题及解决方案
javascript·vue.js·html