vue 函数式(编程式) render (functional:true)

news2024/9/21 16:19:38

文章目录

    • 一、文档
    • 二、区别
    • 三、使用
    • h函数的参数解释:
    • 参数一:
        • 使用导入的组件名
    • 参数二:
        • 绑定css
        • 绑定事件
        • 往组件里面传递参数
        • 动态绑定值props
        • 动态绑定值data
        • functional:true到底是做什么的?
        • 动态绑定props 非functional:true版本
    • 参数三:
        • 参数为文本时
        • 当参数为数组时
        • 当参数里面设置插槽时
        • 如何给插槽填写默认值
        • 具名插槽

一、文档

(官方文档)
官网地址:https://cn.vuejs.org/api/options-rendering#render
渲染机制说明:https://cn.vuejs.org/guide/extras/rendering-mechanism
渲染函数说明:https://cn.vuejs.org/guide/extras/render-function
(个人参考文档)
如何使用:https://blog.csdn.net/ccattempt/article/details/120481481
render介绍:https://blog.csdn.net/w807139809/article/details/122106086

二、区别

同常规的vue有什么区别:
1、同等条件下,render编程式渲染速度优异,因为编程式跳过了三个阶段的转化(parser -> transform -> generate)
2、编程式缺少了传统template模板编写形式的便捷手段(通俗的讲:用起来不顺手,因为js需要与标签混着写)
3、语法完全不一样(render缺少全局this、标签使用变量由{{}}转为了单{}、、、)

三、使用

<script>
	export default {
		name: "patientSourceImage",
		functional: true,
		render(h, context) {
		//render需要返回一个vNode节点
		//h函数 :参数一原生标签名、或者引入的组件名
		// 参数二:为创建的标签绑定的属性内容,可以是class类名、可以是事件、自定义属性......
		// 参数三:可以是字符串Text文本或者是h函数构建的对象再者可以是有插槽的对象。
		//context 由于没有全局的this,因此出现了context,context是一个对象,里面有很多属性如props、data......
		return h('div',{class:"contain"},[<p>render渲染</p>])
		}
	};
</script>

h函数的参数解释:

参数一:

<script>
	export default {
		name: "patientSourceImage",
		functional: true,
		render(h, context) {
		//h函数 :参数一原生标签名、或者引入的组件名
		//div,就是普通的div元素标签名
		
		return h('div',{class:"contain"},[<p>render渲染</p>])
		}
	};
</script>

使用导入的组件名

<script>
	import HelloWorld from "./components/HelloWorld";
	export default {
		name: "patientSourceImage",
		functional: true,
		components: {
			HelloWorld,
		},
		render(h, context) {
			//HelloWorld ,导入的组件,没有引号,需要先进行组件注册
			return h(HelloWorld, { class: "contain" }, [<p>render渲染</p>]);
		},
	};
</script>

参数二:

绑定css

<script>
	export default {
		name: "patientSourceImage",
		functional: true,
		render(h, context) {
			return h(
				"div",
				//绑定css可以通过类名。或者style属性
				{ class: "contain", style: { background: "black", color: "white" } },
				[<p>render渲染</p>]
			);
		},
	};
</script>

绑定事件

<script>
	export default {
		name: "patientSourceImage",
		data: function () {
			return {
				tt: "前端吴彦祖是tjq",
			};
		},
		functional: true,
		render: function (h, context) {
			return h(
				"div",
				{
					class: "contain",
					style: {
						background: "black",
						color: "white",
					},
					//绑定事件通过on来进行绑定,
					//~ 前缀,表示函数只执行一次
					on: {
						"~click": () => {
							alert("缓存清理成功");
						},

						mouseout: (e) => {
							console.log("鼠标移出", e);
						},
					},
				},
				[<p>{111}</p>]
			);
		},
	};
</script>

往组件里面传递参数

<script>
	import HelloWorld from "./components/HelloWorld.vue"
	export default {
		name: "patientSourceImage",
		data: function () {
			return {
				tt: "前端吴彦祖是tjq",
			};
		},
		components: {
			HelloWorld,
		},
		functional: true,
		render: function (h, context) {
			const name = "tjq";
			return h(
				HelloWorld,
				{
					class: "contain",
					props: {
						name: name,
					},
				},
				[<p>吴彦祖</p>]
			);
		},
	};
</script>

动态绑定值props

app.vue文件



<template>
	<div>
		<button @click="age++">age++</button>
		<HelloWorld :age="age"></HelloWorld>
	</div>
</template>
<script>
	import HelloWorld from "./components/HelloWorld.vue";
	export default {
		data() {
			return {
				age: 1,
			};
		},
		
		components: {
			HelloWorld,
		},
	};
