Vue中从template到jsx语法教程示例

 更新时间:2023年10月25日 09:00:04   作者:熊的猫  
这篇文章主要为大家介绍了Vue中从template到jsx语法教程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

从 template 到 jsx

大多数 Vue 开发者都习惯使用 template 模板语法,因为 template 模板语法 具有如下优点:

  • 熟悉的类 HTML 结构

    • 模板语法可以像 HTML 一样进行布局和设计,上手快、学习成本比低
  • 更简洁的写法

    • 例如,可以在模板中使用各种 修饰符 来达到简化编写代码的过程
  • 结构与逻辑分离

    • 元素结构和逻辑并没有杂糅在一起,因此结构上更简洁明了
  • 提供更好的性能

    • Vue3 中对模板语法在 编译阶段 进行的各种优化,使得其性能更好

但即便如此,在某些场景下还是不得不在 Vue 中使用 jsx 语法 实现需求, 例如开发 内部组件库 选择的编写形式就是 jsx 语法 等。

而对于习惯使用 template 模板语法 的开发者并不是轻易的就能转换到相应 jsx 语法,因此本文就列举一些 template 模板语法 中对应的 jsx 语法 应该怎么写。

插值表达式(文本插值)

template 语法

最基本的数据绑定形式就是 文本插值,它使用的是 Mustache 语法 (即 {{}} ),双大括号 中的内容最终 会将数据解释为纯文本。

<span>Message: {{ msg }}</span>

jsx 语法

而 JSX 中使用 文本插值 就从 双大括号 {{ }} 变成 单大括号 {}

<span>Message: { msg }</span>

原始 HTML

template 语法

双大括号 会将数据解释为纯文本,而不是 HTML,因此若想在模板中 插入 HTML,我们需要使用 v-html 指令

// html 字符内容
rawHtml = '<span>hello!</span>'
// 最终变成纯文本
<p>Using text interpolation: {{ rawHtml }}</p>
// 最终渲染为 html 结构
<div>Using v-html directive: <p v-html="rawHtml"></p></div>

jsx 语法

而在 jsx 语法 中就更直接了,我们直接通过 变量 的形式来写 html 结构 配合上 文本插值 {} 即可:

// 最终变成纯文本
cosnt rawHtml = '<span>hello!</span>'
<p>Using text interpolation: { rawHtml }</p>
// 最终渲染为 html 结构
cosnt rawHtml = <span>hello!</span>
<div>Using v-html directive: { rawHtml }</div>

条件渲染

template 语法

在模板语法中和 条件渲染 相关的可以直接使用指令 v-if / v-show 来实现:

<p v-show="isShow">hello world!</p>
<p v-show="!isShow">hello bros!</p>
<p v-if="isShow">hello world!</p>
<p v-else>hello bros!</p>

jsx 语法

而在 jsx 语法 中我们就不能使用 指令形式 了,取而代之的是 JavaScript 中的 if-else、&&、||、三元表达式 等形式:

if-else

const content = (isShow) => {
    if(isShow){
      return <h1>hello world!</h1>
    }else{
      return <div>hello bros!</div>
    }
}

&&

{ isShow && <div>hello world!</div> }
{ !isShow && <div>hello bros!</div> }

||

const content1 = <h1>hello world!</h1>
const content2 = <h1>hello world!</h1>
<div>{ content1 || content2 } </div>

三元表达式

const content1 = <h1>hello world!</h1>
const content2 = <h1>hello world!</h1>
<div>{ isShow ? content1 : content2 } </div>

列表渲染

tempalte 语法

在 template 模板 中可以通过 v-for 指令 来快速实现列表渲染:

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

jsx 语法

在 jsx 语法 中通常是使用 Array.prototype.map() 方法来实现列表渲染,原因就在于这个遍历数组的方法返回值也是数组:

<ul>
  {
    list.map((item) => (
      <li key={item.key}>{ item.text }</li>
    ))
  }
</ul>

style 外部样式

template 语法

在 .vue 文件 中可以通过 <style> 标签来 编写样式 或 导入外部样式,还可以直接通过设置 scope 实现局部样式:

<script setup lang="ts">
import { ref } from "vue";
import ChcekBox from "./components/CheckBox";
const checkResult = ref(false);
</script>
<template>
  <ChcekBox v-model="checkResult">选项</ChcekBox>
