当前位置:首页 > 技术分析 > 正文内容

极致爽文,tsx、jsx语法应用vue3

ruisui882周前 (04-11)技术分析7

前言

JSX语法让程序员体验到前所未有的舒爽,而在Vue3中,快速过渡到TSX也是轻而易举的。除了下文介绍的TSX用法外,其他方面与Vue3的使用方式并无二致。TSX所需学习的内容并不繁杂,只是稍微改变了开发习惯,取消了模板语法,让我们能够像编写JavaScript一样书写页面。

工程搭建

通过执行npm init vue来创建一个Vue工程。

工程地址

你可以在以下地址找到本文使用的工程示例:gitee.com/z-shichao/v…

组件定义:defineComponent

在Vue3中,defineComponent是一个用于定义组件的函数API。它的作用主要有三个方面:

  1. 创建组件选项对象:defineComponent允许你定义一个包含组件配置信息的选项对象,如组件的属性、方法、生命周期钩子等。
  2. 类型推断支持:使用defineComponent可以帮助TypeScript更好地推断组件的类型,从而提高开发效率和代码的健壮性。
  3. 提供组件定义上下文:defineComponent内部对组件选项对象进行一些处理,包括生命周期钩子的转换、模板的编译等,从而提供了一个统一的组件定义上下文,使得组件的定义更加清晰和一致。

这里有个专门讲解defineComponent的文章 :juejin.cn/post/699461…

tsx语法

tsx有种书写模式:函数语法,选项语法

//选项式
import { defineComponent } from "vue"
export default defineComponent({
  setup() {
    return () => (
vue3+tsx
) } })


//函数式
export default defineComponent(() => {
  return () => (
vue3+tsx
) })


使用选项语法还是函数语法主要取决于个人习惯。下文示例将使用选项式进行讲解。

注意:返回的是一个函数,在函数中返回的是一个JSX元素。JSX元素中必须有一个根标签。如果不想使用根标签,可以使用<>代替,该标签不会在页面中渲染。

插值语法

export default defineComponent({
  setup() {
    let text = ref('我是文本内容')
    return () => (
{text.value}
) } })


注意:使用ref定义响应式数据时,在模板中需要使用.value来访问。

事件绑定

export default defineComponent({
  setup() {
    let text = '我是文本内容'
    return () => (<>
    
{text}
) } })


事件修饰符

后边加驼峰事件修饰符

export default defineComponent({
  setup() {
    let text = '我是文本内容'
    return () => (<>
    
{text}
) } })


注意:使用大括号{}进行插值,使用on+事件名(小驼峰命名法)进行事件绑定,自定义事件也是一样的。

jsx中移除了部分指令:v-bin、v-for、v-if

v-bind:使用大括号{}进行包裹

export default defineComponent({
  setup() {
    let text = '我是文本内容'
    let style = {
      background: 'red'
    }
    return () => (<>
      
{text}
) } })


  • v-for:使用数组方法map
export default defineComponent({
  setup() {
    let items = ['张三', '李四', '王五']
    return () => (<>
      {items.map((item) => 
{item}
)} ) } })


v-if:使用三元表达式

export default defineComponent({
  setup() {
    let isShow = ref(true)
    return () => (<>
      
{isShow.value ?
我出来饿了
: ''}
) } })


注意:js要写在{}里面,返回值是是一个可渲染的元素或元素组成的数组。

插槽

默认插槽

import { defineComponent, ref } from "vue"
export default defineComponent({
  setup(props, { slots }) {
    let text = ref('我是默认插槽')
    return () => ({text.value})
  }
})
let Child = (props: any, { slots }: any) => {
  return 
{slots.default()}
}


具名插槽

import { defineComponent, ref } from "vue"
export default defineComponent({
  setup(props, { slots }) {
    let text = ref('我是默认插槽')
    return () => (
      {{
        default: () => text.value,
        name1: () => '我是插槽1',
        name2: () => '我是插槽2'
      }}
    )
  }
})
let Child = (props: any, { slots }: any) => {
  return 
{slots.default()}
{slots.name1()}
{slots.name2()}
}