</script>
<style scoped>
</style>

HelloWorld.vue

<script>
	export default {
		name: "HelloWorld",
		props: ["age"],
		data: function () {
			return {
				tt: "前端吴彦祖是tjq",
			};
		},
		functional: true,
		//解构赋值 context,取出props
		render: function (h, { props }) {
			return h(
				"div",
				{
					class: "contain",
					style: {
						background: "black",
						color: "white",
					},
				},
				[<p>{props.age}</p>]
			);
		},
	};
</script>

动态绑定值data

这里我们需要去掉functional:true

<script>
	export default {
		name: "helloworld",
		data() {
			return {
				name: "tjq",
				age: 18,
			};
		},
		render(h) {
			return h(
				"div",
				{
					on: {
						click: () => {
							this.age++; //或者使用this.$data.age $data是data的一个映射,同样的也有props的映射$props......
						},
					},
				},
				`name:${this.$data.name},age${this.age}`
			);
		},
	};
</script>

functional:true到底是做什么的?

在 Vue 中,当组件设置 functional: true 时,组件函数将被视为无状态函数组件。无状态函数组件没有实例,没有响应式数据,并且不支持实例方法和生命周期钩子函数。由于它们没有实例上下文,因此无法直接访问插槽。
因此我们上面的所有示例,可以把functional: true去掉,去掉之后我们的render函数缺少了context这一参数,但同时我们也可以调用this变量
举个例子:

动态绑定props 非functional:true版本

app.vue文件



<template>
	<div>
		<button @click="age++">age++</button>
		<HelloWorld :age="age"></HelloWorld>
	</div>
</template>
<script>
	import HelloWorld from "./components/HelloWorld.vue";
	export default {
		data() {
			return {
				age: 1,
			};
		},
		
		components: {
			HelloWorld,
		},
	};
</script>
<style scoped>
</style>

helloworld.vue文件

<script>
	export default {
		name: "HelloWorld",
		props: ["age"],
		render: function (h) {
		// render: function (h ,context) { 之前我们是content.props.age来进行获取的
			//现在多了this,我们直接this.$props即可
			console.log(this.$props.age);
			return h("div", {}, [<p>{this.$props.age}</p>]);
		},
	};
</script>

参数三:

<script>
	export default {
		name: "patientSourceImage",
		functional: true,
		render(h, context) {
			return h(
				"div",
				//参数三,可以是一段文本,也可以是一个数组
				{},
				[<p>render渲染</p>]
			);
		},
	};
</script>

参数为文本时

<script>
	export default {
		name: "patientSourceImage",
		functional: true,
		render(h, context) {
			return h(
				"div",
				{},
				'啦啦啦,我是前端吴彦祖'
			);
		},
	};
</script>

在这里插入图片描述

当参数为数组时

<script>
	export default {
		name: "patientSourceImage",
		functional: true,
		render(h, context) {
			return h("div", {}, [<em>我是前端吴彦祖</em>,<br/>, `<em>我是前端吴彦祖</em>`]);
		},
	};
</script>

在这里插入图片描述

当参数里面设置插槽时

上诉也提到,functional: true为无状态函数,没有插槽,因此用到插槽我们同样不能使用functional: true
app.vue文件

<template>
	<div>
		<HelloWorld >
            <p>我是前端吴彦祖</p>
            <em>我是前端吴彦祖</em>
        </HelloWorld>
	</div>
</template>
<script>
	import HelloWorld from "./components/HelloWorld.vue";
	export default {
		data() {
			return {
				age: 1,
			};
		},
		
		components: {
			HelloWorld,
		},
	};
</script>
<style scoped>
</style>

helloworld.vue文件

<script>
	export default {
		name: "helloworld",
		render(h) {
			return h(
				"div",
				{ class: "menuBox" },
				this.$scopedSlots.default()
			);
		},
	};
</script>

在这里插入图片描述

如何给插槽填写默认值

app.vue文件

<template>
	<div>
		<HelloWorld >
            <p>我是前端吴彦祖</p>
            <em>我是前端吴彦祖</em>
        </HelloWorld>
        <!-- 没写默认插槽,会使用默认值 -->
        <p>下面的用默认值<p/>
        <HelloWorld >
        </HelloWorld>
	</div>
</template>
<script>
	import HelloWorld from "./components/HelloWorld.vue";
	export default {
		data() {
			return {
				age: 1,
			};
		},
		
		components: {
			HelloWorld,
		},
	};
</script>
<style scoped>
</style>

helloworld.vue

