vue中attrs的作用与使用场景

简介: 在讲解 attrs 之前,你首先要知道组件常用的通讯方式:props 和 emits ,这两个是 Vue 组件通讯的基础,本文不会讲解

简单来说, attrs 主要接收没在 props 里定义,但父组件又传过来的属性。


举个例子


<!-- 父组件 ParentCom.vue -->
<template>
  <ChildCom
    msg="雷猴"
    data="123"
  />
</template>
<script setup>
import ChildCom from './ChildCom.vue'
</script>
<!-- 子组件 ChildCom.vue -->
<template>
  <div>
    {{ msg }} - {{ $attrs }}
  </div>
</template>
<script setup>
defineProps({
  msg: {
    type: String
  }
})
</script>


30406f0542be431f97c1f73dd09cbf3d.png


可以看到,在子组件中,msg 使用了 props 接收,所以 {{ msg }} 可以直接输出 props 里接收的内容。


而没在 props 里接收的内容,全部都放到了 $attrs 里,并且存在一个对象里面。


接下来将展开讲解不同情况下 attrs 的使用方法。


attrs在 template 中的用法


在前面简单的例子里其实已经大概知道 attrs 在 template 的用法。但 Vue3 中 template 不再要求只有一个根元素了。所以 attrs 在 template 中分2种情况使用


只有1个根元素的情况下


只有1个根元素的情况下,子组件中,没被 props 接收的属性,都会绑定在根元素上


<!-- 父组件 ParentCom.vue -->
<template>
  <ChildCom
    msg="雷猴"
    data="123"
    name="鲨鱼辣椒"
    style="color: red;"
  />
</template>
<script setup>
import ChildCom from './ChildCom.vue'
</script>
<!-- 子组件 ChildCom.vue -->
<template>
  <div>
    {{ msg }}
  </div>
</template>
<script setup>
defineProps({
  msg: {
    type: String
  }
})
</script>


e1adb70219234302a172f59012444d5b.png


可以看到,没被 props 接收的属性都被绑定到根元素上了。


连 style 里传入的样式也被执行,文字变成红色了。


如果此时我们想在页面输出 name 的值,可以在子组件中这样操作


<!-- 这里省略 父组件代码 ...... -->
<!-- 子组件 ChildCom.vue -->
<template>
  <div>
    {{ $attrs.name }}
  </div>
</template>
<script setup>
defineProps({
  msg: {
    type: String
  }
})
</script>


4dd816966c184de0ac7121ced952bfdd.png


使用 $attrs.xxx ,这里的 xxx 是对应的属性名。


有2个根元素的情况下


当子组件有2个根元素时,没被 props 接收的属性不会绑定到子组件的元素上


<!-- 父组件 ParentCom.vue -->
<template>
  <ChildCom
    msg="雷猴"
    data="123"
    name="鲨鱼辣椒"
    style="color: red;"
  />
</template>
<script setup>
import ChildCom from './ChildCom.vue'
</script>
<!-- 子组件 ChildCom.vue -->
<template>
  <div>
    {{ msg }}
  </div>
  <div>
    {{ msg }}
  </div>
</template>
<script setup>
defineProps({
  msg: {
    type: String
  }
})
</script>


2dad23bd2c754e50b9d47d778b0beee8.png


此时连父组件传入是 style 样式都不生效了。


如果我们此时希望第二个元素绑定所有没被 props 接收的属性,可以使用 v-bind=“$attrs” 的方法实现


<!-- 父组件 ParentCom.vue -->
<template>
  <ChildCom
    msg="雷猴"
    data="123"
    name="鲨鱼辣椒"
    style="color: red;"
  />
</template>
<script setup>
import ChildCom from './ChildCom.vue'
</script>
<!-- 子组件 ChildCom.vue -->
<template>
  <div>
    {{ msg }}
  </div>
  <div v-bind="$attrs">
    {{ msg }}
  </div>
