Search code examples
vuejs3vue-composition-api

How to get props in Vue3 Composition API


I try to write a container component "A" to layout a third-party component "Tree", in order to use A, I use "inheritAttrs" to get all props and event of "Tree":

<template>
  <Tree v-bind="$attrs" />
</template>

<script lang="ts">
  export default {
    inheritAttrs: true,
  };
</script>

<script lang="ts" setup>
  import { Tree } from 'ant-design-vue';
  import { onMounted, PropType, toRef, unref, ref, toRefs } from 'vue';
  function A() {
      // this is not working
      console.log(props);
   }
</script>

How can I get some props attributes inherit from "Tree" in function A?


Solution

  • 'InheritAttrs'

    Firstly, inheritAttrs does not mean inheriting props, inheritAttrs set to true means you inherit the attributes (not props) automatically and bind those attributes to the root node of the component.

    What are 'Attributes'?

    Some common ones are class, style, id, disabled, required and minlength attributes to name a few. Basically all native HTML attributes are addressed by inheritAttrs.


    How to access the props object inside <script setup>?

    In the composition API, you need to explicitly define the props in <script setup> to be able to use the props object.

    In Single File Components (SFCs) using <script setup>, props can be declared using the defineProps() macro:

    <script setup>
       const props = defineProps(['foo'])
    
       console.log(props.foo)
    </script>
    

    ...


    Read More: What if I have a prop with the same name as an attribute?

    Let's set up an example. You define a prop named disabled in MyComponent.vue.

    MyComponent.vue

    <template>
       <Tree v-bind="$attrs"/>
    </template>
     
    <script setup>
       const props =  defineProps({
          disabled: Boolean,
       })
           
       console.log(props.disabled); // this works
    </script>
    

    ... and then add the component like this, passing in disabled. Note that :disabled="true" and just disabled mean the same thing in both cases - when props are defined or not.

    App.vue

    <MyComponent disabled />
    

    Since you defined the props using, defineProps() the v-bind="$attrs" will no longer be having disabled as an attribute in the $attrs object. This is just as the docs explain:

    Vue components require explicit props declaration so that Vue knows what external props passed to the component should be treated as fallthrough attributes...

    In other words, if you don't define the props, they will be treated as attributes.