<script>
	export default {
		name: "helloworld",
		data() {
			return {
				name: "tjq",
			};
		},
		render(h) {
			const scopedSlotFn = this.$scopedSlots.default;
			//scopedSlotFn为undefined时表示并没有传递插槽
			//如果传递了, scopedSlotFn会是一个函数,该函数的返回值是对应的插槽组件
			if (scopedSlotFn) {
				const slotVNode = scopedSlotFn();
				return h("div", [slotVNode]);
			}
			return h("div", {}, ["默认的插槽内容"]);
		},
	};
</script>

在这里插入图片描述

具名插槽

helloworld.vue文件

<script>
	export default {
		name: "helloworld",
		data() {
			return {
				name: "tjq",
			};
		},
		render(h) {
			//slots表示所有接收到的插槽
			const slots = this.$slots;
			//提前预设的插槽,default是默认插槽
			const slots_arr = ["default", "title"];
			const slot_key = Object.keys(slots).map((item) =>
				slots_arr.includes(item) ? slots[item] : null
			);
			if (slot_key.length) {
				return h("div", [...slot_key]);
			}

			return h("div", {}, ["默认的插槽内容"]);
		},
	};
</script>



或者使用下面这种写法
helloworld文件

<script>
	export default {
		name: "helloworld",
		data() {
			return {
				name: "tjq",
			};
		},
		render(h) {
		//预设哪个插槽就this.$slots[预设的插槽名]
			return h("div", {}, [this.$slots.title, this.$slots.default]);
		},
	};

app.vue

<template>
	<div>
		<HelloWorld >
            <p>我是前端吴彦祖</p>
            <em slot="title">标题插槽</em>
            <em slot="detail">没有接受这个插槽</em>
        </HelloWorld>
	</div>
</template>
<script>
	import HelloWorld from "./components/HelloWorld.vue";
	export default {
		data() {
			return {
				age: 1,
			};
		},
		
		components: {
			HelloWorld,
		},
	};
</script>
<style scoped>
</style>

在这里插入图片描述

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

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

相关文章

JSONUtil.toJsonStr 时间变成了时间戳

问题描述 我的接口是以Date来接收日期的&#xff0c;然后我在拿到这个对象参数后&#xff0c;通过hutool当中的JSONUtil.toJsonStr将其序列化成json字符串&#xff0c;然后存储到数据库。然后存储到数据库当中发现这个字段是时间戳。 DateTimeFormat和JsonFormat 前者是控制 请…

动态规划详解Python

动态规划 动态规划&#xff08;Dynamic Programming&#xff09;是一种用于解决复杂问题的算法设计方法。它通常用于优化问题&#xff0c;其中问题可以被分解成一系列重叠子问题&#xff0c;通过存储并重复使用已经解决过的子问题的解&#xff0c;可以避免重复计算&#xff0c…

区块链的简单认识

比特币作为区块链的应用&#xff0c;让区块链广为人知&#xff0c;如果比特币作为第一代区块链&#xff0c;则以太坊则称为第二代区块链。我们知道&#xff0c;区块链的最主要目的就是去中心化&#xff0c;比特币则成为了decentralized currency&#xff0c;去中心化在技术上依…

跨注册中心服务同步实践

博主介绍&#xff1a;✌全网粉丝4W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战、定制、远程&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面…

助你丝滑过度到 Vue3 创建工程 ②③

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; VUE3~TS &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &#x1f449;…

同城跑腿独立版小程序 码科跑腿小程序 支持用户端 骑手端

是独立版哦&#xff0c;不是微擎的 搭建有点复杂&#xff0c;只要一步错就会导致骑手端来单没有声音提示. 多的也不介绍了&#xff0c;不知道的朋友可以百度一下码科跑腿就知道了&#xff01;

机器学习李宏毅学习笔记33

文章目录 前言一、神经网络压缩二、Network pruning----一种network compression技术1.移除不同单位的区别2.大乐透假说 总结 前言 神经网络压缩&#xff08;一&#xff09; 类神经网络剪枝&#xff08;pruning&#xff09; 一、神经网络压缩 简化模型&#xff0c;用比较少的…

netty_客户端和服务端,定长数据输出案例

步骤1&#xff1a;创建server import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channe…

美团小游戏守卫羊村玩法介绍和游戏漏洞

序言 这款游戏是一个解压小游戏&#xff0c;是我在闲暇时发现的&#xff0c;然后就使用它来度过无聊的碎片化时间。这是一款传统的塔防类游戏&#xff0c;建议大家可以试试&#xff0c;玩法有很多种&#xff0c;当然它的游戏优化还是不太行&#xff0c;建议多优化优化。 玩法…

十二、Jenkins构建完成发送飞书消息通知

