拥抱jsx,开启vue3用法的另一种选择??

这篇具有很好参考价值的文章主要介绍了拥抱jsx,开启vue3用法的另一种选择??。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

📝背景

公司高级表单组件ProForm高阶组件都建立在jsx的运用配置上,项目在实践落地过程中积累了丰富的经验,也充分感受到了jsx语法的灵活便捷和可维护性强大,享受到了用其开发的乐趣,独乐乐不如众乐乐,为了帮助大家更好的运用jsx,开发提效,特此总结分享。

💎效果对比

以前

以往我们开发一个列表的增加、编辑、查看详情三个操作要准备3个form表单文件,表单中ui元素共性部分我们要复制三次,例如:

// addForm.vue
<template>
<el-form :model="form" >
 <el-form-item label="活动名称">
 <el-input v-model="form.name" />
 </el-form-item>
 <el-form-item label="活动区域">
 <el-input v-model="form.region" />
 </el-form-item>
 <el-form-item label="活动形式">
 <el-input v-model="form.type" />
 </el-form-item>
 </el-form>
  <el-form-item>
      <el-button >新增</el-button>
    </el-form-item>
</template>


<script setup>
import { reactive } from 'vue'
const form = reactive({
  name: '',
  region: '',
  type: '',
})
...
</script>

// editForm.vue

<template>
<el-form :model="form" >
 <el-form-item label="活动名称">
 <el-input v-model="form.name" />
 </el-form-item>
 <el-form-item label="活动区域">
 <el-input v-model="form.region" />
 </el-form-item>
 <el-form-item label="活动形式">
 <el-input v-model="form.type" />
 </el-form-item>
  <el-form-item>
      <el-button >编辑</el-button>
    </el-form-item>
  </el-form>
</template>


<script setup>
import { reactive,inject } from 'vue'
const form = reactive({})
form=inject('detailData')
...
</script>

// detailForm.vue

<template>
<el-form :model="form" :disabled="true" >
 <el-form-item label="活动名称">
 <el-input v-model="form.name" />
 </el-form-item>
 <el-form-item label="活动区域">
 <el-input v-model="form.region" />
 </el-form-item>
 <el-form-item label="活动形式">
 <el-input v-model="form.type" />
 </el-form-item>
  <el-form-item>
      <el-button >关闭详情</el-button>
    </el-form-item>
  </el-form>
</template>


<script setup>
import { reactive,inject  } from 'vue'
const form = reactive({})
form=inject('detailData')
...
</script>

如果遇到改字段名的情况,如把活动名称的name改成activityName,对应的3个文件都得去修改,表单改动多的话还有可能存在有得文件改漏的情况。

现在

现在使用ProForm结合jsx配置,如下



// add.vue
<template>
 <activity-form
 ref="formRef"
 mode="Add"
 />
      <el-button >新增</el-button>
</template>


<script setup>
Import  ActivityForm from './form.vue'
...
</script>


// edit.vue
<template>
<activity-form
 ref="formRef"
 mode="Edit"
 />
   <el-button >编辑</el-button>
</template>


<script setup>
Import  ActivityForm from './form.vue'
...
</script>
// detail.vue
<template>
 <activity-form
 ref="formRef"
 mode="detail"
 />
   <el-button >关闭详情</el-button>
</template>


<script setup>
Import  ActivityForm from './form.vue'
...
</script>

Form.vue

<template>
  <yun-pro-form
    ref="formRef"
    :form="form"
    :columns="columns"
    :form-props="{ labelPosition: 'top',disabled:mode==='detail' }"
  />
</template>

<script lang="jsx" setup>
import { reactive, ref, computed } from 'vue'
...
const formRef = ref()
const form = reactive({
  name: '',
  region: '',
  type: '',
})
const props = defineProps({
  mode: {
    type: String,
    default: 'Add',
  },
});
const columns = [
  {
    prop: 'name',
    label: '活动名称',
    type: 'input',
  },
  {
      prop: 'region',
      label: '活动区域',
      // jsx部分
      render: (form) => (
        <el-input clearable  v-model={form.region} />
      ),
   },
    {
      prop: 'type',
      label: '活动形式',
      // jsx部分
      render: (form) => (
        <el-input clearable  v-model={form.type} />
      ),
   },
]

...
</script>

改成上面的形式后,一处改动,3处对应生效,开发的重点也转移到form表单中对columns的配置上,columns配置则建立在对jsx的运用,当然举的这个例子只是一个简单案例,复杂的例子在项目中,下面我们正式开启jsx之旅吧

📝JSX是什么

JSX(JavaScript 和 XML),是一个 HTML-in-JavaScript 的语法扩展,首先在 React 中被进入,它允许我们在JavaScript中编写类似HTML的代码,并将其转换为JavaScript对象。Vue3中引入了对JSX的支持,使得我们可以更加灵活地编写组件模板,不再局限于Vue2.x中的模板语法。JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。

形如:

const element = <div id="root">Hello World</div>

function getGreeting(user) {
    if (user) {
        return <h1>Hello, {formatName(user)}!</h1>;
    }
    return <h1>Hello, Stranger.</h1>;
}

📝JSX 和 template 的区别

--语法上有很大区别:

JSX 本质就是 js 代码,可以使用 js 的任何能力
template 只能嵌入简单的 js 表达式,其他需要指令,如 v-if
插值不同,jsx 使用单括号 { },template 使用双括号 {{ }}
JSX 已经成为 ES 规范,template 还是 Vue 自家规范
--本质是相同的:
都会被编译为 js 代码(render 函数)

📝基本用法

安装使用

vite 官方提供了官方的插件来支持在 vue3 中使用 jsx

yarn add @vitejs/plugin-vue-jsx

安装完之后在 vite.config.js 文件中的 plugins 字段中添加 jsx 支持:


import vueJsx from "@vitejs/plugin-vue-jsx";
export default defineConfig({
  plugins: [
    vueJsx(),
  ]
})

插值表达式

// template
<template>
  <span>{{ a + b }}</span>
</template>
 
// jsx
 render: () => {
    return (
       <span>{ a + b }</span>
    )
}

条件渲染

jsx只保留了 v-show指令,没有 v-if指令
使用 if/else和三目表达式来实现判断
// template v-if  v-show
<template>
  <div v-if="show">是</div>
  <div  v-else>否</div>
   <div v-show="show">我是v-show</div>
</template>
 
// jsx
 render: () => {
    const show = ref(true);
    return (
    <div>
       <div>{show.value ? <div>是</div> : <div>否</div>}</div>
        <div v-show={!show.value}>我是v-show</div> 
     </div>
    )
}
// jsx  if-else

 render: () => {
    const isShow = false
      const element = () => {
       if (isShow) {
           return <div>是</div>
       } else {
           return <div>否</div>
       }
   }
    return (
    <div>
           {
               element()
           }
        <div v-show={!show.value}>我是v-show</div> 
     </div>
    )
}


样式绑定

class类名绑定有两种方式,使用模板字符串或者使用数组。
style绑定需要使用 双大括号
// template
<template>
 <div  class="static" :class="{ active: isActive }"></div>
 <div :class="[isActive ? activeClass : '', static]"></div>
 <div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
</template>


// jsx
// jsx 模板字符串
<div className={`static  ${ isActive ? 'active' : '' }`}>header</div>
//jsx 数组
<div class={ [ 'static', isActive && 'active' ] } >header</div>

// jsx 样式绑定需要使用双大括号。
 render: () => {
    const width = '100px'
    return (
      <button style={{ width, fontSize: '16px' }}></button>
    )
}

列表循环

// template v-for

<template>
  <ul>
    <li v-for="item in list" :key="item">{{ item }}</li>
  </ul>
</template>

// jsx 数组 .map 函数
 
 render: () => {
    return <>
      <ul>
        { list.map(item => <li>{item}</li>)}
      </ul>
    </>
  }

事件处理

jsx绑定事件使用的是 单大括号 {},事件绑定不是以 @为前缀了,而是改成了 on,例如:click 事件是 onClick
如果需要使用事件修饰符,就需要借助withModifiers方法啦,withModifiers 方法接收两个参数,第一个参数是绑定的事件,第二个参数是需要使用的事件修饰符,或者在有些修饰符不生效的情况下采用链式驼峰的形式进行设置,如@click.once变为 onClickOnce
// template 

<template>
 <button @click="clickButton('button1')"> 点击</button>
 <!-- 单击事件将停止传递 -->
  <a @click.stop="doThis"></a>
 <!-- 点击事件最多被触发一次 -->
 <a @click.once="doThis"></a>
</template>

// jsx 数组 .map 函数
 
 render: () => {
     const clickButton = val => {
        console.log(val)
    }
    return (
      <div>
      <button  onClick={() =>clickButton('button1')}>点击</button>
       <a onClick={withModifiers(() => doThis(), ['stop'])}></a>
       <a onClickOnce={doThis}></a>
      </div>
    )
  }


标签属性绑定

// template 
<template>
<div v-bind="properties"></div>
</template>

//jsx
 render: () => {
    return (
      <div {...properties}></div>
    )
  }

V-model


// 一般用法
<input v-model="value" /> //  template
<input v-model={value} /> // jsx

// 指定绑定值写法
<input v-model:modelValue="value" /> //  template
<input v-model={[value,'modelValue']} /> // jsx

// 修饰符写法
<input v-model:modelValue.trim="value" /> //  template
<input v-model={[value,'modelValue',['trim']]} /> // jsx

插槽

定义插槽

jsx/tsx中是没有 slot 标签的,定义插槽需要使用{}或者使用renderSlot函数

setup 函数默认接收两个参数 1. props 2. ctx 上下文 其中包含 slots、attrs、emit 等


// template
<template>
  <div>
   <slot></slot>
   <slot name="title"></slot>
  </div>
</template>

// jsx
import { renderSlot } from "vue"
export default defineComponent({
    // 从ctx中解构出来 slots
    setup(props, { slots }) {
        return () => (
            <div>
                { renderSlot(slots, 'default') } // 等价于  { slots.default?.() }
                { slots.title?.() }
            </div>
        )
    }
})


使用插槽

通过 v-slots 来使用插槽

// template
<template>
   <yun-table
  >
    <template #action="{ row }">
      <el-button type="action" @click="handleDel(row)">
        删除
      </el-button>
    </template>
  </yun-table>
</template>

// jsx
render: (form) => {
        const slots = {
          action: ({ row }) => <el-button type="action" onClick={() => handleDel(row)}>
          删除
        </el-button>,
        };
        return (
             <yun-table
              v-slots={slots}
            >
            </yun-table>
          
        );
      },



jsx基础模板

import { defineComponent, onMounted, ref } from 'vue';

export default defineComponent({
  // props: ['xx'],
  setup(props,{ emit }) {
    onMounted(() => {
      // ...
    })
    return () => (
      <div></div>
    )
  }
})

组件运用

在 .vue 文件中使用 jsx组件

// 父
 
<template>
  <div class="home">
    <JSXDemo />
  </div>
</template>
 
<script setup lang="jsx">
import JSXDemo from '@/components/JSXDemo.vue'

</script>
 
// JSXDemo.vue
 
<script>
import { ref } from 'vue'
export default {
  setup () {
    const countRef = ref(200)
 
    const render = () => {
      return <p>DEMO1--{countRef.value}</p> 
    }
    return render
  }
}
</script>
 
 

在.jsx文件格式中父子组件属性传递

// 父组件
 
import { defineComponent, ref } from 'vue'
import JSXChild from './JSXChild.jsx'
 
export default defineComponent(() => { // 传入 setup 函数
  const countRef = ref(360)
 
  const render = () => {
    return <>
      <p>数量--{countRef.value}</p>
      <JSXChild a={countRef.value + 100}></JSXChild>  // vue3的template会自动解析ref的.value,在jsx中ref的.value是不会被自动解析的
    </>
  }
  return render 
})
 
// 子组件 JSXChild.jsx
 
import { defineComponent } from 'vue'
 
export default defineComponent({ // 传入组件配置
  props: ['a'],
  setup (props) {
    const render = () => {
      return <>
        <p>child {props.a}</p>
      </>
    }
    return render
  }
})


📝经验总结

我们该怎么选择 JSX 和 template ?

template优势:template 的语法是固定的,有 v-if、v-for 等等语法。按照这种固定格式的语法书写的代码, Vue3 在编译层面就可以很方便地去做静态标记的优化,减少Diff过程。比如静态提升,类型标记,树结构打平等来提高虚拟 DOM 运行时性能。这也是 Vue 3 的虚拟 DOM 能够比 Vue 2 快的一个重要原因。

JSX优势:template 因为语法限制原因,不能够像 JSX 那样可以支持更动态的需求。每一个 .vue 文件结尾的文件都是一个组件,而且只能 export default 出一个组件,JSX 则不同 ,是可以在一个文件内返回多个组件的,比如我们写一个页面的时候其实可能会需要把一些小的节点片段拆分到小组件里面进行复用,这些小组件在jsx里面,写个简单的函数组件就能搞定,例如:

拥抱jsx,开启vue3用法的另一种选择??

那如何选择呢?

在实现业务需求的时候,优先使用 template,尽可能地利用 Vue 本身的性能优化,如列表、弹窗和抽屉。而对于动态性要求较高的组件可以使用 JSX 来实现,比如动态表单,封装动态递归组件。而对于公司项目来说,大多数业务需求都是表单类的,那就赶紧用上jsx吧,用久了你就会发现,哎,真香。文章来源地址https://www.toymoban.com/news/detail-482038.html

