【vue】h 函数的使用

文章目录

    • 1. 引言
    • 2. h 函数
    • 3. h 函数的使用
      • 3.1 v-if
      • 3.2 v-for
      • 3.3 v-on
      • 3.4 组件
      • 3.5 渲染插槽
    • 4. h函数的使用场景
    • 参考链接

1. 引言

在绝大多数情况下,Vue 推荐使用模板语法来创建应用。然而在某些使用场景下,我们真的需要用到 JavaScript 完全的编程能力。这时渲染函数就派上用场了。

一般在 vue项目开发中,一般都是这样的结构

<template><div></div>
</template><script setup lang="ts"></script><style scoped></style>

但是有时候 不想写 template 想用 原生js 的方式 返回DOM 结构,就需要用到 h 函数

2. h 函数

h() 是 hyperscript 的简称——意思是“能生成 HTML (超文本标记语言) 的 JavaScript”。这个名字来源于许多虚拟 DOM 实现默认形成的约定。一个更准确的名称应该是 createVnode(),但当你需要多次使用渲染函数时,一个简短的名字会更省力。

// 完整参数签名
function h(type: string | Component,props?: object | null,children?: Children | Slot | Slots
): VNode// 省略 props
function h(type: string | Component, children?: Children | Slot): VNodetype Children = string | number | boolean | VNode | null | Children[]type Slot = () => Childrentype Slots = { [name: string]: Slot }