作用域插槽

export default defineComponent({
  setup(props, { slots }) {
    let text = ref('我是默认插槽')
    return () => (
      {{
        default: () => text.value,
        name1: () => '我是插槽1',
        name2: (parms: string) => 
{parms}
}}
) } }) let Child = (props: any, { slots }: any) => { let parms: string = '我是参数' return
{slots.default()}
{slots.name1()}
{slots.name2(parms)}
}


还可以通过props传参向子组件传递元素

import { defineComponent, ref } from "vue"
export default defineComponent({
  setup(props, { slots }) {
    let text = ref('我是默认插槽')
    return () => (<Child
      childs={[
        
我是一
,
我是二
]}>) } }) let Child = (props: any, { slots }: any) => { return
{props?.childs[0]}
{props?.childs[1]}
}


使用css scoped

在Vue 3 中,如果想要在 TSX 文件中使用 CSS scoped 样式,通常不能直接在 TSX 文件中实现 scoped 样式。你可以在 .vue 单文件组件中的 <script> 标签中编写 TSX 代码,并且将 <script> 标签的 lang 属性设置为 'tsx',然后在


vue3+tsx中定义props:

import { defineComponent, PropType } from "vue"
export default defineComponent({
    setup() {
        return () => (<>
            
我是父组件
) } }) //子组件 const Text = defineComponent({ props:{ name:{ type:String as PropType, required:true } }, setup(props) { return () => (<>
{props.name}
) } }) import { defineComponent ,PropType} from "vue" export default defineComponent({ setup() { return () => (<> ) } })


注意:在tsx中定义类型时,只能定义比较笼统的Object、String等,这种类型为什么比较笼统呢,因为在js语言中Object在任何变量的原型上都存在,当你定义一个Object时他就会和any类型时类似的,其他类型同理,当我们想要定义某个类型时,我们只能使用as+ PropType的形式。

简化props的使用:

首先要了解定义string会报错呢,因为我们使用了defineComponent帮我们进行了类型推断定义。那我们可不可以不使用,自己使用ts来规范我们的类型呢。当然可以!!!

方案一:

不适用defineComponent 自己使用ts来进行类型定义,但只支持函数语法和react用法几乎一样

可以看到使用ts也可以进行类型定义,并且更为简便。当然参数在子组件里也是可以定义接收的。缺点就是jsx中是不能使用这种方式的。

import { defineComponent } from "vue"
export default defineComponent({
    setup() {
        return () => (<>
            
我是父组件
) } }) interface Props { name: string, age?: number } const Text = (props: Props, ctx: any) => { return
{props.name}
}


方案二:

混编 这个有篇文章可以看一下 juejin.cn/post/714305…

方案三:

使用# Vue Macros构建项目

vue-macros.dev/zh-CN/guide…

vue中jsx语法和模板语法的优缺点:

JSX语法:

优点:

  1. 更灵活的语法: JSX允许在模板中使用JavaScript表达式,使得模板更加灵活和表达能力更强,更容易阅读和理解JSX的代码。
  2. 组件逻辑更直观,易维护: JSX让组件的结构和逻辑更加紧密,因为你可以在组件中直接编写JavaScript逻辑,并且在同一个文件中可以写多个组件,将相关性较强的组件放在一起更易维护。
  3. 性能较好: 使用JSX编写Vue 3组件会比使用模板语法的组件具有更好的性能。因为JSX可以直接将组件转换为纯JavaScript 代码,而模板语法需要在运行时进行解析和编译。性能差异不大。

缺点:

  1. 学习曲线较陡: 对于新手来说,学习JSX语法可能需要一定的时间,特别是对于那些不熟悉React或其他使用JSX的框架的人来说。
  2. 与HTML混合: 有些开发者可能觉得在JavaScript中嵌入HTML的方式不够直观,因为它打破了HTML和JavaScript的分离原则。
  3. 与模板的差异:TSX(或 JSX)语法与 Vue 的模板语法有一定的差异,可能需要一定的适应时间,并且不支持一些模板特有的语法和指令。

