vue组件通信首先我们学习的便是常用的方式:props 和 emits ,这两个是 Vue 组件通讯的基础,而attrs主要接收没在 props 里定义,但父组件又传过来的属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <!-- 父组件 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> |
可以看到,在子组件中,msg 使用了 props 接收,所以 {{ msg }} 可以直接输出 props 里接收的内容。而没在 props 里接收的内容,全部都放到了 $attrs 里,并且存在一个对象里面。
在前面简单的例子里其实已经大概知道 attrs 在 template 的用法。但 Vue3 中 template 不再要求只有一个根元素了。所以 attrs 在 template 中分2种情况使用
只有1个根元素的情况下,子组件中,没被 props 接收的属性,都会绑定在根元素上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <!-- 父组件 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> |
可以看到,没被props接收的属性都被绑定到根元素上了。连style里传入的样式也被执行,文字变成红色了。如果此时我们想在页面输出name的值,可以在子组件中这样操作,使用 $attrs.xxx ,这里的 xxx 是对应的属性名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <!-- 这里省略 父组件代码 ...... --> <!-- 子组件 ChildCom.vue --> <template> <div> {{ $attrs.name }} </div> </template> <script setup> defineProps({ msg: { type: String } }) </script> |
当子组件有2个根元素时,没被 props 接收的属性不会绑定到子组件的元素上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <!-- 父组件 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> |
此时连父组件传入是 style 样式都不生效了。如果我们此时希望第二个元素绑定所有没被 props 接收的属性,可以使用 v-bind="$attrs" 的方法实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <!-- 父组件 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> |
注意第二个元素,使用了 v-bind="$attrs" 绑定了所有没被 props 接收的属性。如果只希望绑定部分属性,可以单独写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!-- 这里省略 父组件代码 ...... --> <!-- 子组件 ChildCom.vue --> <template> <div> {{ msg }} </div> <div :style="$attrs.style"> {{ msg }} </div> </template> <script setup> defineProps({ msg: { type: String } }) </script> |
除了在 template 中可以访问到 $attrs ,在 JS 中也可以访问到。vue 3 其实是兼容大部分 Vue 2 语法的,也就是 Options API 。而 attrs 在 Options APi 和 Composition Api 中的使用方法会稍微有一丢丢区别。而 Composition API 又分为 Vue 3.2 前的语法和 3.2 后的语法,接下来将分开讨论这3种情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <!-- 父组件 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> |
此时控制台会输出没被 props 接收的属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <!-- 父组件 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> |
Vue 3.2 前的写法,需要在 setup 方法里接收2个参数,而 attrs 就在 context 参数里。
Vue 3.2 后的语法,可以在script标签上添加 setup 属性。所以在代码里就不需要再调用setup方法了。在这种情况下,props 成了默认的全局方法,而 attrs 则需要另外引入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <!-- 父组件 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> |
需要引入 vue 中的 useAttrs ,在调用 useAttrs 后会返回当前未被 props 接收的属性,重点是以下两句。之后在 js 代码里就可以使用 attrs.xxx 获取对应的属性值了。
1 2 | import { useAttrs } from 'vue' const attrs = useAttrs() |
上一篇:Vite+Vue3图片资源六种引入方式,总有一种能解决你当下难题
下一篇:手把手教你基于微前端qiankun的应用实践(上篇)
支付宝扫一扫打赏
微信扫一扫打赏
共 0 条评论关于"Vue3 – $attrs 的几种用法-父子组件通信"
最新评论