Vue 3 第二十二章:组件十(组件高级特性-组件的渲染函数和JSX/TSX语法)

news2025/2/25 13:23:44

文章目录

  • 1. 渲染函数
  • 2. JSX / TSX 语法
    • 2.1. 基本使用
    • 2.2. 使用 vue 中的语法
      • 2.2.1. {} 语法
      • 2.2.2. v-model 使用
      • 2.2.3. v-show 使用
      • 2.2.4. v-if 不支持,实现v-if功能
      • 2.2.5. v-for 不支持,实现 v-for 功能
      • 2.2.6. v-bind 不支持,模拟 v-bind
      • 2.2.7. v-on 使用
      • 2.2.8. Props 使用
      • 2.2.9. Emit 使用
      • 2.2.10. v-slot 使用
  • 总结

1. 渲染函数

渲染函数是一种将组件的模板转换成虚拟 DOM 的方法。在 Vue 中,我们可以选择使用渲染函数来代替模板语法。

渲染函数可以让我们更加灵活地定义组件的模板,并且可以让我们在编写组件时使用JavaScript的全部语言特性。在Vue3中,我们可以使用 h 函数来创建虚拟 DOM 元素。h 函数接受三个参数:元素名元素的属性子元素

下面是一个简单的示例代码:

// ChildComponent.vue
<script lang="ts">
import { h } from "vue";

export default {
  render() {
    return h("div", { class: "container", style: { color: "red" } }, [
      h("h1", "Hello, world!"),
      h("p", "h函数的基本使用"),
    ]);
  },
};
</script>


// Parent.vue
<template>
  <div>
    <child-component></child-component>
  </div>
</template>

<script setup lang="ts">
import ChildComponent from "./ChildComponent.vue";
</script>

渲染到页面上的效果如下:
在这里插入图片描述

在上面的代码中,我们定义了一个渲染函数,并使用 h 函数来创建 div 元素、h1 元素和 p 元素。我们将这些元素作为子元素传递给 div 元素,并将 div 元素作为渲染函数的返回值。当我们在组件中使用渲染函数时,我们可以将其返回值渲染到页面上。

需要注意的是,在Vue3中,我们可以选择使用模板语法渲染函数来定义组件的模板。使用哪种方式取决于我们的个人喜好和项目的需求。

2. JSX / TSX 语法

JSX 是一种将XML语法嵌入到JavaScript中的语法。在 Vue3 中,我们可以使用JSX语法来编写组件的模板。使用JSX语法可以让我们更加灵活地定义组件的模板,并且可以让我们在编写组件时使用JavaScript的全部语言特性。

要在 Vue3 中使用 JSX 语法,我们需要安装 @vitejs/plugin-vue-jsx 插件,并在 vite.config.ts 文件中配置该插件。然后,我们就可以在组件中使用 JSX 语法了。

下面是一个简单的示例代码:

2.1. 基本使用

1)安装 @vitejs/plugin-vue-jsx

npm install @vitejs/plugin-vue-jsx -D

2)配置vite.config.ts
在这里插入图片描述
3)配置 tsconfig.json 文件
在这里插入图片描述

// vite.config.ts
import { fileURLToPath, URL } from "node:url";

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), vueJsx()],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
});

3)使用TSX

// index.tsx
const tsxDom = () => {
  return (
    <>
      <div class="container">
        <h1>Hello, world!</h1>
        <p>This is a tsx.</p>
      </div>
    </>
  );
};

export default tsxDom;
// tsx.vue
<template>
  <div>
    <tsxDom></tsxDom>
  </div>
</template>

<script setup lang="ts">
import tsxDom from "@/tsx/index";
</script>

<style scoped></style>

在页面上渲染的结果如下:
在这里插入图片描述

2.2. 使用 vue 中的语法

2.2.1. {} 语法

// index.tsx
// tsx 中使用{}语法
import { ref } from "vue";

let hello = ref<string>("Hello, world!");
const tsxDom = () => {
  return (
    <>
      <div>
        <h1>{hello.value}</h1>
        <p>This is a tsx.</p>
      </div>
    </>
  );
};

export default tsxDom;

2.2.2. v-model 使用

注意:使用 v-model 时,需要 .value 获取值

// index.tsx
// tsx 中使用 v-model 语法
import { ref } from "vue";
let hello = ref<string>("Hello, world!");

const tsxDom = () => {
  return (
    <>
      <input type="text" v-model={hello.value} />
    </>
  );
};

export default tsxDom;

2.2.3. v-show 使用

注意:使用 v-show 时,需要 .value 获取值

// index.tsx
// tsx 中使用 v-show 语法
import { ref } from "vue";
let flag = ref<boolean>(false);

const tsxDom = () => {
  return (
    <>
      <div v-show={flag.value}>显示</div>
      <div v-show={!flag.value}>隐藏</div>
    </>
  );
};

