Question presented to candidate:
"We are moving our BaseInput from the Options API to <script setup>. In the template it used $attrs, and it had inheritAttrs: false. How do you do the same things in the Composition API, and what is the difference between useAttrs() and $attrs?"
What a strong answer should cover:
$attrsis the template handle on fallthrough attributes;useAttrs()is the script handle in<script setup>(andsetup(props, { attrs })in a plainsetup()function). They expose the same data.inheritAttrs: falsemoves intodefineOptions({ inheritAttrs: false })(Vue 3.3+), which the compiler hoists into the component options.- A common pattern: split
classandstylefor the wrapper from the rest for the inner<input>, withcomputedobjects bound byv-bind. - The attrs object is read-only and not a
reactive()object: do not destructure it at the top of setup, and the docs advise using a prop when you need to watch a value (or reading it inonUpdated). - In TypeScript
useAttrs()returnsRecord<string, unknown>, so declare as props anything you need typed. - When you need neither (single root, default behaviour), you need neither API: inheritance is automatic.
Clarifying questions expected:
- "Should
classstyle the wrapper or the input?" - "Does any logic in the script depend on the attribute values, or is it only forwarding them?"
Code / implementation expected: Yes — a <script setup> wrapper using defineOptions({ inheritAttrs: false }), useAttrs() and v-bind on the inner element.