上面介绍了在 Vue.js 中,传递给组件的非 Prop 属性会自动替换或者合并到组件的根元素上,庆幸的是,class 和 style 属性会稍微智能一些,即两边的值会被合并起来。
如果你不希望组件的根元素继承属性,你可以在组件的选项中设置 inheritAttrs: false。例如:
Vue.component('my-component', { inheritAttrs: false, // ... })
这尤其适合配合实例的 $attrs 属性使用,该属性包含了传递给一个组件的属性名和属性值,例如:
{ required: true, placeholder: 'Enter your username' }
有了 inheritAttrs: false 和 $attrs,你就可以手动决定这些属性会被赋予哪个元素。在编写基础组件的时候是常会用到的,例如:
Vue.component('base-input', { inheritAttrs: false, props: ['label', 'value'], template: ` <label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on:input="$emit('input', $event.target.value)" > </label> ` })
注意:inheritAttrs: false 选项不会影响 style 和 class 的绑定。
这个模式允许你在使用基础组件的时候更像是使用原始的 HTML 元素,而不会担心哪个元素是真正的根元素:
<base-input label="Username:" v-model="username" required placeholder="Enter your username"></base-input>
<html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue</title> <!-- 使用 CDN 引入 Vue 库 --> <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> --> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.7.9/vue.js"></script> </head> <body> <div id="app"> <base-input label="Username:" v-model="username" required placeholder="Enter your username" ></base-input> </div> <script type="text/javascript"> Vue.component('base-input', { inheritAttrs: false, props: ['label', 'value'], template: ` <label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on:input="$emit('input', $event.target.value)" > </label> ` }); var app = new Vue({ el: "#app", data: {} }); </script> </body> </html>
效果如下图: