vue3 $attrs和inheritAttrs的用法说明
作者:hao_0413 发布时间:2024-04-26 17:39:08
$attrs和inheritAttrs用法
$attrs
属性解释:包含了父作用域中不作为组件 props 或自定义事件的 attribute 绑定和事件。当一个组件没有声明任何prop 时,这里会包含所有父作用域的绑定,并且可以通过 v-bind="$attrs" 传入内部组件——这在创建高阶的组件时会非常有用。inheritAttrs
属性解释:如果你不希望组件的根元素继承特性,你可以在组件的选项中设置 inheritAttrs: false
可能不是很好理解,我们可以举个例子来验证一下。
在父组件app.vue中
<template>
<div>
<MyInput type="text" placeholder="输入用户名" v-model="state.text" />
<MyInput type="password" placeholder="输入密码" v-model="state.pass" />
</div>
</template>
<script setup>
import MyInput from "@/components/myInput.vue";
import { reactive } from "vue";
const state = reactive({
text: "",
pass: "",
});
</script>
子组件 myInput.vue 设置 inheritAttrs: true(默认)
<template>
<div class="input">
<input v-bind="$attrs" v-model="modelValue" />
</div>
</template>
<script>
export default {
props: {
modelValue: [String, Number],
},
};
</script>
子组件 myInput.vue 设置 inheritAttrs: false
<template>
<div class="input">
<input v-bind="$attrs" v-model="modelValue"/>
</div>
</template>
<script>
export default {
inheritAttrs: false,
props: {
modelValue: [String, Number],
},
};
</script>
小结:
由上述例子可以看出,子组件的props中未注册父组件传递过来的属性。
当设置inheritAttrs:true时,子组件的顶层标签元素中会渲染出父组件传递过来的属性(例如:type="text"等)
当设置inheritAttrs: false时,子组件的顶层标签元素中不会渲染出父组件传递过来的属性
不管inheritAttrs为true或者false,子组件中都能通过$attrs属性获取到父组件中传递过来的属性。
$attrs和inheritAttrs实例
官网的文档简短而又不清晰,实在是看不懂,只好自己找代码验证来看看是什么意思:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.1.5/vue.global.js"></script>
</head>
<body>
<div id="app">
<father :v1="'value1'" :v2="'value2'" :v3="'value3'"></father>
</div>
</body>
</html>
<script>
const app = Vue.createApp({
data() {
return {}
},
})
app.component('father', {
// inheritAttrs: false,
props: ['v1'],
template: ` <div><p>v1 is {{v1}}</p>
<son v-bind='$attrs' :some="1"></son>
</div>`,
created() {
console.log('father:', this.$attrs)
}
})
app.component('son', {
// inheritAttrs: false,
props: ['v2'],
template: `<div><p>v2 is {{v2}}</p>
<grandSon v-bind='$attrs'></grandSon>
</div>`,
created() {
console.log('son:', this.$attrs)
}
})
app.component('grandSon', {
props: ['v3'],
template: `<p>v3 is {{v3}}</p>`,
created() {
console.log('grandSon:', this.$attrs)
}
})
app.mount('#app')
</script>
页面显示的结果:
v1 is value1
v2 is value2
v3 is value3
页面源代码:
<div id="app" data-v-app="">
<div v2="value2" v3="value3"> <!-- 这是father -->
<p>v1 is value1</p>
<div v3="value3" some="1"> <!-- 这是 son-->
<p>v2 is value2</p>
<p some="1">v3 is value3</p> <!-- 这是 grandSon -->
</div>
</div>
</div>
控制台打印是当前组件的$attrs:
father: Proxy {v2: "value2", v3: "value3", __vInternal: 1}
son: Proxy {v3: "value3", some: 1, __vInternal: 1}
grandSon: Proxy {some: 1, __vInternal: 1}
首选,father组件被传入了3个值,但是实际使用props接收的只有v1,v2和v3作为attributes在DOM里面渲染了。
上图的devtool 也可以说明,另外就是控制台也同时证明了。
同样son组件只是接收v2作为prop:
grandSon组件只是接收v3作为prop
father prop:v1,attributes: v2,v3
son prop:v2 ,attributes:v3,some
grandSon prop:v3,,attributes: some
发现无论是father传入的3个值v1,v2,v3还是son又传入的值':some=1',
只要不被prop传入下一层组件,那么一定是在下一层组件的$attrs,也就是说不被作为prop的值会传入下一个组件作为attrs的一员。一个组件的attrs由父组件传递以及自己自带的组合而成。
上面说的是$attrs,那么inheritAttrs则说的是attrs继承,这里的继承是控制DOM渲染,不继承也就是不渲染了,但是实际还是存在这个attrs的。
`inheritAttrs`属性默认是true,所以能看到上面的结论,attrs会往下传,当设置为false的时候就不会在DOM渲染从上一层继承来的attrs。
修改一下代码:
app.component('father', {
inheritAttrs: false, // 不继承
props: ['v1'],
template: ` <div><p>v1 is {{v1}}</p>
<son v-bind='$attrs' :some="1"></son>
</div>`,
created() {
console.log('father:', this.$attrs)
}
})
father组件这不继承attrs,控制台的打印没变:
father: Proxy {v2: "value2", v3: "value3", __vInternal: 1}
son: Proxy {v3: "value3", some: 1, __vInternal: 1}
grandSon: Proxy {some: 1, __vInternal: 1}
devtool这里依然可以看到attrs
但是看源代码:
<div id="app" data-v-app="">
<div> <!-- 这里是 father --> <!-- 看这行 -->
<p>v1 is value1</p>
<div v3="value3" some="1"> <!-- 这里是 son-->
<p>v2 is value2</p>
<p some="1">v3 is value3</p> <!-- 这里是 grandSon-->
</div>
</div>
</div>
DOM渲染里面的v2,v3 attrs都不存在了。
所以综合总结一下:
$attrs就是给组件传值排除了作为prop的那部分(比如father的v2,v3),包括了(class,id)inheritAttrs只是用来控制attrs是否在DOM中渲染。
来源:https://blog.csdn.net/weixin_41977619/article/details/116597022