十二、Jenkins构建完成发送飞书消息通知 1. 创建一个飞书webhook 群机器人 得到一个飞书webhook地址&#xff1a; https://open.feishu.cn/open-apis/bot/v2/hook/2d0b6357-333a-4077-9fcd-61e361a3e51e 2. send_notice.py上传到jenkins服务器目录 send_notice.py最后面 代码…

移动硬盘中安装Ubuntu 20.04系统——立省99%的问题

目录 关于我为什么要在移动硬盘中装系统 准备工作 开始安装 磁盘分区 创建虚拟机 关于我为什么要在移动硬盘中装系统 (6条消息) 笔记本安装双系统ubuntu时踩的坑——戴尔_放风筝的猪的博客-CSDN博客 准备工作 1.移动硬盘 2.Ubuntu镜像 3.VMware虚拟机 Ubuntu镜像可以从…

Linux查看版本号,lsb_releasa过时了,得用uname -a

突然想查看Linux版本号了 然后终端输入lsb_release,结果给我报错No LSB modules are available. 然后网上一查发现Linux 版本是 Ubuntu 11.1.0 或更高版本,则 lsb_release 命令可能已经被弃用。 这是由于 lsb-release 命令已经不再维护,并且由于安全问题而被移除。 因此,对于…

基于matlab使用迭代最近点算法组合多个点云以重建三维场景(附源码)

一、前言 此示例演示如何使用迭代最近点 &#xff08;ICP&#xff09; 算法组合多个点云以重建三维场景。 此示例将使用 Kinect 捕获的点云集合拼接在一起&#xff0c;以构建场景的更大三维视图。该示例将 ICP 应用于两个连续的点云。这种类型的重建可用于开发对象的 3D 模型…

关于Realvnc远程Aero效果异常解决方案

默认安装realvnc server后&#xff0c;远程时如下图所示&#xff0c;windows areo效果丢失且提示“配色方案已经更改为windows 7 basic”&#xff1b; 解决方案&#xff1a;取消勾选&#xff0c;user mirror drive to capture screen 在远程时效果恢复如下&#xff1a;

类中的函数重载

函数重载回顾 函数重载的本质为相互独立的不同函数 C 中通过函数名和函数参数确定函数调用 无法直接通过函数名得到重载函数的入口地址 函数重载必然发生在同一个作用域中 类中的成员函数可以进行重载 构造函数的重载 普通成员函数的重载 静态成员函数的重载 问题 全局…

微软发布「升级版」多模态大模型 Kosmos-2!新增局部理解能力,解锁实体级交互

夕小瑶科技说 原创 作者 | 小戏、ZenMoore 三个多月前&#xff0c;微软亚洲研究院在论文《Language Is Not All You Need: Aligning Perception with Language Models》中发布了一个强大的多模态大模型 Kosmos-1&#xff0c;成功将感知与语言对齐&#xff0c;在 ChatGPT 的多…

C#串口通信从入门到精通(26)——多个串口多个线程发送数据和接收数据

前言 我们在开发串口程序的过程中有时候会遇到多个串口,并且多个串口也需要在多个线程进行操作,本文就来讲解如何实现多个串口在多线程下的安全发送与接收。 1、操作界面与测试过程 我们首先使用虚拟串口助手虚拟COM1、COM2这一对串口;COM3、COM4这一对串口,然后使用代码…

小黑子—MySQL数据库:第二章 - 进阶篇

MySQL数据库入门2.0 MySQL进阶篇1. MySQL体系结构2. 存储引擎2.1 InnoDB 存储引擎2.2 MyISAM 存储引擎2.3 Memory 存储引擎2.4 存储引擎选择2.5 MySQL安装Linux版本 3. 索引3.1 索引结构3.1.1 B tree3.1.2 B tree3.1.3 Hash 3.2 索引分类3.2.1 思考题 3.3 索引语法3.4 SQL性能分…

docker jenkins 安装

使用 Docker 安装 Jenkins 并实现项目自动化部署-阿里云开发者社区 (aliyun.com)https://developer.aliyun.com/article/892646#slide-1运行镜像命令&#xff1a; docker run \ --name jenkins \ -p 8080:8080 \ -p 50000:50000 \ -d \ -v /home/admin/SoftWare/volume/jenkin…

CSS 内容盒子

这章比较重要&#xff0c;会不断更新❗ 文章目录 内容盒子开发者工具的使用border 边框padding 内边距margin 外边距盒子整体尺寸元素默认样式与CSS重置元素分类块级标记行级标记行内块标记 display样式内容溢出裁剪掉溢出部分滚动条 圆角边框 border-radius 内容盒子 提示&am…