参数

  • type:必填,字符串/组件(字符串:一个html标签名
  • props:非必填,一个对象,内容包括了即将创建的节点的属性,例如 id、class、style等,节点的事件监听也是通过 props 参数进行传递,并且以 on 开头,以 onXxx 的格式进行书写,如 onInput、onClick 等。不写的话最好用 null占位
  • children:这个是子节点,也可以是数组

官方示例

import { h } from 'vue'// 除了 type 外,其他参数都是可选的
h('div')
h('div', { id: 'foo' })// attribute 和 property 都可以用于 prop
// Vue 会自动选择正确的方式来分配它
h('div', { class: 'bar', innerHTML: 'hello' })// class 与 style 可以像在模板中一样
// 用数组或对象的形式书写
h('div', { class: [foo, { bar }], style: { color: 'red' } })// 事件监听器应以 onXxx 的形式书写
h('div', { onClick: () => {} })// children 可以是一个字符串
h('div', { id: 'foo' }, 'hello')// 没有 prop 时可以省略不写
h('div', 'hello')
h('div', [h('span', 'hello')])// children 数组可以同时包含 vnode 和字符串
h('div', ['hello', h('span', 'hello')])

3. h 函数的使用

setup 版本

<script>
import { h } from "vue";
export default {setup() {return () => h("div", { class: "my-class" }, "Hello, World!");},
};
</script><style lang="less" scoped></style>

然后再 app.vue 中引入这个 组件,并使用

<template><div><h2>h 函数测试</h2><hello1 /><hr /></div>
</template><script setup>
import hello1 from "./views/01_h函数/hello.vue";
</script><style scoped></style>

在这里插入图片描述

然后就可以再界面上看到效果了

render 版本

<script>
import { h } from "vue";
export default {render() {return h("div", { class: "my-class" }, "Hello, World ddg!");},
};
</script><style lang="less" scoped></style>

3.1 v-if

在这里插入图片描述

<script>
import { h, ref } from "vue";
export default {setup() {// v-ifconst isShow = ref(true);return () => h("div", isShow.value ? "Hello, World true" : "Hello, World false");},
};
</script>

3.2 v-for

在这里插入图片描述

<script>
import { h, ref, render } from "vue";
export default {setup() {// -----------// v-forconst list = ref([{ name: "张三", age: 18 },{ name: "李四", age: 19 },{ name: "王五", age: 20 },]);return () =>h("div",list.value.map((item) => h("div", `姓名${item.name} 年龄${item.age}`)));},
};
</script>

注意:因为我们要展示 list 的数组的所有项, 所以第一个 h 函数 是需要有子节点的,这个参数是一个数组,所以要用 map , map 函数返回一个数组,这个数组每一项都是 h 函数

3.3 v-on

on 开头,并跟着大写字母的 props 会被当作事件监听器。比如,onClick 与模板中的 @click 等价。

在这里插入图片描述

<script>
import { h, ref, render } from "vue";
export default {setup() {// v-onconst handleBtnClick = () => {console.log("click");};return () =>h("button", { style: { color: "red", background: "pink", padding: "10px" }, onClick: handleBtnClick }, "提交");},
};
</script>

如若需要给事件传递参数可以这样写

      h("button",{style: { color: "red", background: "pink", padding: "10px" },onClick: () => handleBtnClick("ddg"),},"提交");

搭配for循环,实现点击这一行,触发点击事件

<script>
import { h, ref, render } from "vue";
export default {setup() {const handleBtnClick = (params) => {console.log("click", params);};const list = ref([{ name: "张三", age: 18 },{ name: "李四", age: 19 },{ name: "王五", age: 20 },]);// return () =>//   h("button", { style: { color: "red", background: "pink", padding: "10px" }, onClick: handleBtnClick }, "提交");return () =>h("button",list.value.map((item) =>h("div",{style: { color: "red", background: "pink", padding: "10px", marginBottom: "10px" },onClick: () => handleBtnClick(item),},`姓名${item.name} 年龄${item.age}`)));},
};
</script>

在这里插入图片描述

3.4 组件

在给组件创建 vnode 时,传递给 h() 函数的第一个参数应当是组件的定义。这意味着使用渲染函数时不再需要注册组件了 —— 可以直接使用导入的组件:

btn组件

<template><div><button class="rounded-lg bg-amber-500 p-[9px]">btn组件的按钮</button></div>
</template><script setup></script><style lang="less" scoped></style>

具体使用方式如下:

<script>
import { h, ref, render } from "vue";
import BtnCPN from "./btn.vue";
export default {setup() {return () => h(BtnCPN);},
};
</script>

在这里插入图片描述

能展示出来信息就是正常

3.5 渲染插槽

有时候,父组件使用这个组件的时候,也会传递过来插槽

子组件

<script>
import { h, ref, render } from "vue";
import BtnCPN from "./btn.vue";
export default {setup(props, { slots }) {// 渲染插槽return () => [h("div", "默认插槽的内容开始"),slots.default(),h("div", "默认插槽的内容结束"),h("div", "具名插槽 footer 的内容开始"),slots.footer(),h("div", "具名插槽 footer 的内容结束"),];},
};
</script><style lang="less" scoped></style>

父组件

<template><div><h2>h 函数测试</h2><div><hello1><template #default><p>我是父组件传递过来的默认插槽1</p><p>我是父组件传递过来的默认插槽2</p></template><template #footer><br /><p>我是父组件传递过来的footer插槽</p></template></hello1></div><hr /></div>
</template><script setup>
import { ref } from "vue";
import hello1 from "./views/01_h函数/hello.vue";
</script><style scoped></style>

在这里插入图片描述

渲染到界面上的效果就是这样

其实插槽的本质,就是父组件传递过来了一个对象,对象里面的key 是插槽的名称,值就是一个函数,再子组件可以调用这个函数进行渲染DOM

在这里插入图片描述

4. h函数的使用场景

  1. 用 h 函数 写一个组件
  2. componentis 属性可以搭配 h 函数使用
  3. 在一些 UI库中,也有一些使用场景,比如 Ant Design Vue 的表格组件的一些自定义项

在这里插入图片描述

<template><div><!-- <component :is="renderContainer" /> --><component :is="renderContainer('add')" /></div>
</template><script setup>
import { ref, h } from "vue";// const renderContainer = h("div", "我是H 函数渲染出来的!!!!");
const renderContainer = (type) => {if (type === "add") {return h("div", "我是H 函数渲染出来的!!!!" + "    新增");} else {return h("div", "我是H 函数渲染出来的!!!!");}
};
</script><style scoped></style>

在这里插入图片描述

文档上下面还有一些 属性可以用到 h 函数

参考链接

  • h 函数 vue2 官方文档
  • Ant Design Vue table 组件

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java开发代码规范文档

优质博文&#xff1a;IT-BLOG-CN 一、命令规范 包命名规范 包Package的作用是将功能相似或相关的类或者接口进行分组管理&#xff0c;便于类的定位和查找&#xff0c;同时也可以使用包来避免类名的冲突和访问控制&#xff0c;使代码更容易维护。通常&#xff0c;包命使用小写…

安卓中Room持久化库的使用

在Android开发中&#xff0c;Room是Google提供的一个持久化库&#xff0c;旨在为应用提供SQLite的抽象层&#xff0c;以简化数据库的访问和操作。相比直接使用SQLite&#xff0c;Room提供更清晰、更简洁的数据库访问机制。 1. Room的基础知识 1.1 引入Room依赖 首先&#xff…

GB/T 38082-2019 生物降解塑料购物袋检测

生物降解塑料购物袋是指以生物降解树脂为主要原料制得的&#xff0c;具有提携结构的&#xff0c;在销售、服务等场所用于盛装及携提商品的袋制品。 GB/T 38082-2019 生物降解塑料购物袋检测项目&#xff1a; 检测项目 测试标准 尺寸偏差 GB/T 38082 感官 GB/T 38082 提掉…

谷粒商城实战笔记-190-192商城业务-检索服务-面包屑导航

文章目录 一&#xff0c;什么是面包屑导航1&#xff0c;京东商城的面包屑2&#xff0c;面包屑是怎么产生的 二&#xff0c;面包屑导航的后台实现 这三节的主要内容是开发面包屑的前后端功能。 190-商城业务-检索服务-面包屑导航191-商城业务-检索服务-条件删除与URL编码问题192…

阿一网络安全实战演练之利用 REST URL 中的服务器端参数污染

所需知识 要解决这个实验室问题&#xff0c;您需要了解以下内容&#xff1a; 如何确定用户输入是否包含在服务器端的 URL 路径或查询字符串中。如何使用路径遍历序列尝试更改服务器端请求。如何查找 API 文档。 这些内容在我们的 API 测试学院主题中有涵盖。 进入实验室 研…

【Docker安装】Ubuntu系统下离线部署Docker环境教程

【Docker安装】Ubuntu系统下离线部署Docker环境教程 前言一、本次实践介绍1.1 本次实践规划1.2 本次实践简介二、检查本地环境2.1 检查操作系统版本2.2 检查内核版本2.3 更新软件源三、卸载Docker四、下载安装包4.1 创建目录4.2 官网下载五、部署Docker环境5.1 解压安装包5.2 复…

Web Image scr图片从后端API获取基本实现

因系统开发中需求&#xff0c;会有页面显示图片直接从后端获取后显示&#xff0c;代码如下&#xff1a; 后端&#xff1a; /*** 获取图片流* param response* param fileName*/RequestMapping(value"getImgStream",method RequestMethod.GET)public void getImgStr…

Yearning开源SQL审核平台本地Linux系统部署与远程登录语句审核

文章目录 前言1. Linux 部署Yearning2. 本地访问Yearning3. Linux 安装cpolar4. 配置Yearning公网访问地址5. 公网远程访问Yearning管理界面6. 固定Yearning公网地址 前言 本文主要介绍在 Linux 系统简单部署 Yearning 并结合 cpolar 内网穿透工具实现远程访问&#xff0c;破除…

Java基础入门15:算法、正则表达式、异常

算法&#xff08;选择排序、冒泡排序、二分查找&#xff09; 选择排序 每轮选择当前位置&#xff0c;开始找出后面的较小值与该位置交换。 选择排序的关键&#xff1a; 确定总共需要选择几轮&#xff1a;数组的长度-1。 控制每轮从以前位置为基准&#xff0c;与后面元素选择…

Typescript在AI产品中应用越来越广泛

AI产品中的应用 TypeScript 在 AI 产品中的应用逐渐增多&#xff0c;主要得益于其提供的类型安全、面向对象编程和模块化等特性&#xff0c;这些特性使得开发者能够构建可维护、可扩展和高性能的应用程序。 首先&#xff0c;TypeScript 作为 JavaScript 的超集&#xff0c;通…

15.基于session实现登录 前端项目部署

前端项目nginx部署 nginx配置文件 worker_processes 1;events {worker_connections 1024; }http {include mime.types;default_type application/json;sendfile on;keepalive_timeout 65;server {listen 8080;server_name localhost;# 指定前端项目所…

线性DP(动态规划)

文章目录 数字三角形思路代码 最长上升子序列1思路代码 最长公共子序列思路代码 其实和背包一样&#xff0c;都不固定&#xff0c;这种类型的题每一道题都需要自己从之前的经验中去摸索。 数字三角形 题目链接 思路 只能从左上或者右上走过来&#xff0c;用一个二维数组&am…

python-A+B again

[题目描述] 小理有一个非常简单的问题给你&#xff0c;给你两个整数 A 和 B&#xff0c;你的任务是计算 AB。输入格式&#xff1a; 输入共 2∗T1 行。 输入的第一行包含一个整数 T 表示测试实例的个数&#xff0c;然后 2∗T 行&#xff0c;分别表示 A 和 B 两个正整数。注意整数…

计算机网络面试题汇总

文章目录 计算机网络基础计算机网络体系结构(网络分层模型)OSI 七层模型是什么?每一层的作用是什么?TCP/IP 四层模型是什么?每一层的作用是什么?五层体系结构以及对应的协议为什么网络要分层,分层的好处?常见网络协议有哪些,每一层常见协议有哪些?应用层有哪些常见的协…

mysql5.7安装

1.创建一个software文件 2.先下载mysql的repo源 wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm 3安装源包 rpm -ivh mysql-community-release-el7-5.noarch.rpm 可能会报错 改成命令 rpm -ivh mysql-community-release-el7-5.noarch.rpm --nodeps…

目标检测 | yolov6 原理和介绍

前言&#xff1a;目标检测 | yolov5 原理和介绍 后续&#xff1a; 1.简介 YOLOv6是由美团视觉智能部研发的一款目标检测框架&#xff0c;专注于工业应用&#xff0c;致力于提供极致的检测精度和推理效率。相较于YOLOv4和YOLOv5&#xff0c;YOLOv6在网络结构方面进行了深入优化…

在LabVIEW中高效读取大型CSV文件的方法

当尝试使用“读取分隔的电子表格VI”从大型CSV文件&#xff08;数百MB&#xff09;中读取数据时&#xff0c;可能会遇到内存已满错误。这是因为该VI会一次性读取整个文件并将其转换为数值数组&#xff0c;导致占用大量内存。 解决方案 可以使用“从文本文件VI读取”来部分读取…

技术探索之android项目结构

在新建项目时会自动生成很多文件&#xff0c;需要知道项目结构&#xff0c;我们需要编辑的文件的位置&#xff1a; app: 项目的代码资源都在其中&#xff0c;是我们工作的核心目录 build &#xff1a; 编译生成文件。生成的apk就在build/outputs/apk/debug里。apk在虚拟机里就…

MySQL——内置函数

时间函数 select * from msg where date_add(sendtime, interval 2 minute) > now(); 理解&#xff1a; ------------------------------|-----------|-------------|------------------ 初始时间 now() 初始时间2min 字符串 length函数返回字符串长度&#xff0c;以字节为…

【docker】docker数据卷与网络部署服务

Docker 网络模式 选择网络模式 Host Mode (主机模式) 特点: 容器与宿主机共享网络命名空间操作: docker run --nethost ... Container Mode (容器模式) 特点: 容器与指定容器共享网络命名空间操作: docker run --netcontainer:<container-id-or-name> ... None Mode (无…