当前位置: 首页 > Web前端 > vue.js

Vue进阶InheritAttrs和$attrs

时间:2023-04-01 10:58:11 vue.js

前言作者两个月前换了一份新工作。刚来公司时,他接手了一个新项目。核心点是后端返回事先准备好的数据结构,前端根据相应的结构来渲染表单。当时有一个动态表单组件,但是缺少下面两个功能:表单嵌套渲染自定义组件所以我在这个表单组件中加入了这两个功能。看了之前component作者的代码,内部使用render函数构建组件,再看对应的form控件的结构,所有的控件props都是通过attrs传入的,如下:当我看到的时候一时间,我开始怀疑这个部件是否正常。work,因为vue官方文档清楚的解释了render函数的attrs的作用:不就是把控件的所有自定义props当成普通的html属性吗?但是事实证明这个组件是可以正常工作的,因为表单组件是封装元素的表单组件,于是跑去翻了一下elementUI的源码,发现了一些东西,我们使用el-input组件取的以源码为例:注意上面用红圈圈出来的,$attrs绑定了input,传入的options传入了一个inheritAttrs属性;接下来,我们来看看它们分别代表什么;inheritAttrs默认情况下父作用域中不被视为props的属性绑定将“回退”并作为普通HTML属性应用于子组件的根元素。当组成一个包装一个或另一个目标元素的组件时,这可能并不总是像预期的那样表现。通过将inheritAttrs设置为false,这些默认行为将被删除。这些属性可以通过(也是2.4新增的)实例属性$attrs生效,可以通过v-bind显式绑定到非根元素上面是vue官方文档中对inheritAttrs的解释,大概意思就是如果值的inheritAttrs设置为false,则所有绑定的props但未在组件中声明的将不会回退到正常的HTML属性,例如://Subcomponent//父组件上面的子组件中定义了A,但是b没有定义,外部在子组件中A和b绑定到组件,a会被识别为props,b会回退为一个普通的HTML属性,如下:如果我们给子组件加上inheritAttrs:false,渲染结果如下:此时b为not然后是一个普通的HTML属性,它与$attrs一起使用时会显示出它的好处;$attrs包含在父范围中未被识别(和获取)为props的属性绑定(类和样式除外)。当一个组件没有声明任何props时,所有的父作用域绑定(class和style除外)都会被包含在这里,内部组件可以通过v-bind="$attrs"传入——在创建高级组件时非常有用。上文官网解释,$attrs保存了所有绑定到组件上的,不被识别为props的属性。上面的例子中,b会保存在子组件的$attrs中;如果子组件包含另一个组件CompB,而CompB只有一个b的prop。我之前的做法是在子组件中定义一个b的prop,然后将b绑定到CompB,再在最外层绑定b;通过绑定$attrs我们组件的props不能在中间组件声明内部使用,如下://SubcomponentComp因为b外层组件传入的保存在Comp组件中Comp实例的$attrs中,b的绑定是通过将??Comp实例的$attrs属性绑定到CompB来实现的,因为inheritAttrs设置为false,所以会有在Comp呈现的标签上没有b;这就是为什么公司的表单组件能正常使用的原因是,传递给渲染函数的attrs是分配的组件实例的$attrs,而elmentUI将实例上的$attrs绑定到input控件上,所以它能达到其应有的功能反应;summaryinheritAttrs:不要回退到组件上绑定的非组件内部定义的props回退到正常的HTML属性$attrs:所有不被认为是props的属性都会保存在里面,除了style和class