博客地址:https://blog.csdn.net/weixin_39415598/article/details/125044520?spm=1001.2014.3001.5506
使用 Vue 开发时,肯定会接触到 组件 的概念,无可避免的也会接触到 组件通讯 的概念。
组件通讯的方式有很多种,我在 《Vue3 的10种组件通讯方式》 一文中粗略罗列了 Vue3 常用的组件通讯方法。
在 Vue 2 中除了 $attrs
外,还有 $listeners
;Vue 3 把 $listeners
合并到 $attrs
里了。
而本文的重点是讲解在 Vue 3 中如何使用 $attrs 。
本文使用的 Vue 版本是 3.2.25 ,以下都基于vue3.2展开,由于vue向下兼容,所以也包括了vue3和vue2中的情况!
本文关键字:
$attrs:在 template 中使用(单一根元素和多个根元素的情况)
useAttrs:在 js 中使用(1种 Options API 和 2种 Composition API 的用法)
1.attrs的作用
简单来说, attrs
主要接收没在 props
里定义,但父组件又传过来了的属性。
2.attrs在 template 中的用法
在前面简单的例子里其实已经大概知道 attrs
在 template
的用法。
但 Vue3
中 template
不再要求只有一个根元素了。所以 attrs
在 template
中分2种情况使用。
代码:
App.vue
<template>
<!--vue3的组件模版结构可以没有根标签-->
<Son data="123" name="鲨鱼辣椒" style="color: red"> </Son>
</template>
<script>
import Son from "./components/Son";
export default {
name: "App",
components: { Son },
setup() {
return;
},
};
</script>
Son.vue
<template>
<div>{{$attrs.name}}</div>
</template>
<script>
export default {
name: "Son",
};
</script>
<style>
</style>
效果:
2.1 只有1个根元素的情况下
只有1个根元素的情况下,子组件中,没被 props
接收的属性,都会绑定在根元素上。
可以看到,没被 props
接收的属性都被绑定到根元素上了。
连 style
里传入的样式也被执行,文字变成红色了。
如果此时我们想在页面输出 name
的值,可以在子组件中这样操作
使用 $attrs.xxx
,这里的 xxx
是对应的属性名。
2.2 有2个根元素的情况下
当子组件有2个根元素时,没被 props
接收的属性不会绑定到子组件的元素上。
如果我们此时希望第二个元素绑定所有没被 props
接收的属性,可以使用 v-bind="$attrs"
的方法实现
注意第二个元素,使用了 v-bind="$attrs"
绑定了所有没被 props
接收的属性。
如果只希望绑定部分属性,可以单独写,例:"$attrs.name"
3.attrs在 js 中的用法
除了在 template 中可以访问到 $attrs ,在 JS 中也可以访问到。
vue 3 其实是兼容大部分 Vue 2 语法的,也就是 Options API 。
而 attrs 在 Options APi 和 Composition Api 中的使用方法会稍微有一丢丢区别。而 Composition API 又分为 Vue 3.2 前的语法和 3.2 后的语法。
接下来将分开讨论这3种情况
3.1 Options API
此时控制台会输出没被 props
接收的属性。
this.$attrs
3.2 Composition API 3.0的语法
Vue 3.2 前的写法,需要在 setup 方法里接收2个参数,而 attrs 就在 context 参数里。
context.attrs
3.3 Composition API 3.2的语法
Vue 3.2 后的语法,可以在 <script>
标签上添加 setup 属性。所以在代码里就不需要再调用 setup 方法了。
在这种情况下,props 成了默认的全局方法,而 attrs 则需要另外引入。
需要引入 vue 中的 useAttrs ,在调用 useAttrs函数 后会返回当前未被 props 接收的属性。
重点是以下两句:
import { useAttrs } from 'vue'
const attrs = useAttrs()
之后在 js 代码里就可以使用 attrs.xxx 获取对应的属性值了!