全网最通俗易懂的vue透传

概念:

Vue的透传是指在Vue组件中,使用特定的语法将父组件传递的属性或事件直接传递给子组件,实现了通过父组件传递数据或事件,再传递给子组件的功能。(传递给一个组件,却没有被该组件声明为 props 或 emits 的 attribute 或者 v-on 事件监听器。最常见的例子就是 class、style 和 id。)

在vue2中,透传可以通过v-bind="$attrs"和v-on="$listeners"指令来实现。v-bind指令可以将父组件的属性直接绑定到子组件上,而v-on指令可以将父组件的事件直接绑定到子组件上。

而vue3中,将v-bind和v-on进行了合并,我们只需要v-bind="$attrs"这一个指令就能把父组件的属性和方法都绑定到子组件上。

作用:透传能给我们组件复用或者二次封装第三方库带来极大的便捷。

下面让我们来看看vue3和vue2的透传的实际用法吧:

Vue3:

如何使用透传

父组件:直接传属性和方法

<template><div><ChildComponent name="John Doe" age="25" @handleData="handleData"/></div>
</template><script setup>
import ChildComponent from './ChildComponent.vue';const handleData = () => {// ...逻辑
}
</script>

子组件:使用 $attrs 或 useAttrs() 接收属性和方法

<template><div><!-- 在模板的表达式中直接用 $attrs 访问到 --><p>{{ $attrs.name }}</p><!-- 也可以用 useAttrs() 访问到 --><p>{{ attrs.age }}</p><button @click="$attrs.handleData">按钮1</button><button @click="onChange">按钮2</button></div>
</template><script setup>// 在js里 使用 useAttrs() API 来访问到import { useAttrs } from 'vue'const attrs = useAttrs()console.log(attrs)const onChange = () => {attrs.handleData()}
</script>

透传注意点

当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上。多个根节点的组件没有自动 attribute 透传行为。如果 $attrs 没有被显式绑定,或者没有被使用,将会抛出一个运行时警告。

把上面的子组件改一下,多一个div根节点:

下面是被透传的子组件

<template><div><h2>{{ name }}</h2></div>// 多了一个根节点(Vue3是支持多个根节点的)<div></div>
</template><script setup>defineProps({name: String})
</script>

此时报错表示:vue不知道要将 attribute 透传到哪里。

解决办法:如果 $attrs 被显式绑定 或者 使用,或者 两者同时出现,则不会有警告。

下面是解决后的代码:

<template><!-- 显示绑定 --><div v-bind="$attrs"><h2>{{ name }}</h2></div><div><!-- 使用 --><p>{{ $attrs.age }}</p></div>
</template><script setup>defineProps({name: String})
</script>

$attrs和显示绑定都能访问到属性和方法,但是它们的有些使用场景还是略有不同的,下面举个简单的栗子

修改一下父组件,添加一个id属性,子组件不变:

<template><div><ChildComponent id="custom-layout" name="John Doe" :age="25" /></div>
</template><script setup>import ChildComponent from './ChildComponent.vue'
</script>

这里可以看到的是,父组件传递下来的id属性,自动添加到了使用 v-bind 显示绑定的元素上了。而没有显示绑定的元素,是不会获得透传过来的id的

关闭透传

我们在使用vue2的透传的时候,可以设置inheritAttrs这个属性为false,来禁用透传,那么在Vue3中我们如何禁用透传呢?

其实从 3.3 开始我们就可以直接在 <script setup> 中使用 defineOptions来禁用透传。

我们需要明白,禁用透传只是禁用了自动透传,我们仍然可以通过显式$attrs访问到透传的属性和方法

<script setup>
defineOptions({inheritAttrs: false
})
// ...setup 逻辑
</script>

Vue2

vue2版本里,透传的属性可以使用this.$attrs获取到。在父级给组件绑定的事件可以用this.$listeners获取到。但是在vue3版本中,父组件透传来的属性都放在了$attrs里面,使用useAttrs()可以获取所有透传的属性和方法。

如何使用透传

$attrs:包含父作用域里除 class 和 style 除外的非 props 属性集合。通过 this.$attrs 获取父作用域中所有符合条件的属性集合,然后还要继续传给子组件内部的其他组件,就可以通过 v-bind="$attrs"

$listeners:包含父作用域里 .native 除外的监听事件集合。如果还要继续传给子组件内部的其他组件,就可以通过 v-on="$linteners"