到了这里,关于拥抱jsx,开启vue3用法的另一种选择??的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • github 通过ssh进行连接的另一种方式

    一般使用ssh连接是通过22端口。如果已经把ssh公钥假如到了github中还无法连接。可以通过 测试一下。如果报出 ssh: connect to host github.com port 22: Connection timed out 可以通过443 端口进行连接 注意:端口 443 的主机名为 ssh.github.com,而不是 github.com。 也需修改项目地址

    2024年01月20日
    浏览(73)
  • 智能家居的另一种形式:智能家居中心的技术架构

    作者:禅与计算机程序设计艺术 随着智能设备的普及、互联网技术的飞速发展以及人们对智能家居产品的追求,越来越多的人选择将家居环境变成一个“智能”的地方,比如通过智能安防系统、智能遥控器、智能监控等方式帮助用户实现更加精细化的生活控制和场景管理。但

    2024年02月07日
    浏览(67)
  • git提交的时候出现异常“bad object HEAD”的另一种解决方案

    Git仓库是目前很主流的代码管理工具,一旦被损坏或出现异常,内心想直接吐血。 当进入到Git仓库执行命令: git status 显示: fatal: bad object HEAD 在此尝试用git checkout git reflog 等命令希望能恢复,但都是提示错误。在网上搜索大部分看到的是如下的解决方式: 但是我的代码分

    2024年02月02日
    浏览(66)
  • STM32-HAL库08-TIM的输出比较模式(输出PWM的另一种方式)

    STM32F103C6T6最小系统板 STM32CUBEMX(HAL库软件) MDK5 示波器或者逻辑分析仪 通过定时器TIM的输出比较模式得到预定频率与占空比的PWM波形;其中定时器输出比较模式与PWM模式的区别在于!!! PWM模式在同一个TIM下所有输出口的频率一致不能单独控制单个的频率 ,而输出比较模式

    2024年02月03日
    浏览(64)
  • 在Linux云服务器上部署stable diffusion的lora训练的另一种方法

    这里参考了https://www.bilibili.com/video/BV1fs4y1x7p2/?vd_source=419c9ebc4060e9bec24d95773bba5275 LoRA 模型训练教程 一键包 以及: https://colab.research.google.com/drive/1_f0qJdM43BSssNJWtgjIlk9DkIzLPadx#scrollTo=8Qp6STJk2Wjh 首先是安装miniconda 或者 anaconda 来获得虚拟环境: 建立虚拟环境: 这里我们只需要有pytho

    2024年02月16日
    浏览(54)
  • SQL的substring函数及其用法实例——MYSQL另一种截取目标字符的函数

    目录 1.substring()的语法和用法实例 (1)两个参数的语法和用法实例 ①语法:substring(string ,index)|substring(string from index) ②用法实例: 从指定字符串的某序数开始获取字符 (2)三个参数的语法和用法实例 ①语法:substring(string ,index,len)|substring(string from index for len) ②用法实

    2023年04月08日
    浏览(85)
  • jsx (vue3项目中使用)

    一、什么是jsx 在 JavaScript 里面写 HTML 的语法,就叫做 JSX,算是对 JavaScript 语法的一个扩展. (在vue3项目中相当于单文件组件,.vue)使用的是jsx语法 二、jsx语法 1.插值。与 vue 模板语法中的插值一样,但是双大括号 {{}} 变为了单大括号 {}。大括号内支持任何有效的 JavaScript 表

    2024年01月17日
    浏览(42)
  • Vue3 项目中怎么使用 jsx——易懂

    在 vue3 项目中使用JSX( JavaScript XML )可以让你更灵活地创建组件和视图。接下来给大家讲解一下vue3项目中怎么使用 jsx 步骤 1: 创建一个Vue 3 项目 如果你还没有Vue 3项目,可以使用Vue CLI来创建一个。 在创建项目时,确保选择Vue 3选项。接下来,进入项目目录并启动开发服务器

    2024年02月06日
    浏览(38)
  • 如何在 vue3 中使用 jsx/tsx?

    我们都知道,通常情况下我们使用 vue 大多都是用的 SFC(Signle File Component)单文件组件模式,即一个组件就是一个文件,但其实 Vue 也是支持使用 JSX 来编写组件的。这里不讨论 SFC 和 JSX 的好坏,这个仁者见仁智者见智。本篇文章旨在带领大家快速了解和使用 Vue 中的 JSX 语法,好让大家

    2023年04月19日
    浏览(51)
  • 在Vue2和Vue3中JSX的使用集锦

    有时候,我们使用渲染函数(render function)来抽象组件,而渲染函数使用Vue的h函数来编写Dom元素相对template语法差别较大,体验不佳,这个时候就派 JSX 上场了。然而在Vue3中默认是带了JSX支持的,而在 Vue2 中使用 JSX,需要安装并使用 Babel 插件: @vue/babel-preset-jsx @vue/babel-hel

    2024年02月09日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包