• vue3 中使用 jsx 开发(语法差异)


    安装 JSX 插件

    Vue2 中要想使用 jsx 开发,需要安装 @vue/babel-preset-jsx 等插件,之后在 babel 里指定即可,详细可以参考下面的 Vue2 GitHub 文档

    Vue2:GitHub 文档 —— Babel Preset JSX

    最近在使用 Vue3,突然想用 jsx 进行开发部分页面,顺便记录一下,也可以参考下面的 Vue3 GitHub 文档

    Vue3:GitHub 文档 —— Babel Plugin JSX for Vue 3.0

    构建工具使用的是 vite,要想使用 jsx 开发,需要安装 @vitejs/plugin-vue-jsx,之后配置 vite.config.js 里的 plugins 即可

    // vite.config.js
    import vueJsx from '@vitejs/plugin-vue-jsx'
    import { defineConfig } from 'vite'
    
    export default defineConfig(() => {
      return {
        plugins: [vueJsx()]
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    接下来着重说一下在使用 .vue 文件和 .jsx 文件在使用语法上的差异

    使用语法差异

    模板

    之前在 template 里写的 html 代码需要放到 render 函数或 setup 函数里,Vue3 在 setup 里写会好一点

    
    <template>
      <div>Hello Worlddiv>
    template>
    
    
    <script>
    export default defineComponent({
      setup() {
        return () => (
          <div>Hello World</div>
        )
      }
    })
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    指令

    需要把双引号改为单括号

    • v-ifv-showv-html 等同理
    • v-bind 也是一样的,不过需要把动态绑定需要去掉 :

    注意:

    • .vue 文件中,ref 在模板中会自动进行解包,所以不需要使用 .value
    • 但是在 .jsx 文件中,ref 在模板中不会自动解包,所以需要使用 .value
    
    <el-input v-model="queryParams.pageNumber" />
    <el-form model="queryParams" :inline="true">...el-form>
    
    
    <el-input v-model={queryParams.value.pageNumber} />
    <el-form model={queryParams.value} inline={true}>...el-form>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    事件修饰符

    • 想使用事件修饰符可以把 v-model 改为一个数组,事件修饰符需要以数组的形式传递

      如果需要传递参数,需要在数组第二个参数中以字符串形式传递

    • 推荐:可以使用 _ 来分割事件修饰符,GitHub 里没有特殊声明,但是 Babel Plugin JSX for Vue 3.0 源码里做了判断,可以参考: parseDirectives.ts#L52-L61

    
    <el-input v-model.trim={ queryParams.name } />
    
    
    <el-input v-model={ [queryParams.value.name, ['trim'] } />
    
    <el-input v-model_trim={ refVal.value } />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    自定义指令

    如下示例为:添加 .event 事件修饰符并传递 arg 参数,直接打印 binding 效果如下:

    image-20220901105132150

    
    <el-button
      v-hasPermission:arg.event="['xxx:add']"
      type="primary"
      plain
      icon="Plus"
      @click="handleAdd"
    >
      新增
    el-button>
    
    
    
      新增
    el-button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    v-for

    • v-for 无法直接使用,需要使用 map 去实现循环遍历渲染
    
    <h1 v-for="item in list" :key="item">{{item}}h1>
    
    
    <script>
    {list.value.map(item => (
      <h1>{item}</h1>
    ))}
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注意:

    • 如果遍历时需要判断每一项其是否显示,不能使用 v-if,需要使用三元运算符
    • v-forv-if 不能一起使用
    
    <template v-for="col in columns">
      <el-table-column
        v-if="col.visible"
        :key="col.key"
        :label="col.label"
        :prop="col.field"
      />
    template>
    
    
    {columns.value.map(col =>
      col.visible ? (
        <el-table-column
          key={col.id}
          label={col.label}
          prop={col.field}
        />
      ) : null
    )}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    v-on

    • v-on 无法直接使用,需要使用原生绑定事件的方式去实现(@ -> on,之后进行驼峰)
    
    <el-button @click="handleQuery">搜索el-button>
    
    
    <el-button onClick={handleQuery}>搜索el-button>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    系统按键修饰符不能通过 .xxx 形式书写,需要自己进行判断,比如如下示例是按回车时进行搜索

    • 这里顺便说一下 style,由于里面是 : 形式表示,需要改为对象形式书写
    
    <el-input
      v-model.trim="queryParams.number"
      clearable
      style="width: 180px"
      @keyup.enter="handleQuery"
    />
    
    
    { width: '180px' }}
      onKeyup={e => e.code === 'Enter' && handleQuery()}
    />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    插槽

    在 jsx 中,应该使用 v-slots 代替 v-slot,且插槽需要是函数式组件

    
    <el-dialog
      v-model="configOpen"
      title="弹出框"
      append-to-body
      >
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="configOpen = false">取 消el-button>
        div>
      template>
    el-dialog>
    
    
    {
        footer: () => (
          <div class='dialog-footer'>
             {
                configOpen.value = false
              }}
            >
              取 消
            el-button>
          div>
        )
      }}
      >
      
    el-dialog>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • 相关阅读:
    LeetCode每日两题02:字符串的排列 (均1200道)方法:哈希表-双指针-滑动窗口
    Jmeter——性能测试的认知以及思考bug(一)
    【前端vue面试】vue2
    DOM渲染与优化 - CSS、JS、DOM解析和渲染阻塞问题
    基于ssm的贫困生管理系统javaEE
    命令行版 Centos 7 虚拟机安装 xfce4 桌面 + x11vnc + novnc
    flink MemoryStateBackend 和 RocksDBStateBackend 切换导致任务出现bug
    在C#中通过groupby组织List对象成为多级别Json数据
    四. 优化与源码
    PC5080USB适配器充电芯片5V/1A输入具有0V充电功能
  • 原文地址:https://blog.csdn.net/qq_38689395/article/details/126639124