// Parent.vue
<template><Child :name="name" age="28" @output='handlePrint'></Child>
</template
import Child from './child.vue'
export default{data(){return {name:"独求求败"}},components:{Child,},methods:{handlePrint(){console.log('name',this.name)}}
}
// Child.vue
<template>// 继续传给孙子组件<sun-child v-bind="$attrs" @bind="$linteners"></sun-child>
</template>
import SunChild from './SunChild.vue'
export default{components:{SunChild,},mounted(){console.log(this.$attrs)//{ name:"独求求败", age:28 }},
}
// sun-child.vue
<template>// 孙子组件<button @click="onClick">打印</button>//<button @click="$linteners.output">打印</button>  也可以直接调用父组件方法
</template>
export default{methods:{onClick(){this.$listeners.output()}}
}

vue2关闭透传

为了关闭透传,你可以在子组件中设置inheritAttrs:false

 <script>export default {inheritAttrs: false, // 禁用data(){return { ... }},methods:{ ... }};</script>

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

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

相关文章

【Javaer学习Python】 1、Django安装

安装 Python 和 PyCharm 的方法就略过了&#xff0c;附一个有效激活PyCharm的链接&#xff1a;https://www.quanxiaoha.com/pycharm-pojie/pycharm-pojie-20241.html 1、安装Django # 安装Django pip install Django# 查看当前版本 python -m django --version 5.0.62、创建项…

c++多态机制

多态 在 C 中&#xff0c;多态&#xff08;Polymorphism&#xff09;是一种面向对象编程的重要概念&#xff0c;它允许不同类的对象对同一消息做出不同的响应。具体来说&#xff0c;多态性允许基类的指针或引用在运行时指向派生类的对象&#xff0c;并且根据对象的实际类型来调…

算法_前缀和

DP34 【模板】前缀和 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别int n in.nextInt(),q in.ne…

Hadoop 3.4.0+HBase2.5.8+ZooKeeper3.8.4+Hive+Sqoop 分布式高可用集群部署安装 大数据系列二

创建服务器,参考 虚拟机创建服务器 节点名字节点IP系统版本master11192.168.50.11centos 8.5slave12192.168.50.12centos 8.5slave13192.168.50.13centos 8.5 1 下载组件 Hadoop:官网地址 Hbase:官网地址 ZooKeeper:官网下载 Hive:官网下载 Sqoop:官网下载 为方便同学…

一文带你快速了解GPT-4o!内含免费使用指南!

一、GPT-4o简介 北京时间5月14日&#xff0c;OpenAI举行春季发布会。OpenAI在活动中发布了新旗舰模型“GPT-4o”&#xff01;据OpenAI首席技术官穆里穆拉蒂&#xff08;Muri Murati&#xff09;介绍&#xff0c;GPT-4o在继承GPT-4强大智能的同时&#xff0c;进一步提升了文本、…

深入理解K8S【安全认证机制kubectlconfig】

深入理解K8S【安全认证机制】 1 核心概念 1.1 安全体系 对于大型系统来说&#xff0c;对业务的权限、网络的安全认证是必不可少的。 对于linux系统来说&#xff0c;用户和组、文件权限、SELinux、防火墙、pam、sudo等&#xff0c;究其核心的目的都是为了保证系统是安全的。 …

LeetCode1657确定两个字符串是否接近

题目描述 如果可以使用以下操作从一个字符串得到另一个字符串&#xff0c;则认为两个字符串 接近 &#xff1a; 操作 1&#xff1a;交换任意两个 现有 字符。例如&#xff0c;abcde -> aecdb操作 2&#xff1a;将一个 现有 字符的每次出现转换为另一个 现有 字符&#xff0…

【计算机毕业设计】ssm绿色农产品推广应用网站

21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的 重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存储达到…

分布式系统的一致性与共识算法(二)

Consitency 背景 如买最后一张车票&#xff0c;两个售票处分别通过某种方式确认过这张票的存在。这时&#xff0c;两家售票处几乎同时分别来了一个乘客要买这张票&#xff0c;从各自"观察"看来&#xff0c;自己一方的乘客都是先到的&#xff0c;这种情况下&#xf…

Docker常用镜像安装

1. mysql 1.1 安装 获取镜像 docker pull mysql:8.0.30创建文件挂载目录 创建容器并运行 docker run -p 3306:3306 --name mysql8 \ -v /home/docker/mysql8/log:/var/log/mysql \ -v /home/docker/mysql8/data:/var/lib/mysql \ -v /home/docker/mysql8/mysql-files:/va…

<网络安全>《83 微课堂<国家数据要素总体框架>》

1 总体框架 国家数据要素化总体框架由“六横两纵”共八个关键环节构成。 2 国家数据基础设施&#xff08;NDI&#xff09; 最底部第一层是国家数据基础设施&#xff08;NDI&#xff09;。国家数据基础设施&#xff08;NDI&#xff09;是经济社会进入数据要素化发展新阶段后新…

ASP.NET银行大厅自助信息系统的开发与实现

摘 要 本毕业设计在基于银行业务大厅现有业务的基础上&#xff0c;针对自助银行的概念和其独有特点&#xff0c;通过.NETSQL技术&#xff0c;开发一个简单的银行大厅自助信息系统&#xff0c;完成一些自助银行的业务需求如帐户信息查询、帐户挂失、自助交费、留言、新闻查询…