vue3中h函数的使用

h函数是用于创建一个 vnodes ,它既可以用于创建原生元素,也可以创建组件,其渲染后的效果等同于使用模版语言来进行创建。

h函数的传参如下:

// 完整参数签名
function h(type: string | Component,props?: object | null,children?: Children | Slot | Slots
): VNode// 省略 props
function h(type: string | Component, children?: Children | Slot): VNode

第一个参数既可以是一个字符串 (用于原生元素) 也可以是一个 Vue 组件定义。第二个参数是要传递的 prop,第三个参数是子节点。

1、创建原生元素:

<script setup>
import { ref, h } from 'vue'const message = ref('在div里面渲染的值')
const comp = h('div',{style: {color: 'red'},onclick: ()=> {console.log('点击了原生元素div');}},message.value
)
</script><template><component :is="comp" />
</template>

这里给 div 传的 props 里有样式 style 和 事件 click ,在页面上的显示和点击了元素后效果和在模版语言中定义是一样的:

需要注意的是,我们这里的 comp 是一个 vnodes ,而 setup 函数并不是响应式的环境,所以当我们在 setup 函数中调用 h 函数来获取 vnodes 时,并没有绑定 message !只有在 render 函数 中执行才会绑定,所以我们可以定义一个h函数来返回给 comp,在渲染时,让component来帮我们调用。可以通过在 2s 后改变 message 的值来对比两种情况下页面渲染的变化:

const message = ref('在div里面渲染的值')
// 这样不会更新 message 的值
// const comp = h(
//   'div',
//   {
//     style: {
//       color: 'red'
//     },
//     onclick: ()=> {
//       console.log('点击了原生元素div');
//     }
//   },
//   message.value
// )// 这样可以更新 message 的值
const comp = () => h('div',{style: {color: 'red'},onclick: ()=> {console.log('点击了原生元素div');}},message.value
)setTimeout(()=> {message.value = '2s后更新了在div里面渲染的值'
}, 2000)

2、创建组件

这里使用的是一个批量注册的方式导入 HelloWorld 组件,Comp 是一个全局组件

全局组件的定义如下:

// component.jsimport { h } from 'vue'const modules = import.meta.glob('../components/*.vue')const components = {}
for(const path in modules) {const module = await modules[path]()const componentName = path.replace(/.*\/(.*)\.vue/, '$1')components[componentName] = module.default
}
const component = (props,{slots}) => {let name  =  props?.componentreturn h(components[name], { msg: '通过props传的msg',onFoo: (value)=> {console.log(value);},},slots)
}export default component

页面上导入是这样的:

容易混淆的地方是,Comp 是一个全局组件,通过传参 HelloWorld 渲染的才是 HelloWorld 组件,相当于外面套了一层,这里的 slots 其实是 Comp 组件的 slots , slots 传进了 HelloWorld 组件里,使用 HelloWolrd 组件里预留的插槽渲染的

<Comp component="HelloWorld">我是 Comp 组件的默认插槽<template #header><div>我是 Comp 组件的 header 插槽</div></template></Comp>

HelloWorld 组件中定义的:

<template><div><div>{{msg}}</div><div style="color: red">{{valueInProps}}</div><slot></slot><slot name="header" valueInSlot="我是 header 插槽里面的值"><div>我是 header 插槽里面的默认值,外部没有定义的话就是显示这个</div></slot></div>
</template>

那么 slots 里面到底是什么呢,我们直接打印一下看看:

我们可以看到 slots 其实是一个对象,键是插槽的名字,值其实就是一个 渲染函数 h(),

也可以这样写:

const component = (props,{slots}) => {let name  =  props?.componentconsole.log(slots);return h(components[name], { msg: '通过props传的msg',onFoo: (value)=> {console.log(value);},},slots.default())
}

使用作用域插槽的话:

const component = (props,{slots}) => {let name  =  props?.componentreturn h(components[name], { msg: '通过props传的msg',onFoo: (value)=> {console.log(value);},},slots.default('我是作用域插槽传的值'))
}<Comp component="HelloWorld"><template #default="scope"><div>{{scope}}</div></template></Comp>

如果我们不想帮 Comp 组件渲染的话,也可以自己来写:

const component = (props,{slots}) => {let name  =  props?.componentconsole.log(slots);return h(components[name], { msg: '通过props传的msg',onFoo: (value)=> {console.log(value);},},{default: ()=> h('div', '我是 HelloWorld 组件的默认插槽里面的值'),header: ()=> h('div', '我是 HelloWorld 组件的 header 插槽里面的值'),})
}

