vue3 $attrs和inheritAttrs的用法说明

 更新时间:2022年04月28日 17:10:02   作者:hao_0413  
这篇文章主要介绍了vue3 $attrs和inheritAttrs的用法说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

$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中渲染。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用Plotly.js在Vue中创建交互式散点图的示例代码

    使用Plotly.js在Vue中创建交互式散点图的示例代码

    Plotly.js是一个功能强大的JavaScript库,用于创建交互式数据可视化,它支持各种图表类型,包括散点图、折线图和直方图,在Vue.js应用程序中,Plotly.js可用于创建动态且引人入胜的数据可视化,本文介绍了使用Plotly.js在Vue中创建交互式散点图,需要的朋友可以参考下
    2024-07-07
  • vue使用 better-scroll的参数和方法详解

    vue使用 better-scroll的参数和方法详解

    这篇文章主要介绍了vue使用 better-scroll的参数和方法详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • 用vue设计一个日历表

    用vue设计一个日历表

    这篇文章主要介绍了如何用vue设计一个日历表,帮助大家更好的理解和学习vue框架,感兴趣的朋友可以了解下
    2020-12-12
  • vue3 HTTP请求中的axios示例详解

    vue3 HTTP请求中的axios示例详解

    Axios 是一个简单的基于 promise 的 HTTP 客户端,适用于浏览器和 node.js。Axios 在具有非常可扩展的接口的小包中提供了一个简单易用的库,这篇文章主要介绍了vue3-HTTP请求之axios,需要的朋友可以参考下
    2022-12-12
  • Vue3中ref与reactive的详解与扩展

    Vue3中ref与reactive的详解与扩展

    在vue3中对响应式数据的声明官方给出了ref()和reactive()这两种方式,下面这篇文章主要给大家介绍了关于Vue3中ref与reactive的相关资料,需要的朋友可以参考下
    2021-06-06
  • Vue3 PC端页面开发规范及说明

    Vue3 PC端页面开发规范及说明

    这篇文章主要介绍了Vue3 PC端页面开发规范及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • vue路由传参的基本实现方式小结【三种方式】

    vue路由传参的基本实现方式小结【三种方式】

    这篇文章主要介绍了vue路由传参的基本实现方式,结合实例形式总结分析了vue.js路由传参的三种实现方式,包括params显示传参、不显示参数以及query显示参数传参,需要的朋友可以参考下
    2020-02-02
  • Vue.set()实现数据动态响应的方法

    Vue.set()实现数据动态响应的方法

    这篇文章主要介绍了Vue.set()实现数据动态响应的相关知识,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2018-02-02
  • Vue中created和mounted使用详解

    Vue中created和mounted使用详解

    Vue中生命周期包括多个阶段,如created和mounted,每阶段有特定钩子函数,生命周期与浏览器渲染过程密切相关,了解这些可以优化页面渲染和数据处理,created阶段适用于数据初始化,而mounted阶段适合进行DOM操作和页面渲染后的处理
    2024-10-10
  • 解决vue-pdf的签章不显示问题记录

    解决vue-pdf的签章不显示问题记录

    文章介绍了使用vue-pdf@4.3.0时遇到的上传特殊PDF文件无法正常预览的问题,通过查看控制台报错信息,发现是因为缺少字体导致的,解决方法是修改pdfjs-dist库的代码,注释掉隐藏电子签章的代码,为了在生产环境中应用这个修改,使用了patch-package插件,感兴趣的朋友一起看看吧
    2024-11-11

最新评论