</template>
<script setup>
defineProps({
  msg: {
    type: String
  }
})
</script>


123.png


注意第二个元素,使用了 v-bind=“$attrs” 绑定了所有没被 props 接收的属性。


如果只希望绑定部分属性,可以单独写


<!-- 这里省略 父组件代码 ...... -->
<!-- 子组件 ChildCom.vue -->
<template>
  <div>
    {{ msg }}
  </div>
  <div :style="$attrs.style">
    {{ msg }}
  </div>
</template>
<script setup>
defineProps({
  msg: {
    type: String
  }
})
</script>


1234.png


attrs在 js 中的用法


除了在 template 中可以访问到 $attrs ,在 JS 中也可以访问到。


vue 3 其实是兼容大部分 Vue 2 语法的,也就是 Options API 。而 attrs 在 Options APi 和 Composition Api 中的使用方法会稍微有一丢丢区别。而 Composition API 又分为 Vue 3.2 前的语法和 3.2 后的语法。


接下来将分开讨论这3种情况。


Options API


<!-- 父组件 ParentCom.vue -->
<template>
  <ChildCom
    msg="雷猴"
    data="123"
    name="鲨鱼辣椒"
    style="color: red;"
  />
</template>
<script setup>
import ChildCom from './ChildCom.vue'
</script>
<!-- 子组件 ChildCom.vue 暂不关注 template 部分 -->
<script>
export default {
  props: {
    msg: {
      type: String
    }
  },
  mounted() {
    console.log(this.$attrs)
  }
}
</script>


12345.png


此时控制台会输出没被 props 接收的属性

Composition API 3.0的语法


<!-- 父组件 ParentCom.vue -->
<template>
  <ChildCom
    msg="雷猴"
    data="123"
    name="鲨鱼辣椒"
    style="color: red;"
  />
</template>
<script setup>
import ChildCom from './ChildCom.vue'
</script>
<!-- 子组件 ChildCom.vue 暂不关注 template 部分 -->
<script>
export default {
  props: {
    msg: {
      type: String
    }
  },
  setup(props, context) {
    console.log('props: ', props)
    console.log('attrs: ', context.attrs)
  }
}
</script>


23.png


Vue 3.2 前的写法,需要在 setup 方法里接收2个参数,而 attrs 就在 context 参数里。


Composition API 3.2的语法


Vue 3.2 后的语法,可以在


在这种情况下,props 成了默认的全局方法,而 attrs 则需要另外引入。


<!-- 父组件 ParentCom.vue -->
<template>
  <ChildCom
    msg="雷猴"
    data="123"
    name="鲨鱼辣椒"
    style="color: red;"
  />
</template>
<script setup>
import ChildCom from './ChildCom.vue'
</script>
<!-- 子组件 ChildCom.vue 暂不关注 template 部分 -->
<script setup>
import { useAttrs } from 'vue'
const props = defineProps({
  msg: {
    type: String
  }
})
const attrs = useAttrs()
console.log('props: ', props)
console.log('attrs: ', attrs)
</script>


24.png


需要引入 vue 中的 useAttrs ,在调用 useAttrs 后会返回当前未被 props 接收的属性。


重点是以下两句。


import { useAttrs } from 'vue'
const attrs = useAttrs()


之后在 js 代码里就可以使用 attrs.xxx 获取对应的属性值了

目录
相关文章
|
3天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
4天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
4天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
4天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
3天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
4天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
3天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
|
4天前
|
存储 JavaScript
Vue 组件间如何通信
Vue组件间通信是指在Vue应用中,不同组件之间传递数据和事件的方法。常用的方式有:props、自定义事件、$emit、$attrs、$refs、provide/inject、Vuex等。掌握这些方法可以实现父子组件、兄弟组件及跨级组件间的高效通信。
|
10天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发
|
10天前
|
存储 JavaScript
Vue 状态管理工具vuex
Vue 状态管理工具vuex