如果我们想渲染预留插槽里面的值(即作用域插槽),可以这样传:

<slot name="header" valueInSlot="我是 header 插槽里面的值"><div>我是 header 插槽里面的默认值,外部没有定义的话就是显示这个</div>
</slot>
const component = (props,{slots}) => {let name  =  props?.componentconsole.log(slots);return h(components[name], { msg: '通过props传的msg',onFoo: (value)=> {console.log(value);},},{default: ()=> h('div', '我是 HelloWorld 组件的默认插槽里面的值'),header: ({valueInSlot})=> h('div', '我是 HelloWorld 组件的 header 插槽里面的值,后面是预留插槽的值传递:'+valueInSlot),})
}

页面上的显示效果:

还有两个比较好理解的点,这里也补充一下:

在组件中传值,我们知道是用 props 来进行传递,所以在子组件中也是用 defineProps 来 接收值,而子组件想要传值给父组件的话,注意如果是传 foo 函数,则要用 onFoo 接受,例子如下:

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

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

相关文章

Docker配置国内镜像加速-2

Docker 官方镜像仓库&#xff08;如 Docker Hub&#xff09;可能由于网络原因&#xff0c;在某些地区或网络环境下下载速度较慢。使用镜像加速可以从距离用户更近、网络条件更好的镜像服务器获取镜像&#xff0c;从而显著提高下载速度&#xff0c;节省时间。 1.测试是否安装 d…

RedHat运维-Linux文本操作基础-AWK基础

你不用整理&#xff0c;跟着敲一遍&#xff0c;有个印象&#xff0c;然后把它保存到本地&#xff0c;以后要用再去看&#xff0c;如果有了新东西&#xff0c;你自个再添加。这是我参考同行的&#xff0c;只不过换成了问答的方式而已。不用背&#xff0c;就算是我自己亲自敲&…

MongoDB可视化工具全面指南

MongoDB可视化工具概述 1.1 什么是MongoDB可视化工具 MongoDB可视化工具是指那些通过图形用户界面&#xff08;GUI&#xff09;来管理和操作MongoDB数据库的软件工具。这些工具提供了一种直观的方式来执行数据库管理任务&#xff0c;如数据查询、索引管理、性能监控和数据导入…

探索Elastic Search:强大的开源搜索引擎,详解及使用

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 全文搜索属于最常见的需求&#xff0c;开源的 Elasticsearch &#xff08;以下简称 Elastic&#xff09;是目前全文搜索引…

三维点云目标识别对抗攻击研究综述

源自&#xff1a;电子与信息学报 作者&#xff1a;刘伟权 郑世均 郭宇 王程 注&#xff1a;若出现无法显示完全的情况&#xff0c;可 V 搜索“人工智能技术与咨询”查看完整文章 摘 要 当前&#xff0c;人工智能系统在诸多领域都取得了巨大的成功&#xff0c;其中深度学…

TensorRT-LLM加速框架的基本使用

TensorRT-LLM是英伟达发布的针对大模型的加速框架&#xff0c;TensorRT-LLM是TensorRT的延申。TensorRT-LLM的GitHub地址是 https://github.com/NVIDIA/TensorRT-LLM 这个框架在0.8版本有一个比较大的更新&#xff0c;原先的逻辑被统一了&#xff0c;所以早期的版本就不介绍了…

告别繁琐代码,迈向编程新境界—Java集合与泛型全面解析

在Java编程的征途中&#xff0c;集合&#xff08;Collection&#xff09;与泛型&#xff08;Generics&#xff09;是两大里程碑式的特性&#xff0c;它们不仅极大地提升了代码的灵活性和安全性&#xff0c;还帮助开发者简化了数据结构的处理逻辑&#xff0c;让编程之旅变得更加…

Hadoop 2.0 大家族(四)

目录 七、Flume&#xff08;一&#xff09;Flume简介&#xff08;二&#xff09;Flume入门 八、Mahout&#xff08;一&#xff09;Mahout简介&#xff08;二&#xff09;Mahout入门 七、Flume Flume是一个分布式高性能、高可靠的数据传输工具&#xff0c;它可用简单的方式将不同…

Langchain实战:构建高效的知识问答系统

