非Prop特性指的是,一个未被组件注册的特性。当组件接收了一个非Prop特性时,该特性会被添加到这个组件的根元素上。
示例
<section id="app"><!-- age 与 sex 是非prop特性(此处特性就是属性) --><my-prop :name='name' age=10 sex='nan'></my-prop></section><script>Vue.component('my-prop',{// 此处并没有接收 age 与 sex 特性,那就是说明age与sex未被注册props:['name'],template:`<!-- 非prop特性会被添加到根元素上--><div><p>{{name}}</p></div>`})const vm = new Vue({el: '#app',data: {name:'张三',},})</script>
以上面代码为例
<my-prop :name='name' age=10 sex='nan'></my-prop>
props:['name'],
age 和 sex 就是非prop特性(特性就是属性),因为props中并未有注册它们,它们会保存到 $attrs 上 ,
非prop特性默认会将其添加到该组件的根元素上
替换/合并已有的特性
想象一下 <my-cmp> 的模板是这样的:
template:`<input type="date" class="b">`
添加一个特别的类名:
<my-cmpclass="my-cmp"></my-cmp>
在这种情况下,我们定义了两个不同的 class 的值:
- my-cmp,这是在组件的模板内设置好的
- b,这是从组件的父级传入的
对于绝大多数特性来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入 type=”text” 就会替换掉 type=”date” 并把它破坏!庆幸的是,class 和 style 特性会稍微智能一些,即两边的值会被合并起来,从而得到最终的值:my-cmp b。
禁用特性继承与$attrs
如果不希望组件的根元素继承特性,那么可以在组件选项中设置 inheritAttrs: false。如:
Vue.component('my-cmp', {inheritAttrs: false,// ...})
使用 inheritAttrs: false 和 $attrs 相互配合,我们就可以手动决定这些特性会被赋予哪个元素。如
<section id="app"><my-prop :name='name' age=10 sex='nan'></my-prop></section><script>Vue.component('my-prop',{props:['name'],mounted(){console.log(this);console.log(this.$attrs);},inheritAttrs: false, //禁用特性继承template:`<div><p>{{name}}</p><!-- 将非prop特性添加到下面这个元素--><p v-bind='$attrs'>{{this.$attrs}}</p></div>`})const vm = new Vue({el: '#app',data: {name:'张三',},})</script>
效果图
注意:inheritAttrs: false 选项不会影响 style 和 class 的绑定。
$attrs
官方解释
资料中的解释
实现祖先组件传递数据给子孙组件
<section id="app"><my-prop class="son" :name='name' age=10 sex='nan'></my-prop></section><script>// vm的孙子组件Vue.component('my-prop-son',{props:['age','sex'],template:`<div><button>{{sex}}</button></div>`})// vm的儿子组件Vue.component('my-prop',{props:['name'],mounted(){console.log(this);console.log(this.$attrs);},inheritAttrs: false, //禁用特性继承template:`<div><p>{{name}}</p><!-- 将非prop特性添加到下面这个元素--><p v-bind='$attrs'>{{this.$attrs.age}}</p><!-- 向子组件 my-prop-son 传递数据,数据是从该子组件的父组件传递过来的--><my-prop-son class='grandson' v-bind='$attrs'></my-prop-son></div>`})const vm = new Vue({el: '#app',data: {name:'张三',},})</script>
效果图
控制台