export default tsxDom;

2.2.4. v-if 不支持,实现v-if功能

使用v-if时,报错:

![在这里插入图片描述](https://img-blog.csdnimg.cn/e9096405f14b4bc189b0ac8742cbb085.png

此时需要采用三元运算来实现 v-if 的功能:

// tsx 中模拟 v-if 语法
import { ref } from "vue";
let flag = ref<boolean>(false);

const tsxDom = () => {
  return <>{flag.value ? <div>显示</div> : <div>隐藏</div>}</>;
};

export default tsxDom;

2.2.5. v-for 不支持,实现 v-for 功能

// tsx 中模拟 v-for 语法
import { reactive } from "vue";
interface Data {
  name: string;
  age: number;
}
let list = reactive<Data[]>([
  { name: "张三", age: 12 },
  { name: "李四", age: 18 },
]);

const tsxDom = () => {
  return (
    <>
      {
      	{/* 此处完全遵循 react 语法即可 */}
        list.map((item) => {
          return <div>{item.name}</div>;
        })
      }
    </>
  );
};

export default tsxDom;

2.2.6. v-bind 不支持,模拟 v-bind

  • 使用时,用 {} 包裹
  • 以 data- 开头的自定义属性
// tsx 中模拟 v-bind 语法
import { reactive } from "vue";

interface List {
  name: string;
  age: number;
}

let list = reactive<List[]>([
  {
    name: "张三",
    age: 10,
  },
  {
    name: "李四",
    age: 18,
  },
]);

const tsxDom = () => {
  return (
    <>
      {
        list.map((item) => {
          return <div data-name={item.name}>{item.age}</div>;
        })
      }
    </>
  );
};

export default tsxDom;

渲染效果如下:
在这里插入图片描述

2.2.7. v-on 使用

  • jsx/tsx中事件的使用与 react 一致
  • 以 on 开头
  • 接收一个回调函数
    注意:不能使用vue中的修饰符
// tsx 中模拟 v-on 语法

const handleClick = () => {
  console.log("被点击了");
};

const tsxDom = () => {
  return (
    <>
      <button onClick={() => handleClick()}>点击</button>
    </>
  );
};

export default tsxDom;

测试效果如下:

在这里插入图片描述

2.2.8. Props 使用

  • 通过父组件传递参数
  • jsx/tsx接收props并使用
// tsx.vue
<template>
  <div>
    <tsxDom :userName="userName" :userAge="userAge"></tsxDom>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import tsxDom from "@/tsx/props";

const userName = ref<string>("张三");
const userAge = ref<number>(18);
</script>

<style scoped></style>
// props.tsx
// tsx 中接收及使用props
interface Props {
  userName?: string;
  userAge?: number;
}

const handleClick = (props: Props) => {
  console.log(props);
};

const tsxDom = (props: Props) => {
  return (
    <>
      <div>{props.userName}</div>
      <div>{props.userAge}</div>
      <button onClick={() => handleClick(props)}>点击</button>
    </>
  );
};

export default tsxDom;

测试效果如下:
在这里插入图片描述

2.2.9. Emit 使用

  • jsx/tsx组件中通过第二个参数 ctx 拿到 emit 方法
  • 通过 emit() 方法传递一个自定义事件以及参数
  • 父组件通过 v-on:自定义事件 拿到传递过来的值
// tsx.vue
<template>
  <div>
    <tsxDom
      :userName="userName"
      :userAge="userAge"
      @on-click="handleClick"
    ></tsxDom>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import tsxDom from "@/tsx/emit";

const userName = ref<string>("张三");
const userAge = ref<number>(18);

const handleClick = (value: string) => {
  console.log(value); // 张三
};
</script>

<style scoped></style>

tsx 中通过emit给父组件传参

// emit.tsx
interface Props {
  userName?: string;
  userAge?: number;
}

const handleClick = (props: Props, ctx: any) => {
  ctx.emit("on-click", props.userName);
};

const tsxDom = (props: Props, ctx: any) => {
  return (
    <>
      <div>{props.userName}</div>
      <div>{props.userAge}</div>
      <button onClick={() => handleClick(props, ctx)}>点击</button>
    </>
  );
};

export default tsxDom;

2.2.10. v-slot 使用

  • 子组件通过 centex.slots 传参
  • 父组件通过 v-slots={} 接收参数
import { defineComponent, reactive } from "vue";

const state = reactive({ name: "张三" });
const list = reactive([1, 2, 3]);

export const tsxDom = (props: any, ctx: any) => (
  <>
    {/* 默认插槽 */}
    <div>{ctx.slots.default ? ctx.slots.default() : "默认"}</div>
    {/* 声明名称为state的插槽 并传值,不传值为ctx.slots.state() */}
    <div>{ctx.slots.state && ctx.slots.state(state)}</div>
    {/* 声明名称为list的插槽 并传值,不传值为slots.list() */}
    <div>{ctx.slots.list && ctx.slots.list(list)}</div>
  </>
);

export default defineComponent({
  setup() {
    type State = {
      name: string;
    };

    // 使用插槽
    const slots = {
      // default: () => <div>匿名插槽</div>,
      state: (state: State) => <div>{state.name}</div>,
      list: (list: number[]) => list.map((item) => <div>{item}</div>),
    };
    return () => (
      <>
        {/* 引用组件, 使用插槽:v-slots={slots} */}
        <tsxDom v-slots={slots} />
      </>
    );
  },
});

测试效果如下:


在这里插入图片描述

总结

在 Vue3 中,我们可以选择使用模板语法、渲染函数或 JSX 语法来定义组件的模板。使用哪种方式取决于我们的个人喜好和项目的需求。渲染函数可以让我们更加灵活地定义组件的模板,并且可以让我们在编写组件时使用 JavaScript 的全部语言特性。JSX 语法是一种将 XML 语法嵌入到 JavaScript 中的语法,可以让我们更加灵活地定义组件的模板。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/561394.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AWD竞赛全流程解析

AWD(Attack With Defense&#xff0c;攻防兼备)是一个非常有意思的模式&#xff0c;你需要在一场比赛里要扮演攻击方和防守方&#xff0c;攻者得分&#xff0c;失守者会被扣分。也就是说&#xff0c;攻击别人的靶机可以获取 Flag 分数时&#xff0c;别人会被扣分&#xff0c;同…

汇编十三、串口

1、通信相关概念 (1)单工&#xff1a;只能接收或只能发送数据。 (2)半双工&#xff1a;既能发送数据&#xff0c;也能接收数据&#xff0c;但不能同时进行。 (3)全双工&#xff1a;可以同时进行发送和接收数据。 (4)单片机中常用的通信物理接口&#xff1a;I2C、SPI、USB、…

tushare单个股票过去五年的数据整理与预测

文章目录 前言&#xff1a;1. 导入相关包2. 数据预处理3. 构建模型3. 模型训练4. 检查数据6. 工作中其他常用包记录 前言&#xff1a; %md 在量化投资中&#xff0c;计算收益率是更常见的做法&#xff0c;而不是仅计算股价。计算收益率可以更好地反映投资的回报情况&#xff0c…

Pinctrl子系统_01_Pinctrl子系统介绍

本节介绍在Pinctrl子系统中&#xff0c;将会学习哪些内容。 Pinctrl作用 Pinctrl&#xff1a;Pin Controller&#xff0c;顾名思义&#xff0c;就是用来控制引脚的。 一个芯片有成百上千个引脚&#xff0c;这些引用要怎么配置&#xff0c;配置成什么功能&#xff0c;都是通P…

python+django网上书籍商城小说在线阅读分享下载系统k19is-vue

为了解决用户便捷地在网上购物以及下载文件&#xff0c;本文设计和开发了一个网页小说阅读系统。本系统是基于 B/S架构设计&#xff0c;Dango框架 &#xff0c;Python技术的前台页面设计与实现&#xff0c;使用Mysql数据库管理来完成系统的相关功能。主要实现了管理员与用户的注…

ETSI TS-关于SCP80

描述 GPC_UICC Configuration_v2.0.pdf 中: 规范 ts_102.225v12.1.0 Secured packet structure for UICC based applications.pdf spi kic kid编码 7 TCP/IP 的实现 在发送安全数据包之前&#xff0c;发送实体应使用定义的推送机制打开 TCP/IP 连接 在 ETSI TS 102 226 [9] …

【MATLAB第34期】基于MATLAB的2023年棕熊优化算法BOA优化LSTM时间序列预测模型 优势明显,注释详细,绘图丰富

【MATLAB第34期】基于MATLAB的2023年棕熊优化算法BOA优化LSTM时间序列预测模型 优势明显&#xff0c;注释详细&#xff0c;绘图丰富&#xff0c;适合小白 一、代码优势 1.使用2023年棕熊算法BOA优化LSTM超参数&#xff08;学习率&#xff0c;隐藏层节点&#xff0c;正则化系数…

chatgpt赋能Python-python_numpy倒序

Python Numpy倒序&#xff1a;简介、使用和优势 简介 Python是一门功能强大的编程语言&#xff0c;提供了众多开源库&#xff0c;其中Numpy是其中最流行的之一。Numpy是Python中的一个数值计算库&#xff0c;提供了一个高效的数组对象和相应的数学函数。它是数据科学家和机器…

Thonny-适合初学者小白的开箱即用的轻量级 Python IDE

如果你是一位Python初学者小白,那最适合Thonny它了&#xff0c;如果不是初学者&#xff0c;请选择PyDev和Pycharm。 Thonny是一款面向初学者小白的轻量级 IDE&#xff0c;可以让初学者更好更快的入门上手 Python&#xff0c;而不致于在环境上浪费过多的时间。 取之 Python&…

chatgpt赋能Python-python_purple

Python Purple: 一个高效的Python IDE Python Purple是Python程序员们最需要的工具之一。它是一款高效的Python IDE&#xff0c;允许用户轻松地创建&#xff0c;编辑和协作开发Python代码。本文将涉及Python Purple的一些重要特点以及它如何提高编码质量和提高生产力。 介绍P…

【利用AI让知识体系化】TypeScript目标:扩展JavaScript能力

I. TypeScript 简介 TypeScript 的起源 TypeScript 的起源是由微软公司开发&#xff0c;其首席架构师是 Anders Hejlsberg。Anders 是 Delphi 和 C# 语言的创始人&#xff0c;于2012年从微软发布了 TypeScript。 TypeScript 诞生的原因是为了解决 JavaScript 的一些缺点&…

Nginx(四)

部署LNMP架构动态网站WordPress LNMPLinuxNginxMySQLPhp 环境 192.168.29.141centos8Nginx1.24.0192.168.29.142centos8MySQL8.0.33192.168.29.143centos8Php7.2.24 关闭firewalld systemctl stop firewalld systemctl disable firewalld 关闭selinux setenforce 0 sed -ir…

网络原理(六):http 协议(上)

目录 HTTP 协议是什么 抓包工具 Fiddler 的下载 使用Fiddler HTTP 请求 (Request) HTTP 请求格式 首行 请求头&#xff08;Header&#xff09; Cookie HTTP 协议是什么 还是老样子&#xff0c;在讲解http 之前我们先来了解以下什么叫做 http 。 HTTP&#xff08;Hyp…

使用百度 PaddleOCR对身份证识别的简单处理

一&#xff1a;引言 本文才用百度的PaddleOCR对身份证进行识别的处理&#xff0c;由于直接使用并未进行对跟多数据集进行训练&#xff0c;当前的效果是对非少数民族的身份证识别率可以达到85%以上&#xff0c;同时要求身份证图片是正面且相对清晰。否则效果不理想&#xff0c;本…

基于java的时间管理系统的设计与实现

背景 要设计一个时间管理系统&#xff0c;通过这个系统能够满足时间管理的管理功能。系统的主要功能包括首页&#xff0c;个人中心&#xff0c;系统公告管理&#xff0c;用户管理&#xff0c;时间分类管理&#xff0c;事件数据管理&#xff0c;目标数据管理&#xff0c;用户日…

【系统软件】源码编译安装ZLIB——Could NOT find ZLIB(missing:ZLIB_LIBRARY ZLIB_INCLUDE_DIR

【系统软件】源码编译安装ZLIB——Could NOT find ZLIB(missing:ZLIB_LIBRARY ZLIB_INCLUDE_DIR 前言一、简介二、源码下载三、解压、构建四、编译五、安装六、安装成功后如下图七、如何使用zlib中的include 前言 今天原本打算源码编译安装protobuf&#xff0c;但是在构建项目…

图神经网络GNN GCN AlphaFold2 虚拟药物筛选和新药设计

文章目录 图神经网络1. Geometric Deep LearningRepresentation learning 表征学习机器学习的数据类型&#xff1a;序列、网格、图引出GNN 2. Graph Neural NetworksMachine Learning Lifecyclelearning graph is hardFeature Learning in GraphsWays to Analyze NetworksA Nai…

chatgpt赋能Python-python_plot标题

Python Plot 标题&#xff1a;如何让你的数据可视化更加引人注目 Python是数据科学和可视化领域中最受欢迎的编程语言之一。Python的可视化库让数据可视化变得非常容易、灵活和美观。 在创建一个数据可视化时&#xff0c;最重要的是让图表或图形作品的标题尽可能引人注目。这…

chatgpt赋能Python-python_plt_标题

Python plt&#xff1a;用Python创建出色的可视化图表 Python是一种广泛使用的高级编程语言&#xff0c;它被用于各种不同的领域&#xff0c;包括Web开发、数据科学、人工智能和计算机视觉等。Python拥有一个强大的生态系统&#xff0c;其中包括了大量的第三方库和工具&#x…

chatgpt赋能Python-python_property描述符

Python Property描述符&#xff1a;什么是Property&#xff1f; 介绍 在Python中&#xff0c;属性是一种非常强大的方式&#xff0c;在代码中隐藏数据并将其保护起来。我们可以使用属性来让代码更可读&#xff0c;更易于维护&#xff0c;并降低代码中的错误风险。 Python中&a…