引言 知识问答系统&#xff08;KQA&#xff09;是自然语言处理领域的核心技术之一&#xff0c;它能够帮助用户从大量数据中快速准确地检索到所需信息。知识问答系统成为了帮助个人和企业快速获取、筛选和处理信息的重要工具。它们在很多领域都发挥着重要作用&#xff0c;例如在…

《计算机英语》Unit 1 Computer Overview 计算机概述

期末试卷组成 1、选择20道 2、判断20道 3、词汇翻译&#xff08;单词词组&#xff0c;参照课后习题&#xff09; 4、翻译2道&#xff08;一道原题&#xff0c;参照作业&#xff09; SectionA About Computer 关于计算机 algorithm n. 算法 operate v.…

邦芒贴士:领导最反感下属这6种表现

在单位里面&#xff0c;如果在工作上出现了下面六种情况&#xff0c;就说明领导已经开始嫌弃你了&#xff0c;你的工作方式和方法一定要发生一些变化&#xff0c;及时的适应领导&#xff0c;如果再按部就班&#xff0c;那可就是真的犯傻。 1.安排事情时你总是排在第一个 安排任…

爬虫阶段思考

内容&#xff1a;写这篇文章是因为最近帮同学改了很多的爬虫代码&#xff0c;感触良多。 我用豆瓣为例&#xff0c;并不是不会用别的&#xff0c;而是这个我个人感觉最经典。然后还会写我遇到的一些问题以及解决方法。 首先&#xff0c;我们得先知道怎样爬取。我用的scrapy框…

2024广东省职业技能大赛云计算赛项实战——容器化部署MariaDB

容器化部署MariaDB 前言 今年比赛的容器化部署第一道考的好像就是这个&#xff0c;是往年国赛的题&#xff0c;直接给照搬过来了&#xff0c;今天就做做这道题&#xff1a; 编写Dockerfile构建镜像erp-mysql:v1.0&#xff0c;要求使用centos7.9.2009镜像作为基础镜像&#xf…

深入探讨Redis集群方案

一、什么是Redis集群 Redis集群&#xff08;Redis Cluster&#xff09;是Redis官方提供的分布式数据库解决方案&#xff0c;旨在通过将数据分散到多个节点上来实现水平扩展和高可用性。Redis集群提供了以下几个核心功能&#xff1a; 数据分片&#xff1a;将数据分布到多个节点…

Java变量命名规则

局部变量 使用驼峰命名以小写字母开头int myLocalVariable 实例变量&#xff08;成员变量&#xff09; 使用驼峰命名法小写字母开头myInstanceVariable 静态变量 使用驼峰命名法&#xff0c;以小写字母开头也可以使用大写蛇形命名法&#xff0c;全大写字母&#xff0c;单词…

护眼灯和普通台灯有什么区别?劣质护眼台灯宣传的三大套路

护眼灯和普通台灯有什么区别&#xff1f;围绕这一问题的讨论颇多。然而&#xff0c;真正体验过护眼台灯的人会深知&#xff0c;它与普通台灯之间的差异远非一般&#xff0c;涉及照明效果、色温调节、蓝光控制、闪烁问题及功能性设计等诸多层面。为了让更多人透彻理解这两者之间…

.locked勒索病毒详解 | 防御措施 | 恢复数据

引言 在数字化飞速发展的今天&#xff0c;我们享受着信息技术带来的便捷与高效&#xff0c;然而&#xff0c;网络安全问题也随之而来&#xff0c;且日益严重。其中&#xff0c;勒索病毒以其狡猾的传播方式和巨大的破坏性&#xff0c;成为了网络安全领域中的一大难题。.locked勒…

java实现多元预测(含代码)

1.多元预测介绍 多元预测(Multivariate Forecasting)是指使用多个变量或多个时间序列数据来预测未来的方法。与一元预测不同,多元预测考虑了多个因素对预测结果的影响,这些因素可以是同一时间序列的不同变量,也可以是来自不同数据源或不同领域的数据。 多元预测通常用于…

uniapp H5打开地图

manifest.json文件&#xff0c;源码视图找到H5添加下面内容 "h5" : {"sdkConfigs" : {"maps" : {"amap" : {"key" : "**********************","securityJsCode" : "****************************…

【Python】 使用 pandas 进行数据归一化

那年夏天我和你躲在 这一大片宁静的海 直到后来我们都还在 对这个世界充满期待 今年冬天你已经不在 我的心空出了一块 很高兴遇见你 让我终究明白 回忆比真实精彩 &#x1f3b5; 王心凌《那年夏天宁静的海》 数据归一化&#xff08;Normalization&#xf…