</template>
<style scope>
@import './index.less';
</style>

jsx 语法

而在一个 .jsx / .tsx 文件中由于不存在 <style> 元素,因此无法通过其来编写或导入样式,或者通过 scope 实现局部样式,可通过如下方式导入:

直接 import 导入

import { defineComponent, ref } from 'vue'
import './index.less'
export default defineComponent({})

通过 CSS Module 导入

import { defineComponent, ref } from 'vue'
import styleModule from './index.module.less'
export default defineComponent({
    setup() {
        return () => (
            <label class={styleModule.abs}>hello world!</label>
         )
})

事件绑定

tempalte 语法

在模板语法中绑定事件可以使用 v-on(简写 @) 来实现,并且可以在模板中 直接传递参数 给目标事件,也可以配合使用 事件修饰符,支持内联事件等等。

绑定处理函数

<!-- 方法处理函数 --> 
<button v-on:click="doThis"></button>
<!-- 缩写 --> 
<button @click="doThis"></button>

使用修饰符

<!-- 链式调用修饰符 -->
<button @click.stop.prevent="doThis"></button>

传递参数

<!-- 传参 --> 
<button @click="doThis($event, params)"></button>

内联事件

<!-- 传参 --> 
<button @click="count++"></button>

jsx 语法

上述写法在 jsx 语法 中的对应写法具体如下:

绑定处理函数

需要使用 on + [eventName] 的形式来绑定事件,可使用 或 不使用 驼峰形式,但当使用 typescript 时建议使驼峰形式,否则会有提示:

<!-- 驼峰 --> 
<button onClick={doThis}></button>
<!-- 非驼峰 --> 
<button onclick={doThis}></button>

使用修饰符

在 jsx 语法 中不能直接使用 .stop 形式的事件修饰符,需要通过 withModifiers 函数来实现,其支持 事件和按键修饰符:

<!-- withModifiers  -->
<button onClick={withModifiers(doThis, ['prevent'])}></button>

传递参数

在 jsx 语法 中不能像在模板中使用 handleAction($event, params) 的方式来实现传参,因为这种写法在 jsx 中属于调用,因此相当于把函数返回值作为事件绑定到目标元素上,大多数情况下会抛出异常(即返回值不一定为函数):

使用 bind 实现传参

const bindEvent = doThis.bind(tarrget)
<!-- 传参 -->
<button onClick={bindEvent}></button>

使用 箭头函数 实现传参

<!-- 传参 -->
<button onClick={ (parms) => bindEvent(parms)}></button>

内联事件

在 jsx 语法 并不支持内联事件的写法,因此可以使用箭头函数来包裹:

<!-- 方式一 -->
<button onClick={ () => count++ }></button>
<!-- 方式一 -->
const addCount = () => count++
<button onClick={ addCount }></button>

双向绑定 v-model

template 语法

v-model 可以在组件上使用以实现 双向绑定:

  • 在 原生表单元素 上使用 v-model 会被编译为 value 属性 和 input 事件
  • 在 组件 上使用 v-model 会被编译为 modelValue 属性 和 update:modelValue 事件
  • 支持自定义 v-model 绑定的 属性名 和 事件名
// 常见表单
<input v-model="searchText" />
// 自定义组件
<CustomInput v-model="searchText" />
// 自定义 v-model 名
<MyComponent v-model:title="bookTitle" />

jsx 语法

正常绑定

<CustomInput v-model={searchText} />

自定义名称

jsx 语法 中不存在类似 v-model:title 的命名形式,因此我们给 v-model 一个数组,如 [title, 'titleAlias']

  • 数组的第一个参数就是要绑定的 值

数组的第二个参数就是要绑定的 自定义名称

<Custom v-model={[title, 'titleAlias']} />

slot 插槽

template 语法

在模板语法中可以 <slot> 元素来定义 插槽出口,用于标示父元素提供的 插槽内容 的渲染位置:

默认插槽

<button class="fancy-btn">
  <slot></slot> <!-- 插槽出口 -->
</button>

具名插槽

<button class="fancy-btn">
  <slot name="content"></slot> <!-- 插槽出口 -->
</button>

动态插槽

<div> 
    <!-- 动态插槽 --> 
    <template v-slot:[dynamicSlotName]> ... </template> 

    <!-- 缩写为 --> 
    <template #[dynamicSlotName]> ... </template> </base-layout>
</div>

作用域插槽

<!-- MyComponent 模板 --> 
<div>
    <slot :text="greetingMessage" :count="1"></slot> 
</div>
<!-- 父组件模板 --> 
<MyComponent v-slot="slotProps"> 
    {{ slotProps.text }} {{ slotProps.count }} 
</MyComponent>

jsx 语法

由于 jsx 语法 中不存在 <slot> 元素,因此只能通过如下方式来渲染插槽内容:

从 SetupContext 中获取

defineComponent({
    setup(props, { slots }) {
        return <div>
            { slots.default && slots.default() }
            { slots.nameSlot && slots.nameSlot() }
        </div>
    }
})

使用 useSlot() 方法

import { defineComponent, renderSlots } from 'vue'
defineComponent({
    setup(props, context) {
        const slots = useSlots();
        return <div>
            { renderSlot(slots, 'default') }
        </div>
    }
})

使用 renderSlot() 方法

import { defineComponent, renderSlot } from 'vue'
defineComponent({
    setup(props, { slots }) {
        return <div>
            { renderSlot(slots, 'default') }
        </div>
    }
})

使用 Scoped Slots 作用域插槽

<!-- MyComponent 模板 --> 
defineComponent({
    setup(props, { slots }) {
        const slotParams = { name: 'hello' };
        return <div>
            { slots.default && slots.default(slotParams) }
        </div>
    }
})
<!-- 父组件模板 -->
defineComponent({
    setup(props, { slots }) {
        return <div>
            <MyComponent v-slot="slotProps"> 
                {{ slotProps.name }}
            </MyComponent>
        </div>
    }
})

以上就是Vue中从template到jsx语法指北的详细内容,更多关于Vue template jsx语法的资料请关注脚本之家其它相关文章!

相关文章

  • 探索Vue中组合式API和选项式API的用法与比较

    探索Vue中组合式API和选项式API的用法与比较

    Vue3为我们开发提供了两种组件逻辑实现方式:选项式API和组合式API,本文将尝试为大家分析什么是选项式API和组合式API,以及两种API的优缺点,希望对大家有所帮助
    2023-12-12
  • vue使用axios实现excel文件下载的功能

    vue使用axios实现excel文件下载的功能

    这篇文章主要介绍了vue中使用axios实现excel文件下载的功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • vue项目中使用高德地图的超详细步骤

    vue项目中使用高德地图的超详细步骤

    在vue项目中添加高德地图,对开发地图的开发人员有一定帮助,下面这篇文章主要给大家介绍了关于vue项目中使用高德地图的超详细步骤,文中通过图文以及实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法

    Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法

    下面小编就为大家分享一篇Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • Vue中指令v-model的原理及使用方法

    Vue中指令v-model的原理及使用方法

    v-model是Vue中的一个重要语法糖,主要用于实现数据的双向绑定,它通过结合value属性和input事件,简化了代码并提高了开发效率,文中通过代码介绍的非常详解,需要的朋友可以参考下
    2024-09-09
  • vue配置根目录详细步骤(用@代表src目录)

    vue配置根目录详细步骤(用@代表src目录)

    vue用@表示src文件夹,引入时找文件路径更方便,下面这篇文章主要给大家介绍了关于vue配置根目录(用@代表src目录)的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • 解决vue中el-date-picker type=daterange日期不回显的问题

    解决vue中el-date-picker type=daterange日期不回显的问题

    这篇文章主要介绍了解决vue中el-date-picker type=daterange日期不回显的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • vue篇之事件总线EventBus使用示例详解

    vue篇之事件总线EventBus使用示例详解

    这篇文章主要为大家介绍了vue篇之事件总线EventBus使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • vue导出excel文件流中文乱码问题及解决

    vue导出excel文件流中文乱码问题及解决

    这篇文章主要介绍了vue导出excel文件流中文乱码问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • VUEJS实战之修复错误并且美化时间(2)

    VUEJS实战之修复错误并且美化时间(2)

    这篇文章主要为大家详细介绍了VUEJS实战之修复错误并且美化时间,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-06-06

最新评论