模板语法:

优点:

  1. 易于学习和上手: 模板语法更接近传统的HTML,因此对于初学者来说更容易理解和上手。
  2. HTML代码直观: 模板语法使得HTML代码更加直观,可以更清晰地看到组件的结构。
  3. 编辑器支持良好: 大多数编辑器对Vue模板语法有良好的支持,提供语法高亮、自动补全等功能。

缺点:

  1. 表达能力受限: 模板语法相比于JSX在表达能力上受到一定的限制,因为因为它不能像JSX那样直接在模板中使用JavaScript表达式。
  2. 组件与逻辑分离: 使用模板语法时,组件的结构和逻辑可能会分离得较为明显,因为一些逻辑需要放在JavaScript中,而不是直接嵌入模板中。

总的来说,选择JSX还是模板语法取决于个人的偏好、团队的技术栈以及项目的需求。在Vue 3中,JSX语法的支持更加完善,因此如果你对JavaScript更为熟悉,或者项目需要更高的灵活性和表达能力,那么可以考虑使用JSX语法。而对于简单的项目或团队中大多数成员都熟悉HTML的情况下,模板语法可能更为适合。


作者:用户1585826119852
链接:
https://juejin.cn/post/7352763168902578230

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/3417.html

标签: vue 修饰符
分享给朋友:

“极致爽文,tsx、jsx语法应用vue3” 的相关文章

Vue3 如何实现父子组件传值?

在Vue 3中,要实现父子组件传值效果主要通过props和emit两种机制来实现,下面我们就来详细介绍一下这两种机制。父组件向子组件传值propsprops是Vue组件的一种机制,主要的作用就是实现从父组件向子组件传递数据值,在父组件上通过在子组件标签上定义属性来实现数据属性值的传递,在子组件中通过...

面试官:聊聊你知道的Vue与React的区别

最近面到很多大公司的时候,小编都会碰到一个很尴尬的问题,很多大公司的技术栈都是React,但是小编学的是Vue,其实从本质上来说两者都是比较优秀的前端框架,所以有些面试官会问到Vue和React的区别。小编认真整理了一些自己所知道的Vue和React的区别,给大家分享分享。1. 模板语法 vs JS...

「云原生」Containerd ctr,crictl 和 nerdctl 命令介绍与实战操作

一、概述作为接替Docker运行时的Containerd在早在Kubernetes1.7时就能直接与Kubelet集成使用,只是大部分时候我们因熟悉Docker,在部署集群时采用了默认的dockershim。在V1.24起的版本的kubelet就彻底移除了dockershim,改为默认使用Conta...

你感动了吗?佳能超规格镜头 RF 24-105mm F2.8深度测评

如果要你选一支用作多题材创作的挂机镜头,那我相信很多人会选择24-105mm这个焦段的镜头。作为一支可以实现从广角到长焦的变焦镜头,24-105mm有着丰富的焦段选择。只是基于镜头体积以及光学结构上的限制,此前的24-105mm镜头只能恒定在F4的光圈。而佳能打破了这一限制,将实用焦段和恒定光圈完美...

《暗黑破坏神 2:重制版》PC 版 2.3 版本发布,支持英伟达 DLSS

IT之家 12 月 3 日消息,暴雪为《暗黑破坏神 2:重制版》PC 版发布了更新 2.3 版本,添加了“离线难度缩放”滑块(玩家可以在单人游戏时增加挑战和奖励的级别)、多项辅助功能和用户界面改进,以及英伟达 DLSS 支持。玩法改进:玩家现在可以在离线游戏的选项菜单中使用“游戏难度等级”,它提供与...

Vue真是太好了 壹万多字的Vue知识点 超详细!

1??、Vue和其他两大框架的区别Angular 学习成本太高React 代码可读性差Vue 学习成本较低 很容易上手VUE官方: https://cn.vuejs.org/v2/guide/comparison.html?2??、Vue是什么Vue是一套用于构建用户界面的渐进式框架 "前端...