Vue子组件JSX写法中如何获取传入的$attrs?
在Vue JSX子组件中正确处理未被props接收的属性
哥们,我之前也踩过Vue JSX里$attrs的坑,模板写法会自动帮你处理未被props接收的属性,但JSX得手动操作才行,我给你梳理下解决思路和具体做法:
先搞懂核心差异
Vue模板里,未被props接收的属性默认会自动绑定到组件的根元素,同时也会被收集到this.$attrs里;但JSX写法不会自动做这件事,得我们手动处理$attrs的获取和绑定。
具体解决方案
1. 先排查基础问题
首先确认你的子组件没有在props里意外接收那些属性——如果父组件传的属性已经被props定义了,那$attrs里肯定找不到它。比如父传了data-id,你子组件props里写了dataId(或者驼峰转连字符后的属性),那这个属性就会被归到props里,不会出现在$attrs中。
2. Vue2 JSX的处理方式
如果是Vue2项目,直接用this.$attrs来访问未被props接收的属性,需要绑定到根元素的话,用JSX的展开运算符:
export default { name: 'ChildComponent', props: ['title'], // 只接收需要的属性,其他属性留到$attrs // 可选:如果不想让属性自动绑定到根元素(模板默认会),可以设置inheritAttrs: false // inheritAttrs: false, render() { // 把$attrs展开到根元素上,这样父传的未被props接收的属性会绑定到这个div return ( <div {...this.$attrs}> <h2>{this.title}</h2> {/* 也可以直接访问$attrs里的单个属性 */} <p>父传的data-id:{this.$attrs['data-id']}</p> </div> ) } }
如果是函数式组件的JSX写法,$attrs是在render的context参数里,不是this.$attrs:
export default { functional: true, props: ['title'], render(h, context) { // 通过context.attrs获取未被props接收的属性 return ( <div {...context.attrs}> <h2>{context.props.title}</h2> </div> ) } }
3. Vue3 JSX的处理方式
Vue3用setup语法的话,要通过useAttrs()钩子来获取属性,而不是this.$attrs:
import { defineComponent, useAttrs } from 'vue' export default defineComponent({ props: ['title'], setup(props) { const attrs = useAttrs() return () => ( <div {...attrs}> <h2>{props.title}</h2> <p>父传的data-id:{attrs['data-id']}</p> </div> ) } })
常见坑点提醒
- 注意
this指向:如果在render里用了箭头函数或者嵌套函数,要确保this指向组件实例(Vue2里),不然this.$attrs会取不到。 inheritAttrs的作用:这个选项只是控制是否自动把$attrs的属性绑定到根元素,不管设不设,$attrs都会收集未被props接收的属性。- 特殊属性的处理:比如
class、style这类属性,Vue会自动合并,但在JSX里展开$attrs时也会正常处理,不用担心冲突。
内容的提问来源于stack exchange,提问作者zhi3210happy
相关产品推荐
相关产品推荐

