Boris K
Boris K

Reputation: 3580

Vue.js: passing an object as a prop, then using its properties as attributes in a child component

I'm trying to do this. It seems trivial, but is not working.

In my parent component, I'm instantiating the child EndpointDetailsForm component, and passing it the settingsDetails prop, like this:

<EndpointDetailsForm :endpointDetails="modalDetails.content" />

Inside the EndpointDetailsForm component, I'm retrieving the endpointDetails object, like this:

    props: {
        endpointDetails: {
            type: Object
        }
    }

and trying to use its various properties as attributes, like this:

<b-form-input id="nameInput"
              type="text"
              v-model="form.name"
              :placeholder="endpointDetails.name">
</b-form-input>

When I inspect the EndpointDetailsForm component, it shows me the endpointDetails as a prop, but when I inspect the input above, it tells me that the placeholder is null.

What am I missing?

Upvotes: 2

Views: 4225

Answers (1)

ghybs
ghybs

Reputation: 53350

In your template you have to use kebab-cased attributes. Vue will convert them to camelCased props:

HTML attribute names are case-insensitive, so browsers will interpret any uppercase characters as lowercase. That means when you’re using in-DOM templates, camelCased prop names need to use their kebab-cased (hyphen-delimited) equivalents.

Therefore if your prop is named endpointDetails, you should refer to it as an attribute as endpoint-details. Therefore:

<EndpointDetailsForm :endpoint-details="modalDetails.content" />

Code example:

Vue.component('b-form-input', {
  template: '#b-form-input',
  props: {
    placeholder: String,
  },
});

Vue.component('endpointetailsform', {
  template: '#EndpointDetailsForm',
  props: {
    // Vue converts kebab-case to camelCase.
    endpointDetails: {
      type: Object
    },
  },
});

new Vue({
  el: '#app',
  data: {
    content: {
      name: 'my placeholder',
    },
  },
});
<script src="https://unpkg.com/vue@2"></script>

<div id="app">
  <!-- Use kebab-cased attributes -->
  <endpointetailsform :endpoint-details="content" />
</div>

<template id="EndpointDetailsForm">
  <b-form-input :placeholder="endpointDetails.name"></b-form-input>
</template>

<template id="b-form-input">
  <input :placeholder="placeholder" />
</template>

Upvotes: 3

Related Questions