猜你喜欢
- 今天碰到这个极度郁闷的报错,搞了大半下午,才发现是ie的问题,忍不住大骂。例子是这样的:页面中有多处能出发菜单,并且菜单出现在触发点的旁边,
- 前言Golang 是一种并发友好的语言,使用 goroutines 和 channels 可以轻松地实现多线程爬虫。具体地说,实现的是多协程
- 推荐阅读:JS iFrame加载慢怎么解决在项目中经常要动态添加iframe,然后再对添加的iframe进行相关操作,而往往iframe还没
- Talk Is Cheap和Java一样,python也提供了对于checked exception和unchecked exception
- llama Index是什么《零开始带你入门人工智能系列》第一篇:还用什么chatpdf,让llama Index 帮你训练pdf。Llam
- 运行下面的代码你就可以清楚的认识到这两个参数的用法,innerText只能动态的改变指定元素内的文本内容,而innerHTML则不仅仅可以改
- 1.1 ID定位HTML Tag 的 id 属性值是唯一的,故不存在根据 id 定位多个元素的情况。下面以在百度首页搜索框输入文本
- 说明:几个简单的基本的sql语句 选择:select * from table1 where 范围 插入:insert into table
- 1. select模块针对select,要先理解其他几个概念:文件描述符:文件描述符在形式上是一个非负整数。实际上,它是一个索引
- 1.消息丢失1.生产者发送失败所有消息队列都可能发生的问题生产者发送消息后,队列未成功接收(网络原因或其他)而生产者不知情,消息丢失生产者发
- 创建测试数据:import pandas as pdimport numpy as np#Create a DataFramedf1 = {
- 废话不多说了,直接给大家贴js代码了,具体代码如下所示:<!DOCTYPE html><html><head&
- SQL语句参考及记录集对象详解1. ASP与Access数据库连接:2. ASP与SQL数据库连接:建立记录集对象:set rs=serve
- 在技术问答中看到一个这样的问题,感觉相对比较常见,就单开一篇文章写下来。从纯文本格式文件 “file_in”中读取数据,格式如下:需要输出成
- 一、操作redisredis是一个key-value存储系统,value的类型包括string(字符串),list(链表),set(集合),
- 查询速度慢的原因很多,常见如下几种:1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)2.I/O吞吐量小,形成了瓶颈效
- 网上有很多提供在线按钮制作、文字标题制作、Logo制作服务的网站,它们可以非常方便了让大家轻松的获得效果出色的各类图标型的图片,下面就快来看
- 有时候,女神发来一条消息,说约你看电影,她考虑了一下,又撤回了,不约你了…而你又想知道她究竟发了什么,该怎么办?微信防撤回了解一下。环境要求
- 导语在CSDN学习的过程中,遇到了爆火的文章是关于刮刮卡的!大家猜猜看是谁写的?我看这文章都特别火,我也感觉挺好玩的,那就寻思用 Pytho
- 今天要说的是一个高速视频流的采集和传输的问题,我不是研究这一块的,没有使用什么算法,仅仅是兴趣导致我很想搞懂这个问题.