learn to code
learn to code

Reputation: 303

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?

Upvotes: 29

Views: 69108

Answers (5)

Fanoflix
Fanoflix

Reputation: 2089

'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.

Upvotes: 40

Taimoor Changaiz
Taimoor Changaiz

Reputation: 10684

https://vuejs.org/guide/components/props.html

defineProps({
  // Basic type check
  //  (`null` and `undefined` values will allow any type)
  propA: Number,
  // Multiple possible types
  propB: [String, Number],
  // Required string
  propC: {
    type: String,
    required: true
  },
  // Required but nullable string
  propD: {
    type: [String, null],
    required: true
  },
  // Number with a default value
  propE: {
    type: Number,
    default: 100
  },
  // Object with a default value
  propF: {
    type: Object,
    // Object or array defaults must be returned from
    // a factory function. The function receives the raw
    // props received by the component as the argument.
    default(rawProps) {
      return { message: 'hello' }
    }
  },
  // Custom validator function
  // full props passed as 2nd argument in 3.4+
  propG: {
    validator(value, props) {
      // The value must match one of these strings
      return ['success', 'warning', 'danger'].includes(value)
    }
  },
  // Function with a default value
  propH: {
    type: Function,
    // Unlike object or array default, this is not a factory
    // function - this is a function to serve as a default value
    default() {
      return 'Default function'
    }
  }
})

Upvotes: 0

Andrey
Andrey

Reputation: 2068

And very useful hint to reduce writing and improve readability - how to avoid writing 'props.foo' and use just 'foo' in template

import {toRefs} from "vue";

let props = defineProps(["foo"]);
const { foo } = toRefs(props);

Upvotes: 1

Ibrahim Schi
Ibrahim Schi

Reputation: 418

You can use also following way:

export default {  
...    
    props:["filterOptions"],
    setup(props, context) {      
     const optionsinProps = props.filterOptions;
    }  
...
 };

Upvotes: 3

Orbis
Orbis

Reputation: 475

You can define typesafe props with Typescript and Composition API (<script setup lang="ts" />) like:

<script setup lang="ts">
const props = defineProps({
  foo: { type: String, required: true },
  bar: Number
})

props.foo // string
props.bar // number | undefined
</script>

However, it is usually more straightforward to define props with pure types via a generic type argument:

<script setup lang="ts">
interface Props {
  foo: string,
  bar?: number
}
const props = defineProps<Props>()

props.foo // string
props.bar // number | undefined
</script>

See Docs. If you want to set default values too. See here

Upvotes: 7

Related Questions